Designing a URL Shortener Service


A URL shortener service converts long URLs into shorter, unique aliases that redirect to the original URLs. This is particularly useful for sharing links on platforms with character limits or for creating cleaner, more manageable links.


Functional Requirements:

Non-Functional Requirements:

2. Capacity Estimation
A. Assumptions: B. Throughput Requirements
C. Storage Estimation
D. Bandwidth Estimation
E. Caching Estimation
F. Infrastructure Sizing
Summary Table
Category Value
Daily Writes 1 million
Read:Write Ratio 100:1
Peak WPS 120
Peak RPS 12,000
Storage per URL 127 bytes
Yearly Storage 46.4 GB
Daily Read Bandwidth 50 GB
Peak Bandwidth 6 MB/s
Cache Memory Needed 25.4 MB
DB Requests (Peak) 120 RPS
API Servers 4-6 instances
Database Nodes 10-20
Cache Nodes 3-4

3. High-Level Design

The system comprises several components:

cache
4. Database Design
We Need to consider following points for database design:

A NoSQL database like DynamoDB or Cassandra is ideal because it efficiently handles billions of key-value lookups while offering high scalability and availability.


5. API Design

We will use REST API

  1. Endpoint: POST /api/v1/shorten
  2. This endpoint generates a shortened URL for a provided long URL.
    • Sample Request:
    •   {
          "long_url": "https://example.com/very/long/url/that/needs/shortening",
          "custom_alias": "",
          "expiry_date": "2024-12-31T23:59:59Z", // optional
          "user_id": "user123"
        }            
                
    • Sample Response:
    •   {
          "short_url": "http://short.url/abC123",
          "long_url": "https://example.com/very/long/url/that/needs/shortening",
          "expiry_date": "2024-12-31T23:59:59Z",
          "created_at": "2024-08-10T10:30:00Z"
        }            
                
  3. Endpoint: GET /{short_url_key}
  4. This endpoint redirects the user to the original long URL.jhmng

5. URL Generation Strategy

We'll consider the original long URL:
Original URL: https://www.example.com/some/very/long/url/that/needs/to/be/shortened

  1. Generate a Hash for the Original URL
  2. We'll use SHA-256 to hash the original URL, which produces a 64-character hexadecimal string.
    original_url = "https://www.example.com/some/very/long/url/that/needs/to/be/shortened"
    hash of URL = b7e23e62ec2ac4db238b3955f8bdb9e7dbe2cfd5c430f2c56f47020e54cd93b9

  3. Truncate the Hash to a Shorter Length
  4. Since the hashed value is long (64 characters), we truncate it to a shorter length (let's say 8 characters) to create a compact short URL.
    shortened hash : b7e23e62

  5. Convert the Truncated Hash to Base 10 (Decimal)
  6. The truncated hash (b7e23e62) is in hexadecimal (Base 16), so we need to convert it into Base 10 (decimal).
    base 10 decimal value = 30642050937830457017007473131008547234

  7. Convert the Base 10 Number to Base 62
  8. Now that we have the decimal (Base 10) number, we will convert it to Base 62.
    Base 62 encoding uses 62 characters: A-Z, a-z, 0-9.
    The encoding process involves repeatedly dividing the number by 62 and recording the remainders to build the Base 62 string.
    Base62-encoded short value = BfJ3HrsV

  9. Store the Mapping in a Key-Value Database
  10. Now, we store the mapping of the generated short URL (BfJ3HrsV) to the original URL in a key-value database.
    Original url : https://www.example.com/some/very/long/url/that/needs/to/be/shortened
    Short url : http://short.ly/BfJ3HrsV

  11. Redirect to the Original URL
Note: If a collision occurs, we can handle it by rehashing or appending random strings or timestamp during hasing, ensuring no two URLs map to the same short URL.
6. Handling Expiration and Deletion

For URLs with expiration:


7. Security Considerations

8. Scalability and Fault Tolerance

9. Conclusion

Designing a URL shortener involves careful consideration of scalability, performance, and security. By addressing these aspects, the service can efficiently handle high traffic volumes while providing a reliable user experience.