Receives full length URL and returns unique shortened URL. If a full length URL has been seen, return the shortened URL from before.
Allows user to create custom URL
Uptime: 99.9%
Data consistency. Shortened URL mapping should not be lost.
Latency - ideally user should receive a quick response in order to be redirected quickly (under 100 ms)
Tracking - User could view statistics about URL access. Geography, referral, click count.
100,000 URLs per day
100,000 / 24 = 4,000 URLs per hour
4,000 / 3600 = About 1 URL a second
POST long URL -> returns short URL
GET short URL -> returns long URL
The database can be a key-value store mapping short URL to long URL
The database can be partitioned into several instances.
Since it's a simple mapping from long URL to short and also the other way around, Redis can be used.
However, MongoDB or document stores may be considered. This is because they scale better and ensure data safety out-of-the-box. In Redis data persistence needs to be configured. We are also interested in storing long term statistics about the URL to show to the URL like number of clicks and geographies accessed from. MongoDB may have been support for aggregating and querying this data for developers.
Database can be managed like MongoDB Atlas for simplicity. Atlas can be deployed to same cloud network as the rest of the application for better latency.
The client can POST new URLs to shorten or GET URL from short URL to application server.
Application server saves URL mapping to MongoDB. Both directions are indexed so it can be looked up when a user creates a new URL to check for duplicates, and when clients click on the short URL to map to the long URL.
When users click on short URL, total click count is incremented by 1. Application server looks up user location based on IP from location locator service. Click count for that geography is incremented by 1. Can be separated by country. Since IP addresses are identified with cities, we could collect click data at the city level. Although proxy usage can skew this data, albeit it's a minority of traffic so we might consider not worrying about it. But the locator service could identify proxy traffic and classify it as its own bucket "proxy".
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...
The application server can be scaled either horizontally or vertically. Since we need to support 1 URL per second, a handful of instances should suffice (since transactions shouldn't stay open for more than a few seconds, one application server should be enough but we can have a couple more for redundancy in case it goes down).
The database can also be scaled, independently of the application, if necessary. If we assume each URL mapping takes around 256 bytes, we need 100,000 * 0.25 KB = 25 MB per day of storage, or on the order of 10 GB disk space for a year.
Explain any trade offs you have made and why you made certain tech choices...
A spike in traffic could cause the server to be overloaded.
What are some future improvements you would make? How would you mitigate the failure scenario(s) you described above?
Autoscaling could help.