When the Langkawi International Half Marathon (LIHM) 2025 team called me, the mission was simple on paper but spicy in reality:
“Zabel, we need a treasure hunt + lucky draw system. It must survive thousands of runners hammering the site at once. And on event day… it cannot die.”
Alright. No pressure.
So this article is a breakdown of how I built a production-grade high-concurrency event system — the kind that stays cool even when 8,000 sweaty runners decide to submit their entries simultaneously.
If you’re into Laravel, real-world architecture, or just want to see how much stress a human developer can endure in one event cycle… jom.
🏁 The Challenge: Make It Fun, Fast, and Unbreakable
The LIHM committee wanted:
-
A Treasure Hunt Quiz that checks accuracy and auto-qualifies winners
-
A Lucky Draw System with two pools:
-
One for treasure hunt passers
-
One for general participants
-
-
A Live Big Screen Draw Experience (because drama sells)
-
An admin panel for staff
-
And most importantly: zero crashes & zero double entries
High traffic, high stakes, one-shot deployment.
This is basically “Don’t embarrass yourself in front of 8,000 people” mode.
⚙️ Tech Stack I Chose (Because I Enjoy Sleeping at Night)
Everything is optimized for one goal: take the hits and keep serving pages fast.
🧩 Architecture: Clean, Layered, and Drama-Free
The system isn’t just “Laravel + database”. It’s designed to survive a traffic stampede.
User → Load Balancer → Laravel App
↙︎ ↘︎
Redis MySQL
Every request goes through:
-
reCAPTCHA v3 (to swat bots)
-
Validation
-
Service layer
-
Atomic database writes
-
Caching checks
The result: no duplicates, no race conditions, no bib number chaos.
🧠 Core Features That Made This System Rock-Solid
1. Treasure Hunt Quiz Engine
Participants answer curated Langkawi-themed questions.
To qualify, they must pass the threshold defined in admin settings.
The system:
-
Randomizes answer options
-
Scores on the fly
-
Logs every answer
-
Auto-enrolls eligible runners into the treasure hunt lucky draw
Atomic DB transactions ensure everything is stored correctly — even under load.
2. General Lucky Draw Registration
Purely for fun — no quiz required.
Key rule: One bib = one slot.
Whether 10 or 1,000 people submit the same bib at the same millisecond, only one record is stored.
That’s the magic of:
firstOrCreate()
Combined with exception handling if MySQL throws a duplicate key error.
🚀 The Real Challenge: Handling 8,000+ Users at Once
This isn’t a normal website.
During an event, everyone registers at the same time.
Here’s how I stopped things from exploding:
✔ Atomic Database Operations
Guarantee that duplicate entries simply… can’t happen.
✔ Exception Catching for Extreme Edge Cases
If someone somehow slips through, the fallback ensures consistent data.
✔ Redis for Sessions + Cache
Removes session load from MySQL, reducing traffic bottlenecks.
✔ Cached Branding & Settings
Cut down to near-zero DB reads during peak loads.
✔ Graceful reCAPTCHA Timeouts
If Google sneezes, the event doesn’t die.
This combination made the entire system bulletproof and stress-proof.
🎉 The Live Draw Experience (The Crowd Favourite)
The organisers wanted big screen, big hype, big energy.
So I built:
-
A 4-second shuffle animation
-
Confetti bursts
-
Real-time updating winner list
-
PIN-protected controls
-
Keyboard shortcuts for smooth operation on stage
When that shuffle stops and the winner pops up — the whole hall reacts.
Worth every line of JavaScript.
🛠️ Admin Dashboard That Actually Helps (Not Another Boring Panel)
Staff could:
-
Manage questions
-
Monitor pass rate
-
Track total submissions
-
See winners instantly
-
Manage general and treasure hunt entries separately
All designed to be usable even by non-tech event crew.
🧨 Deployment: What Kept the System Alive on Event Day
My production checklist included:
-
Pre-building assets
-
Migration batching
-
Storage & cache permission fixes
-
PHP-FPM tuning
-
MySQL threadpool adjustments
-
Redis swapfile protections
The result?
Zero downtime.
Zero double entries.
Zero complaints.
Plenty of happy runners.
📚 What I Learned (Or… The Things That Nearly Caused Grey Hair)
-
Concurrency isn’t something you slap on at the end
-
Caches are your best friend
-
reCAPTCHA timeouts happen — plan for it
-
Load testing saves reputations
-
Always, ALWAYS have a rollback plan
This project is a perfect example of how a well-architected Laravel system can handle real-world, high-pressure loads.
🎤 Final Thoughts
LIHM 2025 pushed me to build a system that’s not only fast… but event-proof.
-
It handled thousands of simultaneous submissions
-
It prevented duplicates flawlessly
-
It delivered dramatic draw moments live on stage
-
It stayed stable the whole day
And honestly?
Seeing the system survive full blast in the middle of an international marathon — absolutely worth it.
If you’re building anything for large crowds, festivals, or high-traffic moments, the principles behind this project will save your life (and your server bill).
For Event Organisers & Big Crowds
Running an event?
Need a registration system, quiz engine, lucky draw platform, or something custom?
I build platforms designed for crowds, pressure, and zero-second downtime.
Your event deserves tools that work as hard as your team.