Scalability: The app must be able to scale with increasing users at the rate of 10% for month, with an initial users of 10,000
Availability:
The system should be highly available for setting goals and tracking
Latency: Since this is a mobile app it should be able to produce quick results with minimum network resources.
History Maintenance: We need the history of the user in order to track progress, so we should be able to store and retrieve history and reports effectively
Initial user base : 10000
Estimated monthly users to increase 10% per month
so ~ 32000 users by end of 1st year and ~ 3 million users in 5 years.
Estimating 20% of monthly active users as Daily active users
DAU for first month : 2000
DAU by end of year: 6400
DAU by end of 5 years: 60,000
Assuming the read to write ratio is 1:1 for monitoring progress and assuming 10 transactions from user per day.
Throughput required is
first month : 2000 * 10 / 30/ 24 - 28 transactions/hour
end of year : 6400 * 10/ 30/ 24 - 89 transactions/hour
end of 5 years : 60000 * 10/ 30/ 24 - 833 transactions/hour or 0.23 tps
Storage:
initial user base should include user details and goals set, assume about 1kb per user.
10000*1Kb - 10 MB for first month
32000*1kb - 32 MB by end of first year
3 million * 1KB - 3GB by end of 5 years
Daily progress tracking will be including 10 transactions per user per day
2000*10*1Kb * 30 - 0.6 GB/month for first month
6400*10*1kb * 30 - ~2GB/month by end of first year
60000 *10* 1KB * 30 - 18GB/month by end of 5 years
considering geometric progression the storage required by end of 5 years is ~2TB
Create User with Goal Preferences :
Post /User - returns response with userId and creation details
request fields - username, joining date, current weight, target weight, goal type
GET USER:
Get User/userId - response with all the above detals
Update User Preferences:
PUT /User/userId
request fields - current weight, target weight, goal type
Add activity:
Post /Activity - returns response with ActivityId
request fields - name , category
Add Food consumed:
Post /FoodEntry - returns success response with details updated
request fields - food name, time and date consumed, quantity
Add Physical Activity:
Post /ActivityEntry - returns success response with details updated
request fields - activity name, date and time of the activity , duration of the activity
Get Progress:
Get /fitnessReport - returns the report with the calories intake, calories burned though activity, physical activity duration, current weight, target weight
request fields - userId, user name, before time, after time
erDiagram
USER {
string UserId "Primary Key"
string name
float current_weight
float target_weight
date joining_date
string goal_type
}
Activity {
string ActivityId "Primary Key"
string name
string categoryId "Foreign Key referencing Category"
float met_value
}
Category {
string CategoryId "Primary Key"
string categoryName
}
FoodInfo {
string foodId "Primary Key"
string name
int calories_per_100g
int carbs
int protein
int fat
// Other nutritional information
}
FoodEntry {
string food_entry_id "Primary Key"
string food_id "Foreign Key referencing FoodInfo"
string name
date entrydate
int quantity
}
ActivityEntry {
string activity_entry_id "Primary Key"
string activity_id "Foreign Key referencing Activity"
string activity_name
date entrydate
int duration
}
CalorieEntry {
string Id "Primary Key"
string UserId "Foreign Key referencing USER"
string type_of_entry
int calories
date entryDate
}
Components:
Load balancer: We will need a load balancer to effectively redirect the request to available servers
Rate Limiter: A rate limiter is required to limit the number of requests per user and avoid DDos attacks
Application Servers: All the APIs are served from this application servers. the Application servers can be scaled horizontally to support increasing load.
Database:
We can a use a nosql database for this as the data is increasing exponentially and it is easy to horizontally scale nosql databases.
We can use Cassandra DB for this as the write and reads are both high for the system. Partition key is userId.
Notification Service:
A notification service can be designed to send out notifications / reminders for regular food and activity entries. notifications can also be sent out for any new achievements of the user.
Reporting Service:
A service to generate regular reports based on the changes in weight over time and comparing actual progress against the set target. Providing virtual awards if the set goals are achieved.
Nothing apart from above
Reporting Service:
Generate regular fitness report daily, weekly , monthly and yearly and show the report.
Explain any trade offs you have made and why you made certain tech choices...
Try to discuss as many failure scenarios/bottlenecks as possible.
What are some future improvements you would make? How would you mitigate the failure scenario(s) you described above?