Tiny URL System Design

What do we understand by TinyURL or URL shortener?
A URL shortener is like giving a nickname to a long web address smaller, easier, but still takes you to the same place.
- A URL is just a web address (like https://www.longurl-website.com/some/very/long/link).
- Sometimes, links are too long, messy, or hard to share. A URL shortener is a tool that takes that long web address and gives you a much shorter version (like https://tinyurl.com/abc123).
- When someone clicks the short link, it automatically sends them to the original long web address.
Functional requirement
Generate short URL: When given a long web address, the system creates a unique, much shorter alias for easy sharing.
Redirect: When a user clicks or enters the short link, they're instantly redirected to the original long URL.
Custom short link (optional): Users can optionally create a custom alias for their short URL (like https://tinyurl.com/1b7328r).
Link expiration: Short links typically expire after a default period, but users may set custom expiration times.
Multiple short URLs for same long URL: Even if two users shorten the same long link, they can get different short URLs.
These requirements ensure TinyURL provides its core functionality creating short, unique links that redirect to long URLs, with useful options for managing, customising, and tracking those links.
Non-Functional Requirements (for completeness)
Performance: Redirection should be very fast (ideally < 100ms).
Scalability: Should support very high read (redirect) to write (shorten) ratio.
Reliability: No broken links; highly available.
Security: Validate URLs to avoid malicious links (phishing/malware).
Persistence: Shortened URLs should be stored reliably in DB.
Nature of TinyURL traffic : TinyURL is a read heavy application
Write (shorten URL) happens only once per long URL.
Read (redirect short URL) happens many times whenever users click that shortened link.
- Shows read-heavy path: Client → Cache (many reads), occasional DB hits.
- Shows write path: Shorten URL request → DB insert, optional cache update.
Example:
- You shorten a link once → tinyurl.com/abc123
.
- That short link might be clicked 1000s or millions of times.
API Design for TinyURL
1) Shorten URL
Endpoint:
POST /api/v1/shorten
Description: Create a short URL for a given long URL.
Request:
{ "originalUrl": "https://www.example.com/some/long/path?query=abc", "customAlias": "myLink123", // optional "expiryInDays": 30 // optional }
Response:
{ "shortUrl": "https://tiny.url/myLink123", "shortCode": "myLink123", "expiryDate": "2025-09-16T12:00:00Z" }
2) Redirect
Endpoint:
GET /{shortCode}
Description: Redirects to the original long URL.
Response:
302 Found
→ Redirects tooriginalUrl
.404 Not Found
→ If shortCode is invalid or expired.
3) Get URL Details
Endpoint:
GET /api/v1/url/{shortCode}
Description: Get metadata about a short URL.
Response:
{ "shortCode": "myLink123", "originalUrl": "https://www.example.com/some/long/path?query=abc", "createdAt": "2025-08-16T10:00:00Z", "expiryDate": "2025-09-16T12:00:00Z", "clicks": 1042 }
Sequence Diagram
1. Shorten URL Flow (with cache write-through)
Client API Gateway Application Server Cache Database
| | | | |
| POST /shorten | | | |
|---------------->| | | |
| | Validate URL | | |
| |----------------->| | |
| | | Generate shortCode |
| | |-------------------------------->|
| | | Save (short→long) |
| | |<--------------------------------|
| | | Write-through to Cache |
| | |--------------->| |
| | Return shortURL | | |
|<----------------| | | |
2. Redirect Flow (with cache lookup first, DB fallback)
Client API Gateway Application Server Cache Database
| | | | |
| GET /{short} | | | |
|---------------->| | | |
| | Lookup in Cache | | |
| |----------------->| | |
| | Cache HIT ? | | |
| |<-----------------| | |
| | Yes → Redirect | | |
|<----------------| | | |
| (Cache MISS) |
| | Lookup in DB | | |
| |----------------------------------------------->| |
| | Get longURL | |<--------------||
| | Save in Cache | | |
| |----------------->| | |
| | Redirect (302) | | |
|<----------------| | | |
High-Level Components
Client (Browser / Mobile App)
- Sends requests to shorten or resolve URLs.
API Gateway
Entry point for all clients.
Handles load balancing, authentication, rate limiting, and routing to microservices.
Service Discovery
Keeps track of available microservice instances.
API Gateway queries Service Discovery to route requests dynamically.
Microservices
URL Shortener Service
Handles creation of short URLs.
Writes data to Cache (write-through) and Database.
Redirect Service
Resolves short URL → original URL.
First queries Cache, then falls back to Database if cache miss.
Write-Through Cache (e.g., Redis)
Stores shortCode → originalURL mappings.
On writes, data is written to both Cache and DB simultaneously.
On reads, queries Cache first for speed.
Database
- Stores persistent mapping of shortCode → originalURL.
High-level-Design
Subscribe to my newsletter
Read articles from Ashwin Padiyar directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Ashwin Padiyar
Ashwin Padiyar
I have over 14 years of experience in the software industry. When I am coding or designing, I like to keep track of anything I learn. This blog is a sort of technical diary where I note down technical things. I am glad if anyone finds them helpful.