A production-grade, distributed event ticketing and seat reservation platform built with Java 25, Spring Boot 4, PostgreSQL 16, Docker, and React.
QuickTix addresses high-concurrency seat booking scenarios where multiple users attempt to reserve the same seat simultaneously. The platform guarantees strict consistency and zero double-bookings through database-level transactions and optimistic locking.
Live Deployment: https://quicktix-weld.vercel.app/
QuickTix operates as a decoupled client-server architecture:
[ Client: React + Vite ]
| (HTTPS / REST)
v
[ Reverse Proxy / Cloud Gateway ]
| (Port 8080)
v
[ Spring Boot 4 Backend Application ]
├── Spring Security (Stateless JWT Filter)
├── Controller Layer (22 REST Endpoints, OpenAPI 3.0)
├── Service Layer (Business Rules & Ownership Enforcement)
└── Persistence Layer (Spring Data JPA / Hibernate ORM)
└── Database Concurrency (@Version Optimistic Locking)
|
v (JDBC Pool - HikariCP)
[ PostgreSQL 16 Database ] (Containerized / Persistent Volume)
Ticket booking platforms encounter severe concurrency bottlenecks during high-demand on-sale windows. Without robust concurrency controls, simultaneous requests result in race conditions, phantom reads, and double-sold seats.
QuickTix implements Optimistic Concurrency Control (OCC) combined with declarative database transactions:
- Entity Versioning: The
Seatentity incorporates a@Version private Long version;field managed by Hibernate. - Atomic Batch Processing: Seat reservations execute within a
@Transactionalboundary across a collection of seat IDs (List<Long> seatIds). - Collision Detection: When concurrent requests attempt to reserve the same seat, the first committing transaction succeeds and increments the version column (
UPDATE seats SET status = 'BOOKED', version = version + 1 WHERE id = ? AND version = ?). - Automated Rollback: Conflicting concurrent transactions fail the version predicate, triggering an
ObjectOptimisticLockingFailureException. The Spring transaction manager immediately rolls back all seat modifications in the batch. - Deterministic Error Handling: A centralized
GlobalExceptionHandlerintercepts the collision and produces a standardized409 Conflictresponse with human-readable diagnostic details.
A high-concurrency simulation dispatching 10 parallel requests (Promise.all) for the exact same seat within 1 millisecond yields deterministic isolation:
| Request Index | HTTP Status | Response Payload | Result |
|---|---|---|---|
| Request 1 | 201 Created | {"success": true, "message": "Booking confirmed successfully"} |
Seat Reserved |
| Request 2 | 409 Conflict | {"status": 409, "message": "This seat was just selected or booked..."} |
Rejected |
| Request 3 | 409 Conflict | {"status": 409, "message": "This seat was just selected or booked..."} |
Rejected |
| Request 4 | 409 Conflict | {"status": 409, "message": "This seat was just selected or booked..."} |
Rejected |
| Request 5 | 409 Conflict | {"status": 409, "message": "This seat was just selected or booked..."} |
Rejected |
| Request 6 | 409 Conflict | {"status": 409, "message": "This seat was just selected or booked..."} |
Rejected |
| Request 7 | 409 Conflict | {"status": 409, "message": "This seat was just selected or booked..."} |
Rejected |
| Request 8 | 409 Conflict | {"status": 409, "message": "This seat was just selected or booked..."} |
Rejected |
| Request 9 | 409 Conflict | {"status": 409, "message": "This seat was just selected or booked..."} |
Rejected |
| Request 10 | 409 Conflict | {"status": 409, "message": "This seat was just selected or booked..."} |
Rejected |
- Language & Runtime: Java 25 (Temurin OpenJDK)
- Framework: Spring Boot 4.0.x
- Spring Web (RESTful API architecture)
- Spring Data JPA / Hibernate 7.2 (ORM and persistence)
- Spring Security 7.0 (Stateless authentication filter chain)
- Jakarta Bean Validation (Declarative input validation)
- Database: PostgreSQL 16 (ACID-compliant relational engine)
- Connection Pool: HikariCP
- Security & Tokens: JJWT (Java JSON Web Token) 0.12.6 (HS256 signature scheme) + BCrypt password hashing
- API Documentation: springdoc-openapi 2.8.5 (Swagger UI 3.0 specification)
- Containerization: Docker & Docker Compose v2
- Framework & Tooling: React 19, Vite 6
- Routing: React Router 6 (Role-protected route guards)
- HTTP Client: Axios (Configured request/response interceptors for Bearer auth)
- Styling & Design System: Custom Vanilla CSS Design System with theme tokens (Light / Dark mode toggle)
- Hosting: Vercel (Edge CDN deployment with SPA client rewrite rules)
quicktix/
├── client/ # Frontend Single Page Application (React + Vite)
│ ├── src/ # Components, pages, context providers, API client
│ ├── vercel.json # Vercel SPA routing rewrites
│ └── package.json # Node.js dependencies
├── server/ # Backend REST API Service (Spring Boot 4)
│ ├── src/main/java/ # Controllers, services, JPA repositories, entities, security
│ ├── src/main/resources/ # Profiles (application.yml, application-dev, application-prod)
│ ├── Dockerfile # Multi-stage optimized production build
│ └── pom.xml # Maven build configuration (Java 25)
├── docker-compose.yml # Full-stack container orchestration
├── .env.example # Environment variable specification template
└── README.md # Project documentation
The entire backend and database stack can be spun up with a single command using Docker Compose.
- Docker Desktop (v24.0 or newer)
- Node.js (v18.0 or newer, for running client locally)
git clone https://github.com/asyncsourav/quicktix.git
cd quicktix
# Copy environment variables
cp .env.example .envdocker compose up -d --buildDocker Compose will:
- Boot PostgreSQL 16 with a persistent named volume (
postgres_data). - Run healthchecks via
pg_isreadyuntil the database is ready to accept connections. - Build the backend using a multi-stage Docker build with Java 25.
- Launch the Spring Boot application on port
8080. - Seed demo accounts, venues, events, and seat maps automatically on first run.
Verify that both containers are running and healthy:
docker compose pscd client
npm install
npm run devThe client application will start at http://localhost:5173 (or http://localhost:3000).
QuickTix features full interactive OpenAPI 3.0 documentation via Swagger UI.
- Swagger UI: http://localhost:8080/swagger-ui.html
- OpenAPI Specification JSON: http://localhost:8080/v3/api-docs
| Domain | Method | Endpoint | Authorization | Description |
|---|---|---|---|---|
| Auth | POST |
/api/auth/register |
Public | Register new account with BCrypt password hashing |
POST |
/api/auth/login |
Public | Authenticate credentials and receive signed JWT | |
| Events | GET |
/api/events |
Public | Query events with category and keyword search filters |
GET |
/api/events/{id} |
Public | Retrieve detailed event metadata | |
GET |
/api/events/{id}/seats |
Public | Fetch current seat layout and availability status | |
POST |
/api/events |
Organizer / Admin | Publish event and auto-generate seat layout | |
PUT |
/api/events/{id} |
Organizer / Admin | Update event details (organizer ownership enforced) | |
DELETE |
/api/events/{id} |
Organizer / Admin | Delete event (organizer ownership enforced) | |
| Venues | GET |
/api/venues |
Public | List all registered venues |
GET |
/api/venues/{id} |
Public | Retrieve venue specifications and capacity | |
GET |
/api/venues/organizer/{id} |
Public | List venues managed by an organizer | |
POST |
/api/venues |
Organizer / Admin | Register new venue | |
PUT |
/api/venues/{id} |
Organizer / Admin | Update venue details (ownership enforced) | |
DELETE |
/api/venues/{id} |
Organizer / Admin | Remove venue (ownership enforced) | |
| Bookings | POST |
/api/bookings |
Authenticated | Atomic multi-seat reservation with optimistic locking |
GET |
/api/bookings/me |
Authenticated | Retrieve authenticated user booking history | |
GET |
/api/bookings/{id} |
Authenticated | Retrieve booking receipt (ownership verified) | |
DELETE |
/api/bookings/{id} |
Authenticated | Cancel booking and release seats back to inventory | |
| Admin | GET |
/api/admin/users |
Admin | Administrative user directory audit |
GET |
/api/admin/stats |
Admin | Real-time aggregate revenue and utilization metrics | |
GET |
/api/admin/bookings |
Admin | Platform-wide transaction ledger audit | |
| Health | GET |
/api/ping |
Public | Service liveness probe |
The backend employs an optimized multi-stage Dockerfile:
# Stage 1: Build stage with compiler and dependencies
FROM maven:3.9-eclipse-temurin-25-alpine AS build
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn clean package -DskipTests
# Stage 2: Runtime stage with minimal Alpine JRE
FROM eclipse-temurin:25-jre-alpine
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]- Single-Stage Build (Legacy baseline): 870 MB
- Multi-Stage Build (Production): 434 MB
- Image Size Reduction: 50.11% (436 MB eliminated from production container)
- Content Layer Size Reduction: 55.81% (from 310 MB to 137 MB)
When launched against an uninitialized database, DataInitializer seeds test accounts with password password123:
| Role | Password | Permissions | |
|---|---|---|---|
| Admin | admin@quicktix.com |
password123 |
System oversight, aggregate metrics, platform audit |
| Organizer | organizer@quicktix.com |
password123 |
Venue management, event creation, seat generation |
| Attendee (User) | user@quicktix.com |
password123 |
Event browsing, seat reservation, booking management |
- Phase 1: Core Domain Model, JPA Repositories, REST API Endpoints
- Phase 2: Role-Based Access Control (RBAC), Stateless JWT Security, Password Hashing
- Phase 3: Optimistic Locking Concurrency Control (
@Version), Race Condition Verification - Phase 4: OpenAPI 3.0 / Swagger UI Interactive Documentation (
springdoc-openapi) - Phase 5: Multi-Stage Docker Containerization, Full-Stack Docker Compose Orchestration
- Phase 6: Dual rotating JWT refresh tokens with token family reuse detection
- Phase 7: Distributed caching with Redis for hot read paths (event listings, seat maps)
- Phase 8: Distributed API rate limiting via Bucket4j and token bucket algorithms
- Phase 9: Real-time seat reservation broadcasts over WebSocket / STOMP protocol
- Phase 10: Automated test coverage (JUnit 5, Mockito, Testcontainers for PostgreSQL)
- Phase 11: Continuous Integration pipeline via GitHub Actions
- Phase 12: High-load performance testing via k6
Sourav Kumar
- GitHub: https://github.com/asyncsourav
- LinkedIn: https://www.linkedin.com/in/asyncsourav
- LeetCode: https://leetcode.com/u/asyncsourav
- Email: xsouravkumar357@gmail.com