A long URL must be shortened into a short URL
The short URL must redirect to the long URL
A unique long URL should map to a unique short URL
99.9% Availability
Custom URL setting
50,000 URLs shortened per day
100 reads per write
shortenURL (POST) - sends a request to shorten a URL and stores in the database
getShortURL (GET) - fetches the shortened URL for a long URL
The database will be a non-relational database with key-value stores. The keys are as follows:
longURL (string)
shortURL (string)
created_on (dateTime)
At a high level, there is a load balancer to distribute requests among servers. The servers send shortening requests to a message queue, which is then sent to the URL shortening service. The shortened URLs and corresponding long URLs are stored in a database, with the most frequently used URLs being stored in a cache.
At a high level, the client sends a request to a load balancer, which gets send to a server. If a URL is being shortened, the message gets put into the message queue, which is sent to the URL Shortening Service. Once it is shortened, it will be sent back to the web server, and then stored in the database. If a get request is being sent, it retrieves it from the database (or cache).
Component 1: URL shortening service
The URL shortening service takes the SHA1 hash of a long URL, and then encodes it with Base62 in order to make it shorter. When a request is sent to the web server, it checks for whether it exists in the database before forwarding the request to the shortening service.
Component 2: URL Storage in the Database
URLs are stored in the format:
longURL (string)
shortURL (string)
created_on (dateTime)
When a GET request is sent, the longURL is searched for in the database, which then returns the short URL. This then sends a redirect request in the form of an HTTP Status, which then converts the location to the longURL. There is also a cron-job that runs to check if any URLs have existed for more than 5 years, and those URLs get deleted from the database.
Trade offs: Instead of using a simpler URL shortening method, such as random string generation, more tech debt is incurred by using a hash function and Base62 encoding. This ensures that we won't have to check if the random string has been generated and assigned already, which in the long run, should lead to faster generation times. A message queue is also used, which may lead to longer loading times, but ensures that the URL Shortening service is not overloaded + allows for the service to run in parallel if it contains multiple servers.
If the web servers are down, then the entire system is down. However, we can avoid this bottleneck by utilizing multiple servers and duplicating this system across regions. Additionally, it is possible that the database gets overloaded, but we can perform database sharding and horizontal scaling in order to mitigate this issue.
Some future improvements would include adding a rate limiter to the web server in order to ensure the system does not get overloaded. Additionally, the cache can be optimized as a read-through cache to optimize for reads.