Requirements


Functional Requirements:


  • Allow users to tweet messages up to 140 characters.
  • Enable users to follow other users.
  • Allow users to like tweets from other users.
  • Display tweets from followed users in the home feed.
  • Show top K popular tweets in the home feed based on likes and followers.



Non-Functional Requirements:


  • High availability
  • Low latency
  • Scale to 100M DAU
    • 5 tweets/user/day
    • 500M tweets/day
  • 8*140*500000000/(1*10^9)=560 GB/day


API Design

POST/PUT /api/v1/{userId}/profile: allows users to make their profile page

{

"userId": "123",

"bio": "I am a tweeter",

"picture": "image.png"

}

output:

{

"status": 200

}

GET /api/v1/{userId}/profile: allows users to see other profile pages

output:

{

"followers": ["123", "456"],

"tweets": ["123456789", "987654321"],

"bio": "this is another user",

"picture": "image.png"

}


POST /api/v1/follow: allow users to follow other users

{

"userId": "3456",

"private": true

}

output:

{

"time": "2026-01-21 10:24:01:00:00:00Z",

"status": 200

}


POST /api/v1/postTweet: allows users to post tweets

{

"userId": "123",

"content": "this is a tweet",

"images": ["image1.png", "image2.png"]

}

output:

{

"tweetId":"123456789",

"time": "2026-01-21 10:24:01:00:00:00Z",

"status": 200

}


POST /api/v1/like: allows users to like tweets

{

"tweetId": "123456789",

"userId": "123"

}

output:

{

"time": "2026-01-21 10:24:01:00:00:00Z",

"status": 200

}


GET /api/v1/{userId}/tweets?followed=true: get tweets from followed users

output:

{

"tweets": [{

"userId": "123",

"tweetId": "123456789",

"likes": [{

"userId": "4",

"time": "2026-01-21 10:25:01:00:00:00Z"

},

{

"userId": "5",

"time": "2026-01-21 10:25:01:00:00:00Z"

}],

"comments": [{

"userId": "4",

"content": "this is a comment",

"time": "2026-01-21 10:25:01:00:00:00Z"

},

{

"userId": "5",

"content": "this is a comment",

"time": "2026-01-21 10:25:01:00:00:00Z"

}],

"time": "2026-01-21 10:24:01:00:00:00Z"

},

{

"userId": "456",

"tweetId": "987654321",

"likes": [{

"userId": "4",

"time": "2026-01-21 10:25:01:00:00:00Z"

},

{

"userId": "5",

"time": "2026-01-21 10:25:01:00:00:00Z"

}],

"comments": [{

"userId": "4",

"content": "this is a comment",

"time": "2026-01-21 10:25:01:00:00:00Z"

},

{

"userId": "5",

"content": "this is a comment",

"time": "2026-01-21 10:25:01:00:00:00Z"

}],

"time": "2026-01-21 10:25:01:00:00:00Z"

}]

}

GET /api/v1/tweets: get top tweets by likes and users

same output as above with no filter, ordered by likes and followers



High-Level Design

I propose a microservices architecture with 5 interconnected services. An api gateway would route the requests based on the action performed. These are the tweets service, social service, timeline service, engagement service and notification service. For api requests involving the addition/modification of tweets, users would be directed to the tweets service, and information would be updated in the tweets relational database. All tweets would also concurrently be added to a message queue (fan-out queue) that would allow the decoupling of the posting and the reading of the tweets. As a result, users timelines can be updated asynchronously and will update user feeds accordingly. From here, Fan-out workers would process these messages and add them to the timeline DB that users would hit when they access their feed. For top tweets ranked by likes and tweeter followers, we would pre load these results into a redis cache before the user requests them as this would speed up reads when the user first opens the application as these tweets would be frequently accessed. Moving to the timeline service, a user would be directed to this service whenever they are viewing their feeds. Frequently accessed tweets would hit the redis cache, otherwise it would hit the Timeline DB to gather the tweets a user is able to see. Moving to the engagement service, a user would be directed to this service every time they engage with a post (like, comment, repost, etc.) where this service would update a separate likes DB keeping information about the userIds who have engaged with a tweet with a given tweetId. The social service would work similar to the engagement service, the difference being users are directed here when they follow another user. This information would update a graph DB (a NOSQL database good for representing social connections) to keep information regarding who users are connected to. Lastly, the notification service would update a user based on the output of the engagement service (i.e. user notified when someone likes their post) and the tweets service (i.e. someone that you follow tweets). A user would be directed to this service if they wanted to adjust how they were receiving notifications.




Detailed Component Design

Firstly, I would like to dive into the usage of a fan out queue in this design.