My Solution for Designing a Simple URL Shortening Service: A TinyURL Approach with Score: 8/10
by grove_xenon832
System requirements
Functional:
- Able to accept the given URL and provide a shorter unique URL.
- It should redirects to correct long URL while retrieving.
- Need a User management where user can add long URL and get short URL.
- Customization on short URL.
- Analytics no of hits, most used.
Non-Functional:
- Not more than one short URL for long URL.
- High availability
- Response time should be lesser.
Capacity estimation
- We can use NoSQL data base to store URLs.
- This will provide key value store options.
- It can scale horizontally Sharding.
- For larger read capacity we distribute the DB across regions and provide caching for most used URL.
API design
Method URL Request_body Response _body
- POST -> /short-url {"url" :"new url"} {"shortURL" : "shorter url"}
- PUT -> /short-url {"url" : "updated url" {"shortURL" : "shorter url"}
- GET -> /long-url/{short-url} {"longURL : "long url"}
- GET -> /redirect/{short-url} redirects to actual url {"longURL : "long url"}
- DELETE -> /short-url/{short-url} 200 ok
- DELETE -> /long-url/{long-url} 200 ok
- Both DELETE will un map and deletes the URLs from DB.
- GET -> count/{short-url} {"totalCount" : "no of hits"}
Database design
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...
- 3 tables
- url_mapping -> maps short-long url and user.
- user -> users personal data
- analytics -> hit count short_url
High-level design
Diagram attached
Request flows
diagram attached
Detailed component design
Database :
- The database requires high read/write capacity especially read.
- we provide master slave instance and multiple replicas across regions for data consistent.
- For scalability and performance we can use sharding and indexing.
Cache :
- The Most recently used can be cached.
- Least recently used can be evicted.
- Use global datastore for replicas of cache.
Servers :
- Can run the applications in multiple instance (Auto scalable).
- This will improve the availability.
Load balancer:
- It can split the request traffic across servers instance.
- Rate limiting and retry the request will reduce server load.
- A scalable Load balancer is good.
Trade offs/Tech choices
- The Redis as DB be very faster but cost a lot.
Failure scenarios/bottlenecks
- Heavy network traffic.
- when large DB hits (Non cached url request)
Future improvements
- Custom url
- Faster redirections