Requirements
Functional Requirements
Core Features
- Generate a shortened URL from a long URL.
- Redirect users from the shortened URL to the original URL.
- Store URL mappings persistently.
- Track basic analytics (optional):
- Click count
- Creation timestamp
- Last accessed timestamp
System Components
API Service
Technology Stack
- Python
- FastAPI
- Alembic
Responsibilities
- Create short URLs
- Validate URLs
- Redirect requests
- Expose analytics endpoints
Database
Technology: PostgreSQL
Responsibilities
- Store URL mappings
- Store metadata and analytics
Schema Example
urls
-----
id
checksum
original_url
created_at
click_count
Indexes
UNIQUE INDEX(checksum)
INDEX(created_at)
Since retrieval is primarily by short code, a unique B-tree index is sufficient.
Cache Layer
Technology: Redis
Responsibilities
- Cache frequently accessed URLs
- Reduce database reads
- Share cache across multiple application instances
Cache Flow
Request
↓
Redis
↓ (miss)
PostgreSQL
↓
Redis Update
For an MVP, an in-memory cache could be enough. Redis becomes valuable once multiple API instances are deployed.
Reverse Proxy
Technology: Nginx
Responsibilities
- SSL termination
- Rate limiting
- Load balancing
- Request filtering
- Compression (gzip/brotli)
Flow
Client
↓
Nginx
↓
FastAPI
Non-Functional Requirements
Performance
Low Latency
- Redis caching for frequently accessed URLs.
- Proper indexing on checksum.
- Use connection pooling.
- Avoid unnecessary joins.
Scalability
Horizontal Scaling
Nginx
↓
-----------------------
↓ ↓ ↓
App-1 App-2 App-3
↓
Redis
↓
PostgreSQL
Strategies:
- Stateless application instances.
- Shared Redis cache.
- Kubernetes for auto-scaling (future).
Reliability
Current MVP:
App
↓
PostgreSQL
Future:
Primary DB
↓
Read Replica
Possible improvements:
- Automated backups.
- Point-in-time recovery.
- Health checks.
Resilience
Strategies:
- Multiple application replicas.
- Kubernetes restart policies.
- Readiness and liveness probes.
- Graceful shutdown handling.
- Circuit breakers and retry policies for external services.
Observability
Logging
- Structured JSON logs.
- Rotating log files.
- Request and error logging.
Monitoring
Recommended tools:
- Prometheus
- Grafana
Metrics:
- Request count
- Latency
- Error rate
- Cache hit ratio
Distributed Tracing
- OpenTelemetry
- Jaeger or Tempo
Security
Application Layer
- URL validation.
- Input sanitization.
- Rate limiting.
- API authentication (if admin endpoints exist).
Infrastructure Layer
Nginx provides:
- TLS/SSL termination.
- Request filtering.
- Rate limiting.
Additional recommendations:
- Security headers.
- Secrets management.
- Database credential rotation.
- HTTPS-only communication.
Future Scope
- Custom aliases (
myapp.com/openai) - URL expiration
- QR code generation
- User accounts
- Click analytics dashboard
- Geo-location analytics
- PostgreSQL replicas
- Kubernetes deployment
- CDN for global redirection performance
Capacity Estimation
Estimate the scale of the system. Consider daily active users, read/write ratio, storage requirements, bandwidth, and any relevant QPS calculations...
API Design
For URL shortening, we can use FastAPI REST APIs to expose endpoints that allow users to create shortened URLs, redirect users, and monitor service health.
The API service will handle:
- URL validation
- Checksum generation
- Duplicate URL detection
- Storing URL mappings
- Generating shortened URLs
- Redirecting users to the original URL
API Contract
1. Create Shortened URL
Endpoint
POST base_url/v1/shortenUrl
Request Payload
{
"url": "http://example.com/aaaaaaaaaaa"
}
Processing Flow
User URL
|
v
Generate checksum
|
v
Check PostgreSQL
|
+------ Exists ------> Return existing shortened URL
|
+------ New ---------> Store URL mapping
|
v
Return shortened URL
Response Payload
{
"statusCode": 20001,
"data": {
"shortenedUrl": "https://base_url/a8f3d2"
},
"errorDetails": []
}
Where:
statusCode→ Application-level response code.data→ Contains generated shortened URL.errorDetails→ Contains error information if request fails.
Example error response:
{
"statusCode": 50001,
"data": null,
"errorDetails": [
{
"errorCode": "INVALID_URL",
"details": "Provided URL format is invalid"
}
]
}
2. Redirect Shortened URL
Endpoint
GET base_url/{hash_id}
Where:
hash_idis the checksum generated for the original URL.- The checksum acts as the unique identifier for retrieving the URL mapping.
Example:
Request:
https://base_url/a8f3d2
Flow:
Client
|
v
Redis Cache
|
Cache Miss
|
PostgreSQL Lookup using checksum
|
Retrieve original URL
|
301/302 Redirect
Response:
HTTP 302 Redirect
Location:
https://example.com/aaaaaaaaaaa
3. Health Check Endpoint
Endpoint
GET base_url/health
Purpose:
- Kubernetes health monitoring.
- Verify application availability.
- Used for readiness/liveness checks.
Example response:
{
"status": "UP"
}
Rate Limiting
Rate limiting can be implemented at two levels:
1. Reverse Proxy Level (Recommended for Production)
Using Nginx:
Client
|
v
Nginx
|
v
FastAPI
Advantages:
- Requests are rejected before reaching the application.
- Protects backend resources.
- Better for large-scale deployments.
Example:
100 requests/minute/IP
2. Application Level (Development / Fine-Grained Control)
FastAPI middleware-based rate limiting can be used for:
- Local development.
- Testing.
- API-specific limits.
Example:
POST /shortenUrl
50 requests/minute/user
Additional Considerations
Duplicate URL Handling
Since checksum is used:
URL A
|
v
checksum = abc123
URL B
|
v
checksum = abc123
Before storing:
- Generate checksum.
- Check existing checksum.
- If checksum exists:
- Same original URL → return existing shortened URL.
- Different URL → regenerate checksum to avoid collision.
Future API Extensions
GET /v1/analytics/{hash_id}
Provides:
- Click count
- Creation timestamp
- Last accessed timestamp
DELETE /v1/url/{hash_id}
For URL expiration/removal.
- This API design keeps the service simple for MVP while allowing future scaling with Redis caching, Nginx rate limiting, PostgreSQL replication, and Kubernetes deployment.
High-Level Design
The URL shortening system consists of multiple components responsible for accepting URL creation requests, storing URL mappings, serving redirects with low latency, and maintaining reliability and scalability.
The main components are:
- Client
- Sends requests to create shortened URLs.
- Accesses shortened URLs for redirection.
- Reverse Proxy (Nginx)
- Acts as the entry point for all requests.
- Handles:
- SSL/TLS termination
- Rate limiting
- Request filtering
- Load balancing between application instances
- Compression
- FastAPI Backend Service
- Core business logic layer.
- Responsibilities:
- Generate checksum for URLs.
- Validate incoming URLs.
- Check existing URL mappings.
- Store new URL mappings.
- Retrieve original URLs for redirects.
- Provide health and analytics endpoints.
- Redis Cache
- Used to reduce database load.
- Stores frequently accessed URL mappings.
- Flow:
Request
|
v
Redis
|
Cache Miss
|
PostgreSQL
|
Update Redis
- PostgreSQL Database
- Persistent storage layer.
- Stores:
- Checksum
- Original URL
- Creation timestamp
- Last accessed timestamp
- Click count
- Monitoring and Observability
- Application logs.
- Metrics collection.
- Distributed tracing.
Tools:
- Prometheus
- Grafana
- OpenTelemetry
Database Design
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...
Detailed Component Design
Deep dive into 2-3 key components. Explain how they work, how they scale, discuss tradeoffs, capacity, and any relevant algorithms or data structures.