CASE STUDY

Fitness Tracking App (Strava-style)

3 min read·424 words·Intermediate

Asked at

1 candidate report in Mar 2026

How to use this case study

SDE-2 / Mid

Design APIs to upload workouts (with GPS routes), store them, and show history and stats; plus following friends and an activity feed.

SDE-3 / Senior

Go deeper on storing routes (compressed polylines, object storage), processing uploads asynchronously, offline uploads from devices, and computing stats.

Staff / Principal

Discuss segments and leaderboards (matching routes to segments), privacy zones, scaling the feed, and costs of storing high-frequency sensor data.


0) Problem Restatement

Meta asked: design the backend of a fitness tracking app. Users record workouts (runs, rides, walks) with a phone or watch: GPS route, time, distance, pace, heart rate. They see their history and statistics (weekly distance, personal records), follow friends and see an activity feed, and optionally compete on segments (popular stretches of road with leaderboards).


1) Requirements

  • Upload workouts (maybe recorded offline) with GPS points every second and sensor data.
  • Show a workout: map, splits, charts. Show history and totals.
  • Social: follow, feed, kudos and comments.
  • Segments and leaderboards (optional).
  • Privacy: hide the start and end near home (privacy zones), and private activities.

1.1 Scale

  • 50M users, 5M workouts/day. A 1-hour workout = 3,600 GPS points ≈ 50–100 KB compressed → ~500 GB/day of route data.


2) Architecture

Architecture Diagram

flowchart LR
    DEV["Phone / watch - records offline"] -->|"upload file (FIT/GPX/JSON)"| API["Upload API"]
    API --> OS[("Object storage - raw files")]
    API --> Q[("Processing queue")]
    Q --> PROC["Processor - clean, stats, privacy zones"]
    PROC --> DB[("Activities DB - summary")]
    PROC --> RT[("Route store - encoded polyline")]
    PROC --> SEG["Segment matcher"]
    SEG --> LB[("Leaderboards")]
    PROC --> K[("Activity events")]
    K --> FEED["Feed fan-out"]
    FEED --> FS[("Feed store")]
    APP["App"] --> RAPI["Read APIs"]
    RAPI --> DB
    RAPI --> RT
    RAPI --> FS

3) Data Model

activities:  activity_id, user_id, type, start_time, duration_s, distance_m, elevation_m,
             avg_pace, avg_hr, visibility, summary_polyline, created_at
routes:      activity_id → full-resolution encoded polyline + sensor streams (object storage / blob)
stats:       user_id, week, distance_m, time_s, count      (pre-aggregated)
follows:     follower_id, followee_id
  • Summary data (small) goes in the DB for lists and feeds. Full streams (big) go in object storage, loaded only when the user opens the activity.
  • Routes are stored as an encoded polyline (a compact text encoding of coordinates), plus a simplified version for thumbnails.


4) Key Flows

  1. Upload: the device records locally (works offline) and uploads the file when connected, with an idempotency key (the device's activity UUID) so retries don't duplicate. The API stores the raw file and queues processing, then returns right away.
  2. Processing: parse, smooth GPS noise, compute distance, pace, splits and elevation, apply privacy zones (trim points near home), save the summary and streams, update weekly stats, and match segments.
  3. Feed: publish "activity created". Fan out to followers' feeds (on write for normal users, on read for accounts with huge followings).


5) Segments and Leaderboards

  • A segment is a polyline with a start and end. For each new activity, find candidate segments near its route (a geospatial index on segment bounding boxes), then check whether the route passes the start and end in order, and compute the elapsed time.
  • Leaderboards per segment: a sorted set by time (overall, by age group, and friends).


6) Wrap-Up

Devices record offline and upload whole activity files idempotently. An async processor cleans GPS, computes stats, applies privacy zones, stores small summaries in the DB and full streams as encoded polylines in object storage, and updates pre-aggregated weekly stats. Activity events drive feed fan-out (hybrid for popular users), and a geospatial segment matcher updates sorted-set leaderboards.

More Case Studies

Practice with a Mock Interview

Apply what you learned in a live system design mock interview with our AI interviewer.

Start System Design Interview →