Evently is a backend platform for managing large-scale events with high concurrency. Users can browse events, book/cancel tickets, and track bookings, while admins can manage events and view analytics.
- Overview
- Features
- User Features
- Admin Features
- System Architecture
- Concurrency & Race Conditions
- Database Schema & Indexing
- Caching & Redis
- Throttling & Rate Limiting
- Dynamic Pricing (Stretch Goal)
- Deployment & Scalability
- APIs
- Environment Variables
- Background Jobs
Evently is designed to handle thousands of concurrent ticket bookings while preventing overselling. It ensures database consistency, supports analytics for event organizers, and is extensible for future features like surge pricing or waitlists.
- Browse a list of upcoming events (
/events) - View popular events (
/events/popular) - Book tickets with idempotency key (
/events/:id/book) - Confirm reservations (
/reservations/:id/confirm) - Cancel bookings (
/bookings/:id/cancel) - View booking history (
/bookings)
- Create and update events (
/admin/events) - View analytics: total bookings, most popular events, capacity utilization, cancellation rates (
/admin/analytics)
- Problem: High concurrent requests may oversell tickets.
- Solution:
- Redis soft reservations with TTL and atomic Lua scripts.
- Optimistic locking using the
versioncolumn in events.
- Trade-offs: Slightly higher implementation complexity and retry logic needed.
- Why no queue: Instant ticket confirmation is required; queueing would delay payment/confirmation.
- Background janitor: Scans expired Redis reservations and restores seat counts, keeping Redis consistent.
- Operational cost: Minimal, Upstash Redis free tier sufficient for MVP, production-scale would require Redis cluster.
- Entities: Users, Events, Bookings.
- Indexes: Optimized on frequently read fields (
users.email,events.start_time,bookings.user_id/event_id) to improve analytics query performance. - Caching: Redis caches frequently accessed data such as upcoming events, event details, and most popular events to reduce DB load.
- Trade-offs: Indexes improve read speed but add slight write overhead.
- Redis caches:
- Upcoming events
- Event details
- Most popular events
- Scalability: System can be horizontally scaled with multiple API instances; Redis acts as a centralized counter for reservations.
- Middleware: Limits API calls (e.g., 10 requests per minute) to prevent abuse.
- Ensures fair usage during traffic spikes.
- Fields:
base_price(fixed) andprice(adjustable). - Usage: Price can be adjusted based on event demand or capacity utilization.
- Background Job: Runs every 24 hours to apply pricing changes automatically.
- Benefit: Flexibility for surge pricing or future monetization strategies.
- Current: Deployed on Render for quick setup.
- Extensible: Can be deployed to Kubernetes, AWS ECS, or other containerized platforms.
- Horizontal Scaling: Multiple API instances can handle high traffic, coordinated via Redis.
| Endpoint | Method | Description |
|---|---|---|
/register |
POST | Register a new user |
/login |
POST | Login and receive JWT |
| Endpoint | Method | Description |
|---|---|---|
/events |
GET | List all upcoming events |
/events/popular |
GET | List top 5 most popular events |
/events/:id/book |
POST | Reserve a ticket (requires idempotency key) |
| Endpoint | Method | Description |
|---|---|---|
/reservations/:id/confirm |
POST | Confirm reservation in DB |
/bookings/:id/cancel |
POST | Cancel a booking |
/bookings |
GET | View user booking history |
| Endpoint | Method | Description |
|---|---|---|
/admin/events |
POST | Create an event |
/admin/events/:id |
PUT | Update an event |
/admin/analytics |
GET | Fetch analytics for bookings |
/admin/events/capacity_utilization |
GET | Event capacity utilization stats |
# PostgreSQL
DATABASE_URL=postgresql://<user>:<pass>@<host>:5432/postgres
# Upstash Redis
UPSTASH_REDIS_URL=<redis_url>
UPSTASH_REDIS_PASSWORD=<redis_password>
# JWT Secret
JWT_SECRET=supersecretkey
# Admin Email (optional)
ADMIN_EMAIL=[email protected]
ADMIN_EMAIL_PASSWORD=password- Redis Janitor: Cleans expired soft reservations and restores seat counts every minute.
- Dynamic Pricing Scheduler: Updates event prices based on capacity/demand every 24 hours.
- CI/CD Jobs: Automated jobs can be triggered via GitHub Actions for deployment or maintenance tasks.
- Fault Tolerance: Redis handles high concurrency atomically, and database transactions ensure source-of-truth integrity.
- Extensibility: The system is designed to support future enhancements like seat-level bookings, waitlists, and notification systems.