System requirements
Functional:
- shortening
- redirection
- scalability
- analytics
Non-Functional:
- they should be higly available
- performance
Capacity estimation
- DAU (daily active users) of around 1 million
Database design
- urls
- id
- short_url
- original_url
- created_at
- updated_at
- deleted_at
- url_accesses
- id
- accessed_at
- url_id
- success
High-level design
- load balancer for better user exeperience
- multiple nodes for horizontal scaling
- noSQL database to allow sharding, fast insertion and queries
- redis cache for urls with high access frequency
Request flows
- user sends a request to route 53 for dns resolution
- route 53 sends back the ip address of the load balancer
- request arrives at the load balancer, which in turn redirects to the node
- node queries by shortened url
- node receives long url
- node responds long url with http 302 code
- client is redirected to the long url
Detailed component design
Trade offs/Tech choices
- using SQL vs noSQL: I chose noSQL due to the faster read/write operation, sharding capability, simplicty
Failure scenarios/bottlenecks
- some URLs might be accessed too often, which is why I will allocate a redis cache for faster access and not to overload the database
- some regions might be accessed too frequently, which is why I could allocate specific nodes for those regions
- if an URL is not registered, service will respond http 404
Future improvements
- adding a CDN with the front page for faster service in remote parts of the globe