We will focus to some KPIs only: timing, distance, heart rate
Each session will consist of many records to track the evolution of KPIs
SessionId (int 4 bytes)
Timestamp (int 4 bytes)
PositionLat (decimal 4 bytes
PositionLong (decimal 4 bytes)
HeartRate (1 byte)
Total 17 bytes
Sessions duration is around 30~60 minutes
We will record the KPIs every 10s
So 360 records per sessions for a 60 minute session
50K users with a session/day
18M records per day
1.62B records for 90 days of history
1,62B * 17 bytes = ~26GB of data
/startsession
Params: userId
Returns: sessionId
/stopsession
Params: sessionId
/track
Params: sessionId, lat, long, hr
/viewhistory
Params: userId
Returns: sessions
Table Sessions
Table Tracking
Table Users
A load balancer will helps balancing traffic accross multiple servers
Backend services are splitted in two:
Data points for tracking are pushed to a queue and processed asynchronously
Some data are cached to speedup displaying the activity reports, particularly for old data that don't change
A report service (scheduled service) can precompute the dashboard for users activities and put the data in cache
Strong consistency isn't required here so a NoSQL database can be ensivaged to accomodate future growth. Using a time series database can be a good choice to store tracking data points.
The bottleneck can be the big amount of tracking data point if many users start their session around the same time
The queue can help to reduce the pressure on database during these peak of activity
If the communication fails between the app and the tracking service, the data can be cached locally and pushed later
This can be also useful for when the user if offline because the a connectivity loss (particularly true for cellular network)