Skip to main content
Back to Projects
FeaturedFlutterNode.jsAWSFitness PlatformReal-time Data

WOD Pro League

Functional-fitness competition platform with real-time leaderboards. Sameem worked on it as an engineer at Zencloud.

WOD Pro League
Flutter + React
Apps
AWS Lambda
Serverless
Zencloud
Engineer at
Socket.io + Redis
Leaderboards

Facts about the build and who it was for. Any figure here is shown on a public store listing or site linked on this page — how we present portfolio work.

Project Story

The Challenge

Athletes in online functional-fitness competitions need scores and rankings that update live, including during registration and submission peaks.

What Was Built

As an engineer at Zencloud, Sameem worked on real-time leaderboards with Socket.io and Redis, a Node.js backend on AWS Lambda and S3, and Stripe registrations, behind Flutter and React front ends.

The Result

In the organisers' words on zencloudtechnologies.com, 'more than 600 athletes joined' in season one.

Project Details

WOD Pro League runs online and live functional-fitness competitions with real-time scoring and leaderboards. Sameem worked on it as an engineer at Zencloud: a Socket.io and Redis leaderboard system, a Node.js and Express backend on AWS Lambda and S3, and Stripe for registrations, behind a Flutter athlete app and a React organiser dashboard. The organisers' quote on Zencloud's website says that 'more than 600 athletes joined' in season one.

Tech Stack

Flutter
Node.js

No public link for this project

Category

Flutter & Node.js
Written by DevoraXReviewed by Sameem Amjad, Founder & Lead Architect EngineerLast updated Based on project records and public sources (case study)

WOD Pro League is an online functional-fitness league: athletes enter competitions, submit workout scores from a Flutter mobile app and see their place on live leaderboards, while organisers run events from a React dashboard. Sameem worked on WOD Pro League as an engineer at Zencloud; his part was the real-time leaderboard on Socket.io and Redis, the Node.js and Express backend that takes competition registrations, and the Stripe integration, on a backend that also uses AWS Lambda and S3. The organisers' testimonial on zencloudtechnologies.com says more than 600 athletes joined in the first season.

What you can check

  • Organisers' testimonial on zencloudtechnologies.com: "more than 600 athletes joined" in season one

Each item points to something public: a store listing, a live site or a demo build. See our terms for how we present portfolio results.

What problem was WOD Pro League solving?

An athlete competing in an online functional-fitness event needs one place to enter a competition, submit a score, and immediately see where that score places them against everyone else attempting the same workout.

Each part of that need carries engineering weight. Online means the system cannot assume a single location, timezone or quality of network. Competitive means the leaderboard has to be authoritative rather than approximate, because the ranking is the product. Real-time means an athlete who submits a score expects the standings to reflect it now, not after an overnight recalculation.

Taken together, those three constraints drove the architecture and ruled out the simpler request-and-response design a non-competitive fitness app could have used.

How is the platform split across mobile, web and admin?

WOD Pro League has three surfaces on one shared backend. Athletes use a Flutter app built for iOS and Android. The league also had a public website. Organisers and staff work through a React dashboard. The app and the dashboard talk to the same Node.js service layer, which uses AWS for serverless functions and storage, with Redis and Socket.io handling real-time data.

The key decision is that scoring and ranking live on the server, never in the apps. A leaderboard computed on a phone can disagree with the phone next to it, and in a competition that disagreement becomes a dispute. Keeping the ranking logic on the backend gives one authoritative answer that the mobile app and the dashboard both display the same way.

The apps therefore become presentation and submission layers, which keeps the mobile codebase thin and lets competition rules change without an app store release.

Why Flutter for the athlete app?

Athletes are not a single-platform audience, and a competition that is live on iOS a week before Android splits its own leaderboard. Flutter produces both native builds from one codebase, so both platforms get the same features at the same time. Both builds were published on the App Store and Google Play.

Flutter also suits the particular screens this product needs. Leaderboards are long, dense, frequently updating lists, and Flutter draws its own widgets through a compiled rendering pipeline rather than bridging to platform views. That keeps scrolling smooth on a list that is changing under the athlete's thumb as socket events arrive.

It keeps the interface consistent too. Division filters, score entry forms and ranking tables look and behave the same on every device, so a conversation about a placement is never complicated by two athletes seeing different layouts of the same event.

How was the real-time leaderboard built with Redis and Socket.io?

Sameem built this part of the platform. A leaderboard is a ranking problem disguised as a list. Recomputing everyone's position by querying and sorting a primary database on every score submission does not survive a competition deadline, when submissions arrive in a burst rather than a trickle. Redis is built for this shape of workload: it holds ranked score data in memory and answers position and range queries without repeated relational sorting.

