My Solution for Design a Fitness Tracking App with Score: 8/10
by kraken9196
System requirements
Functional:
- Allow user to create an account and add their details.
- Allow user to monitor daily metrics such as number of steps and calories burned.
- Allow user to set goals for number of steps and calories burned.
- Users should get notification for pending steps/calories for the set goals.
- Users can view reports on weekly progress.
Non-Functional:
- System needs to be highly available.
- System can be eventually consistent, for metrics such as number of steps or calories burned, immediate update may not necessarily be desirable.
- System should be fault tolerant and should continue to function in case of partial network failures.
- Latency should be minimum for basic operations such as user account creation.
- System should be able to scale with increased traffic and high user count.
Capacity estimation
- We can assume that the application is being used worldwide and has a total user base of 10 million.
- Out of which we can consider 1 million as the DAU count.
- Write traffic can be handled asynchronously in this application, with every write being streamed to MongoDB using kafka or a messaging queue.
- Read traffic will be mainly for getting the current metrics.
- We can consider each user checks metrics about 5 times a day which will be 5 million read requests per day.
- For storing user metadata such as height, weight we can consider about 3 KB of space per user hence a total storage size of 3 KB * 10 M
- It would be difficult to measure the number of writes as writes will be streaming data directly onto a platform.
API design
- /register - This API will be responsible for new account creation for the user.
- /login - This API will be responsible for login of users, users will be able to login to the system by a username and password combination.
- /loginSSO - This API will be responsible for SSO login if user wants to do that.
- /create-goal - this API will be responsible for creating a daily/weekly goal for the users, this will be a POST call.
- /view-metric/{metricName} : This API will be responsible for viewing the metric data for a user such as number of steps or calories burned, User will be able to view the data for the current day or for the last 1 week or 1 month.
- /view-report : This API will be responsible for presenting a report to the user on the application UI for activities in the last 1 month, on UI reports can be limited to 1 month data to avoid a lot of computation.
- /download-report : This API will be used by user to generate data over long duration and directly download the report.
- /notifications : This API will trigger in-app notification to the user if they are behind on their goal.
Database design
- We will be using postgres database in order to store user specific data such as user details. There will be a table called user which will store the basic details of the user.
- There will be a credentials table as well which will store password in the encrypted format, this table will have an expiry_date column as well which will store the date of 3 months ahead of the date of password creation.
- There will be a user_metric table which will store basic user details such as height, weight, age of the user for biometric purpose.
- We will use mongoDB to store metrics for a user such as number of steps and number of calories burned, heart rate etc. A collection metrics will store documents for a user with metrics on a daily basis.
High-level design
Request flows
- User Interface (UI): The front-end where users interact with the app.
- Load Balancer (Incoming Requests): Balances user requests across multiple backend servers.
- Backend Server: Processes user requests and interacts with the Kafka topic.
- Kafka Topic: Streams data from the user's device.
- MongoDB Database: Used for storing metrics.
- Load Balancer (MongoDB Read Replicas): Balances read requests to MongoDB.
- MongoDB Read Replica Instances: Instances that handle read queries from MongoDB.
- PostgreSQL Database: Used for transactions that require complex queries and ACID compliance.
- Load Balancer (PostgreSQL Read Replicas): Balances read requests to PostgreSQL.
- PostgreSQL Write Instance: Dedicated instance for handling write operations for PostgreSQL.
- PostgreSQL Read Replica Instances: Instances that handle read queries from PostgreSQL.
Detailed component design
- For viewing the daily metrics the data will be streamed directly from the user's device to a kafka topic, from there the data would be pulled in into a mongodb database collection.
- For further usages such as requests by user to view these metrics or for reporting, data can be pulled out directly by MongoDB.
- User will also get notifications about 3 notifications a day can be sent to the user if the user is behind on their set goal, For each user who have set their goals in the system the notification module will pull up the goal vs the target achieved today and send a notification to the user if they are behind.
Trade offs/Tech choices
- Made use of kafka for live data streaming instead of API calls which could be a potential bottleneck as there can be multiple calls.
- Made use of MongoDB instead of a relational database as different users can have different metrics selected at their end and write performance will also be better as it is not structured.
- Made use of messaging queue for notification module so that message generation and delivery can be decoupled.
Failure scenarios/bottlenecks
Future improvements
- We can have a caching mechanims, with increase in the user count we can store the metrics from mongodb in a cache for quicker retrieval.
- Notification deliveries can fail hence we can introduce a retry mechanims there or use kafka instead of a messaging queue to have data retention which would make retry easier.