1) Shorten URL Generation: specify mechanism how to generate short url from long one
2) Redirect user from short url to the long one
3) Read URL Details: create a user account, so that user can see all urls he created
4) Possibility to update/delete urls in the user account
5) URL Expiration Management: allow user to add expiration time. Set default TTL for urls of 5 years.
6) Save some analytic (for example for url clicks)
7) Premium users could have a shorter urls
8) Error Handling: Implement functions for error handling that return meaningful messages for common issues, such as expired URLs, accessing URLs that do not exist, or unauthorized access.
1) Performance: Specify response time targets for different functionalities, like maintaining a response time under 10ms for redirection and slightly longer for URL creation.
2) Scalability: Detail the expected growth in traffic and how the system would scale to accommodate more users and URL requests, e.g., horizontal scaling of the database and caching layers.
3) Security: Emphasize the need for secure data storage, encryption of sensitive data (e.g., user credentials), and protection against common web vulnerabilities (like XSS and SQL Injection).
Also nobody should guess any short url.
4) Availability: Specify the expected uptime percentage (e.g., 99.99% uptime) and strategies for achieving high availability, such as redundancy and failover mechanisms.
5) Data Consistency: Ensure strong consistency, particularly for critical operations like creating and redirecting URLs, so that changes are immediately visible.
** Suggesion **
- shortening:redirection request ratio is 1:100
- 200 mln new shorten urls request per month
- A URL shortening entry requires 500 Bytes of database storage.
- each entry will have a maximum of five years of expiry time, unless explicitly deleted.
- 100 million DAU
**Storage:**
200 mln/month * 12 month * 5 years = 12 bln URL shorten requests
12 bln * 500B = 6 TB
**Query per second:**
Redirects: 200 Million * 100=20 Billion
Seconds in a month: 30.42 days * 24 hours * 60 mins * 60 secs = 2628288 secs
QPS (creation or shortenings): 200 mln / 2628288 secs = 76 URLs/sec
QPS (redirects): 100 * 76 URLs/s=7600 URLs/s
**Bandwidth:**
Incoming badnwidth: 76URLs/sec * 500B * 8bits = 304 Kbps
Outgoing bandwidth: 7600URLs/sec * 500B * 8bits = 30400 Kbps
Total bandwidth = 304 Kbps + 30400 Kbps = 30.4 Mbps
**Memory estimation:**
20 percent of redirection requests generate 80 percent of the traffic
7600 * 3600 secs * 24 hrs = 0.66 bln
0.2 * 0.66 bln * 500B = 66 GB
**Servers neeeded:**
100 mln RPS/s/64000 RPS/s = 1.6K servers
## API design
- Shorten url: POST "/urls/shorten", body: {long_url, user_id, ttl}, response: {short_url, ttl}, status_codes: [201, 400, 429]
- Redirect url: GET "/short_url", status_codes: [302, 404, 429]
- Create user account: POST "/sign-up", body: {firstname, lastname, email, password }, response: {id, firstname, lastname, email}, status_codes: [201, 400, 429]
- Get user settings: GET "users/:id", response: {id, firstname, lastname, email}, status_codes: [200, 404, 429]
- Sign-in a user: POST "/sign-in", body: {email, password }, response: {id, firstname, lastname, email, jwt, refresh_token }, status_codes: [200, 400, 401, 429]
- Get user's urls: GET "/users/:id/urls", response: { urls: [{id, url}] }, status_codes: [200, 403, 404, 429]
- Update url for the user: PUT "/users/:id/urls/:id", body: {updated_url}, response: {updated_url}, status_codes: [200, 403, 404, 429]
- Delete url for user: DELETE "/users/:id/urls/:id", status_codes: [204, 403, 404, 429]
**Rate limiter:**
Anon. user:
shorten requests (10-50/ min)
redirects requests (100- 300/min)
Signed users:
shorten requests (100-500/ min)
redirects requests (10000 - 30000/min)
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?