Sangathan Events.
A multi-tenant, QR-based event attendance platform for multi-state organizations — bulk QR/ID card generation, real-time scanning, CSV onboarding, OTP self-registration, and automated WhatsApp distribution.
The Problem
Large events (10,000+ attendees) needed printed QR ID cards. The original PHP implementation was synchronous and CPU-bound — one card every 2 seconds. A 10K-card event meant roughly 5.5 hours of blocking server time. Infeasible.
The Solution — Microservice Extraction
- Diagnosed the bottleneck: PHP's synchronous, single-threaded image processing — not the DB or I/O.
- Extracted card generation into a dedicated FastAPI microservice using Pillow.
- Offloaded work to 4 Celery workers processing in parallel from a Redis-backed queue, in batches of 50 with async job tracking.
- Result: 90% reduction in generation time (2s → 0.2s per card) — 10K-card events became a background job.
The Hard Part
Multilingual ID cards broke in production
Under a live event deadline, ID-card rendering failed for regional-language (Devanagari) text — Pillow's font rendering couldn't shape the glyphs. I debugged font loading, glyph shaping, and text encoding, and shipped the fix before the event started. A real production war story with no room to slip the date.
Key Features
- Multi-tenant architecture with state-level data isolation — concurrent events across multiple states.
- Role-based access: admin, manager, scanner — with permission-based scanning.
- Real-time QR validation with duplicate detection and event-expiry checks for fraud prevention during live entry.
- CSV bulk import supporting 20+ custom fields per event, with dynamic form generation from event templates.
- OTP-based self-registration flow.
- Automated WhatsApp QR-card delivery via the Aisensy API (batch-wise distribution).
- Production deployment and operations on DigitalOcean.
Trade-offs & What v2 Adds
Why sync for single cards, async for bulk?
Balances UX responsiveness for one-offs against system load for large batches.
Why a batch size of 50?
A tuned balance between per-worker memory usage and total processing time.
What v2 would add
Redis caching for event data, WebSockets for live attendance updates, and JWT replacing session auth.
Want the full walkthrough?
Happy to walk through the bottleneck diagnosis, the microservice design, and the production fix in detail.