List functional requirements for the system (Ask the chat bot for hints if stuck.)...
User should be able to turn a long URL to a short URL
User should be able to remove a short URL
When users click the short URL, they should be redirected to the long URL
List non-functional requirements for the system...
The system should be highly consistent and highly available
The system should have low latency
Estimate the scale of the system you are going to design...
There may be upto 100,000 daily active users
Each user can create a URL, perhaps an average of 1000 URLs per day
Each URL can be clicked 100 times per day.
This means there will be more reads than writes
There will be about (100,000,000 * 100) / 100,000 =>100,000 reads per second, and 1,000 writes per second
Define what APIs are expected from the system...
POST /v1/tiny-url?url=
GET /v1/tiny-url?shortUrl=
DELETE /v1/tiny-url?shortUrl=
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...
User
ShortenedURL
One User to one or many ShortenedURLs
We can use a NoSQL database here as we don't need any kind of complex queries or joins. This means we can easily partition the users by UserId and ShortenedUrls by the ShortURL.
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...
A user will interact with the API gateway to shorten a long URL. They need to be authenticated, hence the API gateway. From there, the request will go to the load balancer to distribute load among the services. We will have to main services -- the ShorteningService, responsible for shortening the long URLs, and the RedirectService, responsible for fetching the long URL from the short URL and redirecting the user. When the user initially creates a short URL, it will go to the ShorteningService which will generate a unique short URL based on a hashing algorithm. From there, it will persist it to the database and return the shortened URL to the user. When a user clicks on a shortened URL, it will go through the API Gateway and loadbalancer and reach the RedirectService. The RedirectService will query the database for the unique short URL, and then forward the user to the long URL. To optimize this, we can introduce a cache which will store the most used URLs, with the short URL as the cache key and the long URL as the cache value. If the requested shortened URL isn't in the cache, the service will go to the database and add the entry in the cache. At capacity, the cache will evict using LRU policy.
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...
There will be multiple instances of the ShorteningService and more instances of the RedirectService. The LoadBalancer will be responsible for distributing the request load to each service through an approach like Round Robin or Consistent Hashing. Additionally, we will have a cache on the RedirectService which will be useful when users are requesting the same shortened URL, for example a popular tweet included the short URL. The cache will contain these popular URLs so that less database reads are needed.
Explain any trade offs you have made and why you made certain tech choices...
By selecting a NoSQL database, we have most likely eliminated the ACID properties that are normally guaranteed on a SQL database. This means we need to be a bit more methodical with how we approach insertions to the database. On the upside, we will be able to scale the reads better, which is needed for this system to be highly available.
Try to discuss as many failure scenarios/bottlenecks as possible.
As mentioned, some bottlenecks might be if the system is hit by a popular URL by many users. This could lead to things like a hot partition on the DB if we do not have a cache.
What are some future improvements you would make? How would you mitigate the failure scenario(s) you described above?