https://example.com/articles/system-design/url-shortener
↓
https://sho.rt/aB3xYz
Non-Functional Requirements:
Estimate the scale of the system. Consider daily active users, read/write ratio, storage requirements, bandwidth, and any relevant QPS calculations...
Endpoint
POST /api/v1/urls
Request
{
"longUrl": "https://www.example.com/blog/system-design/url-shortener",
"customAlias": "design101",
"expirationTime": "2026-12-31T23:59:59Z"
}
longUrl – Required.customAlias – Optional. If provided, the system checks whether it's available.expirationTime – Optional.Success Response (201 Created)
{
"shortCode": "aB3xYz",
"shortUrl": "https://sho.rt/aB3xYz",
"expiresAt": "2026-12-31T23:59:59Z"
}
Possible Errors
400 Bad Request – Invalid URL.409 Conflict – Custom alias already exists.429 Too Many Requests – Rate limit exceeded.Endpoint
GET /{shortCode}
Example:
GET /aB3xYz
Server Processing
Response
HTTP/1.1 302 Found
Location: https://www.example.com/blog/system-design/url-shortener
Interview note: I'd use 302 Found by default because it allows the destination to change later if needed. If links are permanent and immutable, 301 Moved Permanently can improve browser and CDN caching.
Endpoint
GET /api/v1/urls/{shortCode}/analytics
Response
{
"totalClicks": 15234,
"uniqueVisitors": 10872,
"topCountries": [
{
"country": "US",
"clicks": 6200
},
{
"country": "IN",
"clicks": 4100
}
],
"createdAt": "2026-01-01T10:00:00Z"
}
Requires authentication since analytics belong to the link owner.
Endpoint
DELETE /api/v1/urls/{shortCode}
Response
204 No Content
Only the owner (or an administrator) should be allowed to perform this operation.
Endpoint
PATCH /api/v1/urls/{shortCode}
Request
{
"expirationTime": "2027-01-01T00:00:00Z",
"enabled": false
}
This endpoint can update mutable properties like expiration or enable/disable status. Whether to allow changing the destination URL depends on product requirements.
+------------------+
| Client |
+--------+---------+
|
HTTPS Request
|
+--------v---------+
| DNS / CDN |
+--------+---------+
|
+--------v---------+
| Load Balancer |
+--------+---------+
|
+-------------+-------------+
| |
+-------v-------+ +-------v-------+
| API Servers | | Redirect |
| (URL Create) | | Servers |
+-------+-------+ +-------+-------+
| |
| |
+-------v-------+ +--------v--------+
| Redis Cache |<-------->| Read Cache |
+-------+-------+ +--------+--------+
| |
+-------------+-------------+
|
Cache Miss
|
+--------v---------+
| URL Database |
| (Primary + |
| Read Replicas) |
+--------+---------+
|
Async Event
|
+--------v---------+
| Message Queue |
+--------+---------+
|
+--------v---------+
| Analytics Service|
+--------+---------+
|
+--------v---------+
| Analytics DB |
+------------------+
Define the data model. Identify the main entities, their attributes, and relationships. Consider the choice of database type (SQL vs NoSQL) and justify your decision based on access patterns...
Deep dive into 2-3 key components. Explain how they work, how they scale, discuss tradeoffs, capacity, and any relevant algorithms or data structures.