FlagshipCommunication infrastructure
High-Volume Campaign Platform
Laravel · Redis · MySQL · ClickHouse · Elasticsearch · AWS · Docker
Evolving a mature, multi-tenant Laravel campaign platform into an asynchronous, observable sending system engineered for billion-scale workloads, without stopping the product.
The system was already mature. The goal wasn’t to rewrite it. The goal was to isolate bottlenecks, introduce better execution paths, and evolve the architecture without breaking existing functionality.
- 01
Recipients
Segments resolved per tenant
- 02
Streaming
Cursor-based, never loaded whole
- 03
Queue orchestration
Chunk, order, pace
- 04
Redis
Queues · dedup · throttles · cooldowns
- 05
Batch processing
Workers pull bounded batches
- 06
Send infrastructure
Providers, failover, webhooks deferred
- 07
Analytics
Events, not row updates
- 08
ClickHouse
Per-campaign send data, columnar
Key decisions
Five architectural choices carried the redesign. Three of them are here; the case study explains all of them, what each cost, and what they changed.
Decision 01
Stream recipients instead of loading them
Memory ceilings were the first wall. Cursor-based streaming made the audience size irrelevant to worker footprint and let batching become a tuning parameter instead of a limit.
Decision 02
Put coordination state in Redis, not MySQL
Deduplication, throttling and cooldowns are high-frequency, short-lived and latency-sensitive. Redis is the right home for that; a relational table under row locks is not.
Decision 03
Defer webhook processing
Providers deliver events in bursts that had nothing to do with our capacity. Accept, enqueue, process. The database stopped being hammered by someone else’s traffic pattern.