Building Infrastructure for a National-Level CTF: Technical Lessons from RCS CTF 2026
The Challenge: Infrastructure for 100+ Hackers at Once
January 30–31, 2026. The National-Level Capture the Flag competition at Lovely Professional University was about to start. Over 100 cybersecurity students from across India were about to connect to our platform simultaneously.
And I was one of the infrastructure engineers responsible for keeping it running.
Here's the problem: CTF platforms are brutally hard to host.
Why?
100+ concurrent users
↓
Real-time flag submissions
↓
Challenge-specific servers running exploitable code
↓
Network isolation requirements
↓
Scoring system needing instant updates
↓
Complete infrastructure failure = event cancelled
We had zero room for error.
This post covers the technical decisions we made, the disasters we prevented, and the lessons that apply to any high-stakes distributed system.
Understanding CTF Infrastructure (What Most People Don't Know)
Before diving into our setup, let me explain why CTF infrastructure is uniquely challenging.
What is a CTF Platform?
A CTF (Capture the Flag) competition is like a video game for hackers:
Challenges are hosted on isolated servers
Each challenge has a "flag" (a secret code)
Participants exploit vulnerabilities to extract the flag
Flag submission updates their score in real-time
Scoring leaderboard is live and competitive
Why Is This Hard?
Challenge Isolation:
Challenge A might have a vulnerable PHP app
Challenge B might have an exploitable Linux kernel
If Challenge A's vulnerability leaks to Challenge B's server, the entire competition is compromised
Real-Time Constraints:
Flag submission must update scores instantly
Leaderboard must reflect top 10 in less than 1 second
If the scoring system lags, participants get frustrated and competition integrity collapses
Scalability at Unknown Load:
We didn't know how many teams would connect
We didn't know how many attacks would happen simultaneously
Both could spike unpredictably
Security Under Attack:
Participants are literally trying to break the system
A skilled hacker might try to hijack another team's session, modify the database, or crash servers
We had to defend against this while the competition is live
Our Architecture: Designing for Chaos
Here's the infrastructure stack we built:
Internet
↓
Load Balancer (Cloudflare)
↓
API Gateway (Node.js + Express)
↓
Challenge Servers (Docker containers, isolated)
Scoring Service (Redis + MongoDB)
Leaderboard Service (Cached, updated every 5 seconds)
Authentication Service (JWT + Sessions)
↓
Database (MongoDB, replicated)
Let me break down each layer.
Layer 1: Load Balancing (Cloudflare)
Problem: 100 teams, each with 3–5 members, all hitting the platform simultaneously. A single server dies. What happens?
Solution: Cloudflare sits in front of everything.
User connects → Cloudflare (rate limiting, DDoS protection)
→ Distributed to multiple API servers
→ Requests balanced by health checks
What we configured:
Rate limiting: 100 requests per minute per IP
DDoS protection: Auto-block suspicious IPs
Geographic routing: Users routed to nearest server
SSL/TLS: All traffic encrypted
Why it matters: If one API server crashes, Cloudflare routes traffic to healthy servers. The competition keeps running.
Layer 2: API Gateway (Node.js + Express)
The brain of the platform. Every user action flows through here.
Critical decisions:
Atomic transactions — Either all score updates happen or none
Cache invalidation — Every flag submission refreshes leaderboard data
Rate limiting per team — Prevent brute-forcing flags
Layer 3: Challenge Servers (Dockerized, Isolated)
Each challenge runs in its own Docker container on isolated networks.
Why Docker?
Isolation — One compromised challenge cannot affect others
Easy reset — Restart compromised containers instantly
Resource limits — Prevent resource exhaustion attacks
Networking — Containers don’t talk to each other
Real scenario: A competitor tried escaping a container. The exploit worked inside the container but couldn’t escape.
That’s exactly what we wanted.
Layer 4: Scoring Service (Redis + MongoDB)
Real-time score updates go to MongoDB (persistent) and Redis (fast cache).
Why two databases?
MongoDB is the source of truth
Redis is the speed layer
Leaderboard:
Without cache: 1–2 seconds
With cache: less than 10ms
Cache refresh every 5 seconds ensures speed with acceptable staleness.
Real-Time Monitoring: Staying Awake for 48 Hours
The competition ran continuously for 2 days.
We monitored:
API Response Time
Target: less than 500ms
Alert: more than 1000ms
Error Rates
Target: less than 0.1%
Alert: more than 1%
Database Replication Lag
Target: less than 100ms
Alert: more than 500ms
Challenge Server Health
Container running
Accessible
Responding
Within resource limits
If anything failed, we got alerts instantly.
Disaster Scenarios (And How We Handled Them)
Database Corruption
Bug corrupted MongoDB
Fix: Replay last 5 minutes from logs
Lesson: Always design rollback systems
Challenge Server Compromise
SQL injection attempt
Fix: Container isolation blocked it
Lesson: Isolation is critical
DDoS Attack
1000 flag submissions per second
Fix: Rate limiter + Cloudflare block
Lesson: Rate limiting is mandatory
Memory Leak
Node.js process slowed over time
Fix: Restart at 80% memory usage
Lesson: Monitor memory continuously
Lessons for Any High-Stakes System
Isolate everything
Cache aggressively, invalidate carefully
Monitor everything
Rate limit everything
Plan for failures
Keep the team ready
The Results
100+ teams participated
2 days continuous runtime
0 major outages
Less than 5 seconds leaderboard update
99.95% uptime
The system worked flawlessly.
What’s Next
If you’re building a similar system:
Start with Docker
Add monitoring early
Design for failure
Rate limit aggressively
Cache smartly
Infrastructure isn’t boring. It’s the backbone of every successful system.
About This Experience
As Infrastructure Lead for RCS CTF 2026, I learned that DevOps is about anticipating failures and building systems that survive them.
Connect
GitHub: @anubhavxdev
LinkedIn: @anubhavxdev
Portfolio: anubhavjaiswal.me
Email: anubhavjaiswal1803@gmail.com
Top comments (0)