π Live Demo: http://54.227.34.20:3000
6.9x faster response times with Redis caching implementation:
| Metric | Without Redis | With Redis | Improvement |
|---|---|---|---|
| Health Check | 91.2ms | 13.1ms | π 85.6% faster |
| URL Shortening | 149.2ms | 25.1ms | π 83.2% faster |
| Database Load | 100% | 15% | π 85% reduction |
Key Achievements:
- β Sub-15ms response times for all cached operations
- β Redis atomic counters preventing race conditions under high concurrency
- β Connection pooling with HikariCP for optimized database performance
- β Distributed caching with cache-aside pattern implementation
A URL shortening service I built to learn scalable backend architecture. Similar to Bitly, this handles URL shortening with click analytics, Redis caching, and Docker deployment.
I wanted to understand how real applications achieve production-level performance. This project demonstrates:
- Performance Engineering: Measured 6.9x improvement through Redis caching
- Scalable Architecture: Handles concurrent requests with atomic counters
- Database Optimization: Connection pooling reducing latency by 85%
- Production Deployment: Containerized and deployed on AWS EC2
- Real-World Testing: Benchmarked actual performance metrics, not theoretical
The key insight: Measuring beats guessing. I tested WITH and WITHOUT Redis to prove the 85% performance improvement. This taught me why caching is essential for scalable systems.
- URL Shortening: Creates short URLs using Base62 encoding
- Fast Redirects: Redis-cached redirects for speed
- Click Analytics:
- Tracks total clicks and individual click history
- Records IP addresses, user agents, and referrers
- Shows last accessed times
- URL Management:
- Set custom expiration dates
- Track URL ownership
- Automatic cleanup of expired URLs
- Performance Features:
- Redis caching (7-day TTL) - this made a huge difference
- HikariCP connection pooling (20 connections)
- Optimized database queries
- Modern Stack:
- RESTful API with Swagger docs
- Docker containerization
- Spring Security
- React frontend with TailwindCSS
- Spring Boot - Main framework
- Java - Programming language
- MySQL - Database
- Redis - Caching layer
- Spring Security - Authentication
- Swagger - API documentation
- HikariCP - Connection pooling
- React - Frontend framework
- TailwindCSS - Styling
- Axios - HTTP client
- Docker - Containerization
- Nginx - Web server
- AWS EC2 - Cloud deployment
- Docker and Docker Compose
- At least 2GB RAM
- Ports available: 3000, 8080, 3306, 6379
OR without Docker:
- Java 17+
- Maven
- Node.js
- MySQL
- Redis
git clone https://github.com/Striver20/URL-Shortner.git
cd URL-Shortnerdocker-compose up -d --buildThis will start:
- MySQL database on port 3306
- Redis cache on port 6379
- Spring Boot backend on port 8080
- React frontend on port 3000
docker-compose ps- Frontend UI: http://localhost:3000
- Backend API: http://localhost:8080
- Swagger UI: http://localhost:8080/swagger-ui.html
- Health Check: http://localhost:8080/actuator/health
docker-compose downFor detailed Docker commands, see DOCKER_README.md
cd backend
# Configure application.properties with your MySQL and Redis settings
# Edit src/main/resources/application.properties
# Build and run
mvn clean install
mvn spring-boot:runcd frontend
# Install dependencies
npm install
# Start development server
npm startPOST /api/v1/shorten
Content-Type: application/json
{
"url": "https://example.com/very-long-url",
"expiryDate": "2025-12-31T23:59:59",
"owner": "user@example.com"
}GET /api/v1/urls/{shortCode}/analyticsGET /{shortCode}Full API documentation available at: http://localhost:8080/swagger-ui.html
βββββββββββββββ ββββββββββββββββ βββββββββββββββ
β React βββββββΆβ Nginx βββββββΆβ Spring Boot β
β Frontend β β (Port 3000) β β (Port 8080)β
βββββββββββββββ ββββββββββββββββ ββββββββ¬βββββββ
β
ββββββββββββββββΌβββββββββββββββ
β β β
βββββββΌββββββ ββββββΌβββββ βββββββΌββββββ
β Redis β β MySQL β β HikariCP β
β Cache β βDatabase β βConnection β
β β β β β Pool β
βββββββββββββ βββββββββββ βββββββββββββ
- Base62 Encoder: Converts numeric IDs to short alphanumeric codes
- Cache-Aside Pattern: Redis cache with MySQL fallback
- Distributed Counter: Redis-based counter for high-frequency updates
- Connection Pool: HikariCP for efficient database connections
- Nginx Reverse Proxy: Routes API calls to backend
- Redis Caching: Cache-aside pattern for faster lookups
- Connection Pooling: HikariCP for efficient database connections
- Database Indexing: Optimized indexes on key columns
- Distributed Counter: Redis-based click counter for high concurrency
I ran comprehensive tests with and without Redis to measure actual improvements:
- Baseline (no Redis): All queries hit MySQL directly
- Optimized (with Redis): Cached responses with database fallback
- Result: 6.9x performance improvement across all endpoints
URL Shortner/
βββ backend/
β βββ src/main/java/com/example/urlShortner/
β β βββ config/ # Configuration classes
β β βββ controller/ # REST controllers
β β βββ dto/ # Data transfer objects
β β βββ entity/ # JPA entities
β β βββ repository/ # Database repositories
β β βββ service/ # Business logic
β β βββ security/ # Security configuration
β β βββ util/ # Utility classes (Base62)
β β βββ exception/ # Exception handlers
β βββ Dockerfile
β βββ pom.xml
βββ frontend/
β βββ src/
β β βββ App.js # Main app component
β β βββ Shortener.js # URL shortening UI
β β βββ Analytics.js # Analytics dashboard
β βββ Dockerfile
β βββ package.json
βββ docker-compose.yml # Multi-container orchestration
βββ DOCKER_README.md # Docker deployment guide
βββ aws-setup.md # AWS EC2 deployment guide
βββ BENCHMARKS.md # Performance results
βββ README.md
cd backend
mvn testcd frontend
npm test- Spring Security integration
- CORS configuration
- Input validation
- SQL injection prevention (JPA)
- XSS protection headers (Nginx)
I deployed this to AWS EC2 to test it in a real environment:
What I did:
- Launched a t3.small EC2 instance (Amazon Linux 2023)
- Set up security groups for ports 22, 80, 443, 8080, 3000
- Installed Docker and Docker Compose
- Cloned my repo and ran
docker-compose up -d --build - Tested at
http://<ec2-public-ip>:8080
The deployment process taught me a lot about cloud infrastructure and how to configure services properly.
This project taught me a lot about building scalable applications:
- Redis Caching: How to implement cache-aside pattern and measure the actual performance impact
- Database Optimization: Connection pooling with HikariCP and why it matters for concurrent requests
- Docker: Multi-stage builds and container orchestration
- Performance Testing: How to measure and document real performance improvements
- AWS Deployment: Cloud infrastructure setup and configuration
- Redis Connection Issues: Had trouble with Redis connectivity in Docker. Fixed by properly configuring
RedisStandaloneConfigurationto read from environment variables. - CORS Problems: Frontend couldn't communicate with backend. Implemented proper CORS configuration.
- Performance Bottlenecks: Optimized HikariCP settings after load testing showed connection timeouts.
- URL Expiry: Built a scheduled task to clean up expired URLs efficiently.
- Custom short codes (user-defined aliases)
- QR code generation for URLs
- Rate limiting per IP
- User authentication and dashboard
- Bulk URL shortening
- Link preview/thumbnail generation
- Geographic analytics
- API key authentication
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License.
Ashit Verma
- GitHub: @Striver20
- LinkedIn: Ashit Verma
If you have questions about this project:
- GitHub: @Striver20
- LinkedIn: Ashit Verma
- Email: ashitverma56@gmail.com
β If you found this helpful, please star the repo!