Return the long URL associated with a given short URL.
Non-Functional Requirements:
The system must operate in high availability (24/7)
The system must return the short or long URL under 2-digits in milliseconds (max 99ms)
The system must tolerate 24 million creations of shortened URLs per day
The system must save all urls for 10 years
API Design
Request:
POST /api/v1/shorten
Body: {"url": "www.google.com"}
Response:
Status Code 201 (created)
{"short-url": "bitly.ly/zn9e10A"}
Request:
GET /bitly.ly/zn9e10A
Response:
Status Code 301 (move permanently -> browser cache)
Header:
Location: "www.google.com"
Design
load balancer by using round robin can direct requsts to the correct servers and scale the number of pods based on requirements, I'd say memory or computational power can be good metrics to set when to scale the servers horizontally and add more pods to support the number of requests.
A cluster of servers so that Horizontal scalling can be handled
Cassandra to scale DB nodes as needed
Detailed Component Design
High-Availability (24/7) - so the system must have a cluster of servers so that if one goes down others can handle the requests while it's being recreated
To keep latency really low we can leverage browser caching by using HTTP Status Code 301 so responses can happen under two-digits in millisecond
This is an intense reading API. Let's assume for each 10 requests one is to create a new URL and 9 to read existing URL. Due to caching, the number of reading request to the server will be decreased, however, I'll still assume a ratio of 70% reads/30% writes. As a consequence, 1 million requests to read represents only 30% of the traffic. Therefore more 3,3 million read requests will happen per minute. Total around 4.5 million requests per minute. As the number of write requests is high Cassandra will have multiple scalable DB nodes that will help avoiding high write latency.
Over 10 years the system must be able to save 87.600.000.000 - approximatly 90 billion urls. Therefore a function responsible for creating non-collision IDs must be created. Base62 ^ 7 gives trillions of possible combinations so the hashId function can use it.