How not to dial a thousand people by accident
May 2026
OnTune makes and takes real phone calls: AI voice agents that run outbound campaigns and answer inbound ones, first for hotels. The voice pipeline is the part people look at, speech in, a model, speech out, bridged onto the phone network. The infrastructure under it is the part I am proud of.
Outbound calling is a fan-out problem, and serverless is dangerously good at fan-out. The obvious design reads a campaign of five thousand numbers and dispatches five thousand calls. You have now spent your entire telephony budget in a minute, tripped every carrier concurrency limit, and quite possibly broken the law.
So the dispatcher is throttled on purpose, and the throttle lives in Redis. A scheduled event fires every few minutes, a function walks each tenant's live campaigns, and a call is only dispatched if that tenant's in-progress counter has headroom under its concurrency limit. Starting a call increments the counter.
The half that makes it safe is what closes the loop. When a call ends, the completion handler decrements that tenant's counter and puts the tenant back in the queue. A new call can only go out because an old one came back. The system paces itself instead of sprinting off a cliff and finding out about it on the invoice.
Around that: dead-letter queues with retry counts tuned per queue, and a real state machine for call status rather than a boolean. The unglamorous hardening that decides whether a bad night degrades or detonates.
The lesson I keep relearning is that serverless removes the friction that used to protect you. The easiest thing to build is the one that dials everyone at once. The brakes are something you add back deliberately, because nothing in the platform will add them for you.