Real-time Competitive Programming Platform Built for Scale
Supporting 20,000+ concurrent users with 1,500-2,000 RPS
Documentation β’ Architecture β’ Scaling Guide β’ Deployment β’ Testing
- Overview
- Key Features
- System Architecture
- Quick Start
- Scaling Strategy
- Project Structure
- API Documentation
- Deployment Options
- Monitoring & Observability
- Load Testing
- Documentation Links
- License
Nimaora CodeBattle is a high-performance, real-time competitive programming platform designed to simulate coding competitions at scale. Built for the Juniora programming challenge, it demonstrates enterprise-grade architecture capable of handling:
| Metric | Target | Implementation |
|---|---|---|
| Concurrent Users | 20,000+ | Horizontal scaling with Kubernetes HPA |
| Requests Per Second | 1,500-2,000 RPS | Laravel Octane with Swoole |
| WebSocket Connections | 20,000+ | Laravel Reverb with sticky sessions |
| Leaderboard Updates | Real-time | Redis Sorted Sets (O(log N)) |
| Attack Notifications | < 100ms | Priority queues + WebSocket |
Nimaora is an interactive programming competition where students:
- Join a battle with a unique username (session-based authentication)
- Receive 15 randomly assigned questions from a question bank
- Solve problems to earn points
- Choose Arrows (attack) or Shields (defense) as rewards
- Attack other participants to reduce their points
- Compete for the top position on the real-time leaderboard
- Session-based login with username uniqueness
- No duplicate sessions - prevents same username from multiple devices
- Automatic session expiry with heartbeat mechanism
- Graceful reconnection support
- Random assignment - 15 questions per participant from 30+ question bank
- Three difficulty levels - Easy (10-20 pts), Medium (25-35 pts), Hard (40-55 pts)
- Single attempt only - one chance per question
- Immediate feedback - real-time scoring
- Arrows - Attack other participants
- Shields - Defend against incoming attacks
- Smart targeting - Cannot attack users with 0 points
- Instant notifications - Real-time attack alerts via WebSocket
- Real-time updates - Debounced broadcasts
- Optimized queries - Redis Sorted Sets for O(log N) operations
- Online presence - Shows active participants
- Rank tracking - Get your position instantly
- WebSocket via Laravel Reverb
- Private channels for attack notifications
- Presence channels for participant tracking
- Automatic reconnection handling
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β USERS β
β (20,000+ Concurrent Connections) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ArvanCloud CDN + WAF β
β [Edge Cache] [DDoS Shield] [SSL Termination] [Geo Routing] β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Traefik Load Balancer β
β nimaora.dwin.codes β Frontend β
β api.nimaora.dwin.codes β Backend API β
β ws.nimaora.dwin.codes β WebSocket Server β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββ
βΌ βΌ βΌ
βββββββββββββββββββββββ βββββββββββββββββββββββ βββββββββββββββββββββββ
β Frontend β β Backend API β β WebSocket β
β (Next.js 15) β β (Laravel Octane) β β (Laravel Reverb) β
β 3-30 replicas β β 5-50 replicas β β 2-20 replicas β
β React 19 + RSC β β Swoole 10K conn β β Sticky Sessions β
βββββββββββββββββββββββ ββββββββββββ¬βββββββββββ βββββββββββββββββββββββ
β
βββββββββββββββββββββββββββΌββββββββββββββββββββββββββ
βΌ βΌ βΌ
βββββββββββββββββββββββ βββββββββββββββββββββββ βββββββββββββββββββββββ
β PostgreSQL 16 β β Redis 7 β β RabbitMQ β
β + PgBouncer Pool β β Sorted Sets β β Priority Queues β
β 1000 connections β β 4GB Memory β β 100K msg/sec β
β Query Indexing β β Master-Replica β β HA with Mirroring β
βββββββββββββββββββββββ βββββββββββββββββββββββ βββββββββββββββββββββββ
For detailed architecture documentation, see SYSTEM_ARCHITECTURE.md.
- Docker 24.0+ and Docker Compose v2.20+
- Node.js 22+ (for local development)
- PHP 8.3+ with Composer (for local development)
- 8GB RAM minimum (16GB recommended for full stack)
# Clone the repository
git clone https://git.dwin.codes/nimaora/nimaora.git
cd nimaora
# Copy environment configuration
cp .env.example .env
# Generate secure passwords (edit .env with your values)
openssl rand -base64 32 # Use for APP_KEY, DB_PASSWORD, etc.
# Start all services
docker compose up -d
# Wait for services to be healthy
docker compose ps
# Run database migrations and seed data
docker compose exec backend php artisan migrate --seed
# Access the application
open http://localhost:3000# Backend Setup
cd nimaora-backend
composer install
cp .env.example .env
php artisan key:generate
php artisan migrate --seed
php artisan serve --host=0.0.0.0 --port=8000
# WebSocket Server (new terminal)
php artisan reverb:start --host=0.0.0.0 --port=8080
# Frontend Setup (new terminal)
cd nimaora-frontend
npm install
cp .env.example .env.local
npm run dev| Service | URL | Credentials |
|---|---|---|
| Frontend | http://localhost:3000 | - |
| API | http://localhost:8000/api | - |
| WebSocket | ws://localhost:8080 | - |
| Grafana | http://localhost:3001 | admin/nimaora |
| RabbitMQ | http://localhost:15672 | nimaora/secret |
| pgAdmin | http://localhost:5050 | admin@nimaora.dwin.codes |
# Horizontal Pod Autoscaler Configuration
Backend HPA:
minReplicas: 10
maxReplicas: 100
metrics:
- cpu: 60% threshold
- memory: 70% threshold
- custom: http_requests_per_second > 150
scaleUp: 200% in 15 seconds (aggressive)
scaleDown: 10% in 60 seconds (conservative)| Component | Technology | Capacity |
|---|---|---|
| API Server | Laravel Octane + Swoole | 10,000+ conn/pod |
| Connection Pool | Persistent connections | Reduced overhead |
| Coroutines | Swoole async I/O | Non-blocking operations |
| Cache | In-memory state | Faster responses |
-- Leaderboard Query (Indexed for Performance)
SELECT username, points, shields, arrows
FROM battle_participants
WHERE battle_id = ?
ORDER BY points DESC
LIMIT 100;
-- Index: (battle_id, points DESC)PgBouncer Connection Pooling:
- Max 10,000 client connections
- Transaction-level pooling
- 100 default pool size
// Redis Sorted Set Operations
ZADD battle:{id}:leaderboard {score} {username} // O(log N)
ZREVRANGE battle:{id}:leaderboard 0 99 // O(log N + M)
ZREVRANK battle:{id}:leaderboard {username} // O(log N)Queue Priority (Highest to Lowest):
βββ attacks (Priority -5) β Real-time combat
βββ broadcast (Priority -3) β WebSocket events
βββ leaderboard (Priority 0) β Rankings update
βββ default (Priority 0) β General jobs
βββ notifications (Priority +5) β User alerts
For detailed scaling documentation, see docs/SCALING_ARCHITECTURE.md.
nimaora-codebattle/
βββ nimaora-backend/ # Laravel 12 Backend
β βββ app/
β β βββ Contracts/ # Repository interfaces
β β βββ DTOs/ # Data transfer objects
β β βββ Events/ # WebSocket events
β β β βββ AttackReceived.php
β β β βββ LeaderboardUpdated.php
β β β βββ ParticipantUpdated.php
β β βββ Http/Controllers/Api/ # API controllers
β β βββ Jobs/ # Queue jobs
β β β βββ ProcessAttack.php
β β β βββ BroadcastLeaderboardUpdate.php
β β βββ Models/ # Eloquent models
β β βββ Repositories/ # Data access layer
β β βββ Services/ # Business logic
β β βββ BattleService.php
β β βββ Cache/LeaderboardCache.php
β βββ database/
β βββ migrations/ # Database schema
β βββ seeders/ # Test data (2 battles, 30 questions)
β
βββ nimaora-frontend/ # Next.js 15 Frontend
β βββ src/
β βββ app/ # App Router pages
β β βββ battle/page.tsx # Main battle interface
β βββ components/ # React components
β β βββ battle/ # Battle-specific components
β βββ hooks/ # Custom hooks
β β βββ useRealtime.ts # WebSocket hooks
β βββ lib/ # Utilities
β β βββ echo.ts # Laravel Echo client
β βββ store/ # Zustand state management
β
βββ nimaora-infrastructure/ # DevOps & Infrastructure
β βββ ansible/ # Server configuration
β β βββ playbooks/
β β βββ roles/
β βββ docker/ # Docker configurations
β β βββ backend-unified.Dockerfile # Multi-mode backend image
β β βββ frontend.Dockerfile
β βββ kubernetes/ # K8s manifests
β β βββ base/ # Base configurations
β β βββ overlays/ # Environment overlays
β βββ terraform/ # Infrastructure as Code
β β βββ arvancloud/ # ArvanCloud deployment
β β βββ aws/ # AWS deployment
β βββ load-tests/ # k6 load testing
β βββ monitoring/ # Prometheus, Grafana, Loki
β
βββ docs/ # Documentation
β βββ SCALING_ARCHITECTURE.md # Scaling deep dive
β βββ DEPLOYMENT_GUIDE.md # Deployment instructions
β βββ API_DOCUMENTATION.md # API reference
β βββ DEVELOPMENT_SETUP.md # Developer guide
β βββ TESTING_GUIDE.md # Testing instructions
β
βββ docker-compose.yml # Local development stack
βββ DOCUMENTATION.md # Technical documentation
βββ SYSTEM_ARCHITECTURE.md # Architecture overview
βββ README.md # This file
| Method | Endpoint | Description | Rate Limit |
|---|---|---|---|
POST |
/api/battles/{id}/join |
Join a battle | 10/min |
POST |
/api/battles/{id}/leave |
Leave a battle | 10/min |
GET |
/api/battles/{id}/leaderboard |
Get leaderboard | 60/min |
GET |
/api/battles/{id}/questions |
Get assigned questions | 30/min |
POST |
/api/battles/{id}/questions/{qid}/submit |
Submit answer | 30/min |
POST |
/api/battles/{id}/reward |
Select arrow/shield | 30/min |
POST |
/api/battles/{id}/attack |
Attack participant | 20/min |
POST |
/api/battles/{id}/heartbeat |
Keep session alive | 60/min |
| Event | Channel | Direction | Description |
|---|---|---|---|
attack.received |
private-participant.{id} |
Server β Client | Attack notification |
leaderboard.updated |
battle.{id} |
Server β Client | Leaderboard change |
participant.updated |
battle.{id} |
Server β Client | Stats update |
For complete API documentation, see docs/API_DOCUMENTATION.md.
docker compose up -dkubectl apply -k nimaora-infrastructure/kubernetes/overlays/productioncd nimaora-infrastructure/terraform/arvancloud
terraform init && terraform apply
cd nimaora-infrastructure/ansible
ansible-playbook -i inventories/production/hosts.ini playbooks/site.ymlFor complete deployment instructions, see docs/DEPLOYMENT_GUIDE.md.
| Tool | Purpose | URL |
|---|---|---|
| Grafana | Metrics visualization | grafana.nimaora.dwin.codes |
| Prometheus | Metrics collection | prometheus.nimaora.dwin.codes |
| Loki | Log aggregation | Via Grafana |
| Laravel Pulse | Application monitoring | pulse.nimaora.dwin.codes |
| Laravel Horizon | Queue monitoring | horizon.nimaora.dwin.codes |
Performance Targets:
- HTTP P95 Latency: < 500ms
- HTTP P99 Latency: < 1000ms
- Error Rate: < 1%
- Leaderboard Update: < 200ms
- Attack Notification: < 100ms
- WebSocket Connections: 20,000+
- RPS: 1,500-2,000| Alert | Threshold | Severity |
|---|---|---|
| High Request Rate | > 2000 RPS | Warning |
| Backend Latency | P95 > 500ms | Critical |
| Queue Depth | > 10,000 messages | Warning |
| Database Connections | > 800 | Critical |
| Container OOM | Any event | Critical |
We use k6 for comprehensive load testing. See nimaora-infrastructure/load-tests/README.md for full documentation.
# Install k6
brew install k6 # macOS
# or
sudo apt-get install k6 # Ubuntu
# Run smoke test
cd nimaora-infrastructure/load-tests
k6 run -e TEST_PROFILE=smoke k6-load-test.js
# Run load test
k6 run -e TEST_PROFILE=load k6-load-test.js
# Run stress test (50K RPS target)
k6 run -e TEST_PROFILE=stress k6-load-test.js| Profile | VUs | Duration | Purpose |
|---|---|---|---|
smoke |
10 | 1 min | Quick validation |
load |
0β10,000 | 37 min | Normal load |
stress |
500β50,000 RPS | 45 min | Find limits |
spike |
1,000β50,000 | 8 min | Test autoscaling |
massive |
100,000 RPS | 60 min | Massive scale |
| Document | Description |
|---|---|
| Technical Documentation | Complete technical details |
| System Architecture | Architecture diagrams |
| Scaling Architecture | Deep dive into scaling |
| Deployment Guide | Full deployment instructions |
| API Documentation | API reference |
| Development Setup | Developer guide |
| Testing Guide | Testing instructions |
| Load Testing | k6 load testing guide |
| Backend Documentation | Backend specifics |
| Frontend Documentation | Frontend specifics |
- Framework: Laravel 12 (PHP 8.3)
- Server: Laravel Octane + Swoole
- Database: PostgreSQL 16
- Cache: Redis 7
- Queue: RabbitMQ 3.13
- WebSocket: Laravel Reverb
- Monitoring: Laravel Horizon, Pulse
- Framework: Next.js 15
- Runtime: React 19
- Language: TypeScript 5.6
- State: Zustand
- Styling: Tailwind CSS
- Real-time: Laravel Echo
- Containers: Docker
- Orchestration: Kubernetes
- IaC: Terraform, Ansible
- Load Balancer: Traefik
- Monitoring: Prometheus, Grafana, Loki
MIT License - See LICENSE file for details.
Built for Performance | Designed for Scale | Made for Competition
Made with love by dwin.codes - dwin.life - dwingh.me















