List non-functional requirements for the system...
Estimate the scale of the system you are going to design...
10 million URL shortening per day, write request is 100 QPS
100 million URL retrieval per day, read request is 1000 QPS
One entry (long url, short url), 100B
10^7 * 100B = 1GB per day, 365GB per year, 3.65TB per 10 years
If URL has 30-days expiration, then it is 30GB per month.
3.65B URLs per year, if using base-64 encoding, 6-7 digits.
Define what APIs are expected from the system...
REST api:
POST $originalUrl
GET $shortUrl
Defining the system data model early on will clarify how data will flow among different components of the system. Also you could draw an ER diagram using the diagramming tool to enhance your design...
The data structure is key-value pairs. So we should use no-sql database. Redis or dynamo. If expiration is 30 days, can use Redis without a DB.
You should identify enough components that are needed to solve the actual problem from end to end. Also remember to draw a block diagram using the diagramming tool to augment your design. If you are unfamiliar with the tool, you can simply describe your design to the chat bot and ask it to generate a starter diagram for you to modify...
DNS
Load Balancer
Proxy servers to redirect to write or read server, also optionally rate-limiting and user authentication.
write servers:
read servers:
Explain how the request flows from end to end in your high level design. Also you could draw a sequence diagram using the diagramming tool to enhance your explanation...
Write flow:
Read flow:
Analytics flow:
Dig deeper into 2-3 components and explain in detail how they work. For example, how well does each component scale? Any relevant algorithm or data structure you like to use for a component? Also you could draw a diagram using the diagramming tool to enhance your design...
URL shortening algorithm:
Write server:
Read servers/cache/database:
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?
Already mentioned how to resolve failure/bottlenecks in the last section. We could add some more user customization functions, e.g., set custom expiration for each URL, manage user owned URL list.