Real-world Systems
12 min forge

URL Shortener Design

How to design a scalable URL shortening service like Bitly or TinyURL.

πŸ”— URL Shortener: System Design

Designing a URL shortener is a classic system design interview question. It tests your ability to handle read-heavy traffic, generate unique IDs, and optimize for low latency.

1. Requirements

Functional

  • Shortening: Given a long URL, return a much shorter, unique alias.
  • Redirection: When a user hits the short URL, redirect them to the original long URL (HTTP 301/302).
  • Custom Aliases: Users should be able to specify a custom short link (optional).
  • Expiry: Links should have a default expiration time.

Non-Functional

  • High Availability: Redirection must always work.
  • Low Latency: Redirection should be near-instant.
  • Uniqueness: No two long URLs should result in the same short URL (unless specified).
  • Scalability: Handle millions of requests per day.

2. API Design

Shorten URL

POST /api/v1/shorten

  • Request: { "longUrl": "https://example.com/very/long/path", "customAlias": "optional-nick" }
  • Response: { "shortUrl": "https://forge.ly/abc123" }

Redirect URL

GET /{shortCode}

  • Response: 301 Redirect to the original long URL.

3. Storage Schema

We need a database to map shortCode to longUrl.

Database Choice: NoSQL (e.g., MongoDB/DynamoDB)

  • Why? We don't need complex relations. A simple Key-Value store or Document store is faster and easier to scale.
  • Schema:
    • shortCode (PK)
    • longUrl
    • userId (optional)
    • createdAt
    • expiryDate

4. Short Code Generation Strategies

A. Hashing (MD5/SHA)

  • Hash the long URL and take first 7 characters.
  • Problem: Collisions. Two URLs might produce the same hash.
  • Fix: Check DB for collisions, append a salt if it exists. (Expensive).

B. Base62 Encoding

  • Convert a unique numeric ID (like 12345) to a string using characters [a-z, A-Z, 0-9].
  • 7 characters in Base62 = $62^7 \approx 3.5$ trillion unique IDs.
  • How to get a unique numeric ID? Use a Key Generation Service (KGS).

C. Key Generation Service (KGS)

  • A dedicated service that pre-generates unique keys and stores them in a "Key Table".
  • When a new URL needs shortening, just grab a key from the table.
  • Scalability: Use two tables (Used vs. Unused) or keep keys in memory with persistent backup.

5. High-Level Architecture

mermaid Standard
graph TD User --> LB[Load Balancer] LB --> Web[Web Servers] Web --> Cache[Redis Cache] Cache --> DB[(NoSQL DB)] Web --> KGS[Key Generation Service] KGS --> KDB[(Key DB)]

6. Optimization: Caching & Redirection

Caching

  • Redis should store the mapping of the most frequently accessed short URLs.
  • Policy: LRU (Least Recently Used) is ideal.

301 vs 302 Redirect

  • 301 (Permanent): Browser caches the redirection. Reduces load on our servers but makes analytics harder to track.
  • 302 (Temporary): Browser asks our server every time. Better for tracking clicks/analytics, but higher server load.

7. Scalability & Maintenance

  • Database Sharding: Shard based on the shortCode hash.
  • Cleanup Service: A background worker that periodically deletes expired links.
  • Analytics: Push click data to a Message Queue (Kafka) for processing without blocking the redirection flow.