Socket.io handles delivery. Instead of every athlete's app polling for standings, connected apps hold a persistent channel and receive updates as they happen, which replaces a stream of redundant requests with pushed events. Socket.io's transport negotiation and automatic reconnection matter because athletes move between mobile data and wifi mid-session, and a dropped connection has to recover without losing their place in the event.

Together, the two turn a score submission into a visible change in the rankings for everyone watching the event, without anyone refreshing the page.

Why a Node.js and AWS Lambda backend?

Competition traffic is not flat. It clusters around workout releases and submission deadlines, then falls away between events. A fixed set of always-on servers is either oversized for the quiet hours or undersized for the peak, and the peak is the moment that decides whether athletes trust the platform.

Node.js fits because the backend is mostly I/O-bound: score writes, leaderboard reads, registrations and socket fan-out, not heavy computation. Its event-driven, non-blocking model holds many open connections on modest resources, which is the profile of a real-time leaderboard service. Socket.io needs those long-lived connections, which a Lambda function cannot hold, so the real-time tier has to run as a long-running Node.js service.

AWS Lambda suits the other kind of work: stateless jobs that arrive in bursts, scaling out per invocation and back to nothing afterwards, so that capacity follows the competition calendar instead of a fixed plan. Amazon S3 provides durable storage for the platform's files, keeping them off the application servers entirely.

What does the React organiser dashboard do?

A competition platform is only half an athlete product. The other half is an operations tool, because someone has to create events, define divisions, publish workouts, check submitted scores and manage qualification. That is desk work, done on a large screen with dense tables and frequent changes, which is a different interface problem from the mobile app.

React was used for that surface. Its component model maps neatly onto the repeating structures an organiser works with, where an event, a division and a score row are each a reusable unit drawn many times with different data. It also copes well with the frequent, granular updates a dashboard produces when staff are editing live data during an active competition.

Separating the organiser tools from the athlete app keeps the Flutter build focused on competing rather than administering, and lets the dashboard change at its own pace without waiting on a mobile release.

What engineering problems does live online competition create?

Running competitions online, with athletes submitting from wherever they train, creates problems a single in-person event never faces.

Concurrency is the first. When many athletes submit against the same workout at once, every write has to land, rank consistently and produce the same ordering for every observer, which is why ranking is centralised rather than computed on each phone.

Timing is the second. Athletes taking part remotely may be in different timezones, so a deadline has to be stored as an absolute instant and shown in each athlete's local time; a cutoff has to mean the same moment for everyone.

Network quality is the third. Real-time delivery has to degrade gracefully for an athlete on a weak mobile connection, reconnecting and catching up on the current standings rather than silently showing stale ones.

Where can you see WOD Pro League today?

Nowhere live: as of October 2026 the league's website no longer loads and both store listings have gone, so there is no running build to try.

The public trace that remains is on Zencloud's own website, zencloudtechnologies.com, which shows a testimonial from the league's side. It credits Zencloud with leading development of the iOS and Android apps and says that in the first season "more than 600 athletes joined". That is the organisers' statement, published on Zencloud's site.

Why this stack

  • Flutter — one codebase compiles to native iOS and Android builds, which keeps both platforms in step for a single competitive audience instead of splitting a leaderboard across staggered launches. Its own rendering pipeline keeps long, constantly changing leaderboard lists smooth while socket events update them underneath the user.
  • Node.js — the backend workload is I/O-bound rather than compute-bound: score writes, leaderboard reads, registrations and socket fan-out. Node's event-driven, non-blocking runtime holds many concurrent persistent connections on modest resources, and shares a language with the React dashboard.
  • React — the organiser dashboard is dense, table-heavy and frequently updated during live events. React's component model maps directly onto the repeating event, division and score-row structures organisers work with, and its rendering model handles granular state changes without full-page reloads.
  • AWS Lambda — competition traffic spikes at workout releases and submission deadlines, then goes quiet. Serverless functions scale out per invocation and back to zero, so capacity for stateless work tracks the competition calendar rather than a fixed set of servers sized for either the peak or the average.
  • Amazon S3 — durable object storage keeps the platform's files off the application servers, so serving files never competes with the leaderboard for backend resources, and storage scales separately from compute.
  • Redis — a leaderboard is a ranking query, and re-sorting a relational table on every submission struggles under deadline bursts. An in-memory data structure store answers position and range queries from memory, which is what makes live standings feel immediate.
  • Socket.io — replaces polling with persistent push channels, so a score submission reaches everyone watching as an event rather than being discovered on the next poll. Its transport negotiation and automatic reconnection handle athletes moving between mobile data and wifi mid-competition.