Estimate the scale of the system. Consider daily active users, read/write ratio, storage requirements, bandwidth, and any relevant QPS calculations...
Using horizontally scaling systems, including NoSQL databases, as shown, all the API calls should be easy to evaluate in real time, except for get_top_global_tweets. That one can be run reads from a small relational DB. The keys for that relational DB are populated offline every few minutes from a job that reads the Tweet like database, but the relational DB gets updated every time a tweet in that DB gets liked."
Writes:
Reads:
Not shown in the diagram are standard load balancers.
Define the data model. Identify the main entities, their attributes, and relationships. Consider the choice of database type (SQL vs NoSQL) and justify your decision based on access patterns...
The user database and tweet like database are designed for scale, using a simple NoSQL approach.
tweet(), follow(), and like() should all be trivial and easily scaled.
get_top_tweets_from_followed(user) is a bit more complicated, which is why I added a "smaller list of user's recent tweets" in the user database. That smaller list should make it possible to process all the relevant recent tweets even if a user has hundreds or thousands of followers.
The global top tweets are a more complicated calculation, but only a finite number of recent tweets really need to be considered, which is why we can fit that into a relational DB. We also have caching there which will speed up reads, and provide availability in the face of a single point of failure in the DB.