System requirements


Functional:

The system should take a full length URL and return a tiny url.

The system should handle a large amount of request.

The system should have high availability and should not go down.


The tiny URL should be randomlized and not guessable.

One full length URL can have multiple tiny URLs.

Users should be able to check what URLs they have converted.

Users can delete tiny URLs they generated.


Implement traffic meter for each user.


Non-Functional:

The pricing of the service.

The frontend control page for the URLs.





Capacity estimation

Traffic:

The system is expected to serve 10 million users, who are going to access the tiny url 100 times per day.

In total, thats 1 billion request per day.

If the requets are spreaded evenly, then on average, thats 1 billion/86400 seconds = 11k QPS.

If the peak is 5X the average, then we need to design a system that can handle 50k QPS.


Storage:

If 100k tiny URLs are created everyday,



API design


Users can generate their token on their Master account.


create_tiny_url(user_token, url) -> (tiny_url_id, tiny_url)

set_rate_plan(tiny_url_id, rate_plan_id)

get_url(tiny_url, user_id: optional) -> URL


Users can decide if user_id in the get_url is optional, i.e. is this a public API or is used by authorized people only.




Database design

URL table:

id: double

original_url: string

tiny_url: string

created_at: timestamp

updated_at: timstamp

deleted_at: timestamp

user_id: string

rate_plan: RatePlan


RatePlan table:

id: double

plan_type: enum

plan_rate: int

created_at: timestamp


Rate table:

id:double

url_id: double

requets_count_hour



Request Table (use data streaming table such as Snowflake, Kafka. This is for Audit usage)

Request user_id, ip, timestamp, type, url_id,




High-level design

Users can go to the master account webpage to create their url and tiny url pair.


They can choose a rate plan, and attach the plan to their URLs.

If an authorized person has requested a URL from the tiny url, the syste will return such URL, and possibly an automatic redirect if this is on the web browser.



Request flows

create_tiny_url()

then

get_url() from the user side.




Detailed component design

When generating tiny url, we will use md5 to hash the URL and make it the tiny URL. The length would be at maximum 10 characters. This will provide enough variations as (10 + 26) ** 10.


The users are also allowed to slect their own tiny hash, if this hash is not used.




Trade offs/Tech choices

The rate is estimated and is not real time. We will try to update the rate to reflect the real scenario.



Failure scenarios/bottlenecks

Try to discuss as many failure scenarios/bottlenecks as possible.






Future improvements

What are some future improvements you would make? How would you mitigate the failure scenario(s) you described above?