URL Shortening Service

Problem:
Design a system for creating a URL shortening service similar to TinyURL. This service will generate concise aliases that redirect to the original, longer URLs. Notable examples of such services include bit.ly, ow.ly, and short.io.
High-level design
Architecture:
The URL Shortening Service is designed as a scalable, high-performance, and fault-tolerant web system that allows users to generate, resolve, and track shortened URLs.
At a high level, the system follows a modular microservice-based architecture (or optionally monolithic for MVP), consisting of stateless services behind a load balancer, with persistent storage and a caching layer to optimize performance.
Key Design Principles
Stateless application layer: Enables easy horizontal scaling and fault recovery.
Separation of concerns: Each component (e.g., URL generator, redirect handler) performs a single, well-defined function.
Read-heavy optimization: Prioritized for high-throughput read operations, since redirection is the most frequent action.
High-Level Flow
URL Shortening Request:
The user sends a request with a long URL.
The system generates a unique short code (via hashing or sequence-based generation).
The mapping is saved to persistent storage and optionally cached.
The short URL is returned to the user.
URL Redirection Request:
When a user accesses a short URL, the service looks up the corresponding long URL.
If found in cache, it redirects immediately.
If not, it retrieves from the database, caches it, then redirects.
Components:
API Gateway: handles user requests
URL Shorten Service: Generate short code and validate URL
URL Redirect Service: Search for mapped URL with code
Cache Layer: Save database interaction and improves performance
Database: Store URL, metadata and user information
System requirements:
Functional:
URL Shortening:
URL Redirection:
Error Handling:
Non-Functional:
Availability:
Scalability:
Security:
Capacity Estimation:
URL Shortening:
URL Redirection:
API design:
API will follow the RESTful structure
API will follow the standard response
API will follow the versioning
API version will contain URL versioning method
Success Response:
{
data: {
url: "abc.ly/xu3isf1"
},
status: 200, //status code is be according to the API response
message: "success",
error: {}
}
Error Response:
{
data: {},
status: 422, //status code is be according to the API response
message: "validation failed",
error: {
code: 422,
message: "URL is invalid format"
}
}
Generate URL: v1/url POST
API will take 2 parameters
URL (required)
expiration (optional)
API will validate the URL is valid URL format
API will validate the URL duplication entry
API will generate the unique short URL
API will return the response in standard format containing shorten URL
GET All URL: v1/url GET
API will fetch all valid URL's from system
API will contain pagination meta data
API will send the response based on the pagination flow
GET Single URL: v1/url/{id} GET
API will fetch the URL based on the provided ID
API will send standard response containing URL and its information
DELETE URL: v1/url/{id} DELETE
API will fetch the URL based on the provided ID
.API will soft delete the URL of the provided ID
API will send standard success response
Redirect URL: GET
API will take 1 query param
- code
API will find the corresponding long URL associated with the code
API will validate its expiration
API will increase the count
API will return the original long URL
Database Design:
Tables:
users
id (unique, auto increment, primary)
name (string)
email (string, unique)
created_at (timestamp)
updated_at (timestamp)
deleted_at (timestamp)
short_urls
id (unique, auto increment, primary)
user_id (unique, foreign, reference users.id)
long_url (string)
short_url (string, unique)
code (string, unique)
expiry (date, nullable)
count (integer)
created_at (timestamp)
updated_at (timestamp)
deleted_at (timestamp)
ER Diagram
Request Flow:
URL Shorten Service
User will submit long URL
System will validate the URL
System will generate unique short code against the URL
System will map the long URL with short code and store in database
URL Redirect Service
User will open short URL from browser
Client end will detect the URL and send the short code to API
API will find the mapped long URL with the code
API will return long URL to client
Client will redirect user to long URL
Trade offs/Tech Choices:
Micro services:
Better for the separation of services
It might be a overload for MVP
Redis
Improves performance, reduces database load
An extra layer of implementation for the work
Relational Database (PgSQL)
Relational database provide consistency and better structure, using it with cache layer can provide a good performance while reading the data
DynamoDB could be the better option in terms of performance
Failure scenarios/bottlenecks:
increase in number of requests per second by the time system grows and more users are using the system.
Caching service capability to handle requests, if caching service goes down the load the shift to our database
Generating unique codes as the number of code has been generated in our system, system will face hurdle to generate new unique codes and it will increase the write time and database hits
Subscribe to my newsletter
Read articles from Irfan Mumtaz directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Irfan Mumtaz
Irfan Mumtaz
Hi, I'm Irfan — a software engineer with 10+ years of experience in designing and building scalable web applications. I specialize in system design, backend architecture, and clean, maintainable code. This space is where I share detailed system design write-ups, engineering insights, and solutions to real-world architectural problems. Currently exploring: distributed systems, infrastructure design, and scalable backend patterns. Connect with me on LinkedIn or GitHub