1) Generate short url based on the long url, that user provided
2) Store url for some period, for example for 5 years, then delete it
3) Redirect user to the long url, using short url
4) Create a profile for the user, so they can generate unique short url for the same long one
5) Return error 404 when url is expired or incorrect and log all errors
6) Rate limiting
7) When user deleted url, give them a chance to restore it (remove it during the night)
1) Availability
2) Security (it should create unique non trackable short url, so nobody can guess it)
3) Low latency (performance)
4) Multiple regions
5) response time 50 msec
Let's set Read to Write Ratio = 100:1
Then we can say DAU = 1000000
Let's say that space for to store 1 pair takes 500 bytes.
Let's keep records by default 5 years
Amount of Concurrent users: 10% of DAU = 100000
Amount of URL shortened per month: 50 mln
Storage estimation:
DB Storage = 500 B* 50000000 *12*5 = 0,3 TB
Query rate estimation:
Request per month = 50 mln * 100 = 5 bln
Seconds in the month = 30.42 * 24 * 60 * 60 = 2628288 sec
QPS = 50 mln/2628288 = 19 URL/s
Redirection Rate = 100*19 = 1900 URL/s
Bandwidth estimation:
Shortening requests: 19 * 500 *8 = 76Kb/s
Redirection requests: 1900*500*8 = 7.6Mb/s
Total bandwidth = 9,5 + 95 = 7.68Mb/s
Memory estimation:
Let's assume 20% of redirects 80% of the traffic:
For a day: 1900 URL/s * 3600 s * 24h = 164 mln
0.2 * 164mln * 500 Bytes = 16,4 GB
Number of servers estimation:
Servers_at_peak_load = 1000000/64000 = 16 servers
1) Minify a url
POST /urls
body: { longUrl, userId, ttl }
201 Created
response: {shortUrl}
400 bad request
429 Too many requests
2) Redirect to long url
GET /short-url
302
Redirect to longUrl
404 not found
429 Too many requests
3) Create user
POST /sign-up
body: { userName, email, password }
201 Created
400 bad request
429 Too many requests
4) Sign in
POST /sign-up
body { userName, password }
201
response {JWT, refreshToken}
400 bad request
401 unauthorized
429 Too many requests
5) Get user account
GET /user/:id
200
response {userName, email, ttl, urls: urls[]}
6) Update user account
PUT /user/:id
body { userName, email, ttl, url }
400 bad request
401 unauthorized
403 Forbidden
429 Too many requests
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...
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...
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...
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...
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?