My Solution for Design a Fitness Tracking App with Score: 8/10

by marcci

System requirements


Functional:

  • Track Activities
  • Set goal
  • Monitor progress



Non-Functional:

  • Performance: Quick response
  • Support peak times such as: holiday...
  • Availability: 99.9%




Capacity estimation


Target user for the first year: 100.000

DAUs: 20.000

Request / user: 10 request/day

Request / day: 200.000

Response time: 200-300ms





API design

Add activity:

  • user_id: uuid
  • type_of_activity_id: number
  • startTime: DateTime
  • endTime: DateTime
  • distance: number (m)

View activily list / view detail:

  • query params: fromDate, toDate (yyyyMMdd)
  • request params: user_id
    • activity_id: for view detail
  • response: all saved information
    • workload: number
    • duration: number (minute)
    • calories: number


Add goal:

  • user_id
  • period: week, day, month
  • type: km, times, minutes
  • goalValue: number


Monitor progress:

  • request params: user_id, goal_id
  • response:
    • goal: goal_id, period, type, goalValue
    • currentValue: number
    • status: string (New, On track, success, due)




Database design

Use relational database

User

  • id: uuid
  • fullName
  • email
  • phone
  • geolocation
  • timezone
  • lang
  • gender
  • dob

Workout

  • id
  • userId: pgk
  • value: number
  • duration
  • startTime
  • endTime
  • typeOfWorkoutId: fgk
  • calories

Type of Workout

  • id: number
  • name: string
  • createdAt

Goal

  • goalId: uuid
  • userId: uuid: pgk
  • startDate
  • endDate
  • goalValue: number



High-level design


  • Rate Limiter: avoid spam
  • Load balancer: for multiple location servers
  • API Gateway: for API endpoint
  • Goal Service
  • User Service
  • Workout Service
  • Redis Cache: to cache user and goal
  • Message Queue: for asynchronous communication
  • Postgre DB




Request flows







Detailed component design

  1. For our load balancing strategy, we use index based Layer 4 load balancing so that users are routed to the nearest server to reduce latency
  2. API Gateway does rate limiting and lets the user know when they are being rate limit gracefully
  3. We use log based message queues since we do not want to lose user data
  4. We cache a user's goals and his last N workouts, where N is a configurable parameter. We invalidate the workouts whenever we record a new workout for the user. We invalidate the goals of a user from the cache when the user adds a new goal. For other cases, we use Least Recently Used as our cache eviction strategy





Trade offs/Tech choices

  • Postgre for DB
  • Redis as caching service
  • Kafka for message queue





Failure scenarios/bottlenecks

  • User doing workout offline --> can not track distance and geolocation correctly
  • during peak hours such as holiday, workout services maybe overload





Future improvements

  1. Users should be track how far along their goal they have progressed
  2. Letting the user know when they have hit a goal