Introduction
A URL Shortener service takes a long URL (like https://example.com/some/very/deep/path
) and produces a much shorter alias (like https://short.ly/aBcD12
). Users accessing the short URL are redirected to the original long URL. Examples include TinyURL, Bitly, etc.
Functional Requirements
Features
Shorten a long URL
Redirect from Short URL → Long URL
Analytics
Users
100M DAU (daily active users)
100:1 read to write ratio
1M writes/day
500 bytes each entry size
Data retention for 5 years
Non-Functional Requirements
High Availability - The system should be available 24/7, minimal downtime.
Low Latency - Redirects should be very fast (~200 ms).
High Durability - Data must persist even if servers crash.
API Endpoints
-
POST /api/urls/shorten
Request Body:
{ "longUrl": "https://example.com/some/very/deep/path" }
Response Body:
{ "shortUrl": "https://short.ly/aBcD12" }
-
GET /:shorturl
Response Body:
{ "longUrl": "https://example.com/some/very/deep/path" }
High Level Design
Initial flow for a URL Shortening service will have:
-
Client sends a URL to shorten
- The client sends a
POST
request to the API Gateway, including the original long URL.
- The client sends a
-
API Gateway Forwards to URL Shortening Service
- The API Gateway routes the request to the URL Shortening Service.
- This service:
- Generates a
shortCode
- Saves the mapping (
shortCode → longUrl
) in the database - Returns the short URL to the client (e.g.,
https://short.ly/abc123
)
- Generates a
-
Client Uses the Short URL
- When anyone clicks the short URL (
https://short.ly/abc123
), aGET
request is sent to the API Gateway.
- When anyone clicks the short URL (
-
API Gateway Routes to URL Redirection Service
- The Redirection Service looks up the short code (
abc123
) in database.
- The Redirection Service looks up the short code (
-
Redirect to Original URL
- Once the long URL is retrieved, the service responds with a 301 or 302 redirect to the original long URL.
- The browser follows this redirect and loads the long URL.
Optimize Design & Deep Dives
-
How will someone be redirected to original url when clicked on short url?
- When someone clicks on short url, the URL Redirection Service finds corresponding short url in DB.
-
And responds with an HTTP 302 status code (or 301), along with the
Location
header:
HTTP 302 Found Location: https://www.example.com/very/long/path?ref=campaign
-
Why use 302 (Found) instead of 301 (Moved Permanently)?
-
302 is Temporary:
- Tells browsers - "This redirect might change later. Don't cache it permanently."
-
301 is Permanent:
- Tells browsers and search engines: "This link will always go to the same place."
- Browsers will cache it permanently.
-
302 is Temporary:
-
Why use NoSQL DB for a URL Shortener?
- URL shorteners are a perfect fit for NoSQL because they involve simple key-value lookups. For example, you just need to map
shortCode → longUrl
, which doesn’t require complex joins or relationships. -
NoSQL offers:
- High read/write throughput
- Schema flexibility (you can add tracking data later)
- Horizontal scalability (easily handle millions of requests)
- Low-latency key-based access
We can use a highly available DB (eg, DynamoDB or Cassandra) to persist mappings
- URL shorteners are a perfect fit for NoSQL because they involve simple key-value lookups. For example, you just need to map
-
What data should we store in the DB?
-
URL
{ "shortCode": "abc123", "longUrl": "https://www.example.com/very/long/article?id=12345", "createdAt": "2025-09-14T10:00:00Z", "userId": "77a211ff" }
-
-
User
{ "userId": "77a211ff", .... }
-
As we know URL Shortener is Read heavy, so how can we optimize our system?
-
Add a Caching Layer (eg. Redis)
- Cache popular
shortCode → longUrl
mappings - Reduces database reads and latency
- Use TTL or LRU eviction policy to manage memory
- Cache popular
-
Use indexing on
shortcode
in DB- Ensure the DB has a proper index on
shortcode
field. - Speeds up lookup queries for redirection.
- Ensure the DB has a proper index on
-
-
How to generate unique IDs for each long url?
Generating unique, collision-free short codes is critical to the URL shortener’s design. Here are the most common methods:
-
Auto-Incrementing Counter + Base62 Encoding
- Use a global counter that increments for each new URL.
- Convert the counter number to Base62 (0-9, A-Z, a-z) to get a short, URL-friendly string.
- Example:
125 → "cb"
-
Pros:
- Simple, predictable, no collisions.
- Very short codes.
-
Cons:
- Needs centralized counter (hard to scale).
- Sequential URLs can reveal traffic volume.
-
Random String with Collision Check
- Generate a random Base62 string of fixed length (eg., 6 chars).
- Check the database for collisions, regenerate if exists.
-
Pros:
- Easy to scale horizontally.
- Hard to guess next short code (better privacy).
-
Cons:
- Small collision risk (can be minimized by length).
- Requires DB check on every generation.
-
Hashing the Long URL
- Hash the original URL (MD5/SHA) and use first N chars as short code.
- Same long URL always gets same short code.
-
Pros:
- Idempotent (no duplicates for same URL).
- No centralized state needed.
-
Cons:
- Collision risk.
- Slightly longer or less friendly codes.
-
UUID or GUID Encoding
- Generate a UUID, encode in Base62 or hex.
- Use a substring as the short code.
-
Pros:
- Globally Unique.
-
Cons:
- Codes are longer.
Note: For most URL shorteners, especially at small to medium scale, the Random String + Collision Check method offers the best balance.
-
-
How can we scale the system to handle High Traffic?
-
Sharding:
- To handle high traffic and scale efficiently, we can use sharding to distribute data and load across multiple machines. This enables horizontal scaling, allowing us to add more nodes as traffic grows without major reconfiguration.
-
Load Balancing:
- Use load balancers to distribute incoming requests evenly across services.
- Prevents any one server from being overloaded.
-
CDN Edge Caching
- Use a CDN (e.g., Cloudflare) to cache redirects at edge locations.
- Reduces latency for global users.
- Offloads requests before they even hit your backend.
-
Final Design
If you found this post helpful, feel free to:
💬 Drop a comment — I’d love to hear your thoughts or answer your questions!
🔁 Share it with others learning system design.
📌 Follow me here on Dev.to for more deep dives like this!
Thanks for reading! :)
Top comments (0)