Idempotency key
An idempotency key is a caller-supplied or system-derived identifier that lets a receiver recognise a repeated request as the same request. An operation is idempotent when performing it twice has the same effect as performing it once — which is not naturally true of sending a text message.
| Cause | What happens | The control |
|---|---|---|
| Client retry after timeout | The request succeeded but the response was lost, so the caller sends it again | Idempotency key on the request; the second call returns the first result |
| Load balancer or proxy retry | An idle-timeout retry re-issues the request without the application knowing | Same, and it must be enforced server-side — the client never learns a retry occurred |
| Queue redelivery | A worker crashes after sending but before acknowledging; the message is redelivered | Per-row idempotency at the delivery layer, not just at the API boundary |
| Operator double-click | A slow send button is pressed twice | A key derived at composition time, so both submissions carry the same one |
| Failed-batch replay | A batch partially succeeded and is replayed wholesale to catch the failures | Per-recipient scope, so replay only sends the recipients that did not succeed |
Where the scope must sit, and why per-batch is wrong
The design decision that determines whether a district's parents receive duplicates is the granularity of the key.
Consider a broadcast to 4,000 guardians. The worker sends 3,600 successfully and then the process dies. On restart, the batch is retried. If the idempotency key is scoped to the batch, the retry sees a partially-completed batch and has two bad options: treat the batch as done, leaving 400 families unnotified, or replay it, sending 3,600 duplicates. Neither is acceptable for an attendance notice and both are catastrophic for an emergency alert.
Scoping the key to the individual delivery row resolves it. Kastr uses a unique key of ${broadcastId}:${personId}:${channel}, so each recipient-and-channel combination can succeed exactly once within a broadcast. A replay attempts all 4,000, the 3,600 already recorded are rejected by the uniqueness constraint, and the remaining 400 go out. The constraint is in the database rather than in application logic, which matters because application-level checks race under concurrency: two workers can both check, both find nothing, and both insert.
Delivery semantics, and what a district should require
| Semantic | Means | Emergency alert consequence |
|---|---|---|
| At-most-once | Never duplicated, may be lost | Unacceptable. A lockdown notice that silently fails is the worst outcome in the category |
| At-least-once | Never lost, may be duplicated | Acceptable but noisy: families receive the same alert twice and start ignoring alerts |
| Effectively-once | At-least-once delivery plus deduplication at the receiving side of each hop | What you should require. Not the same as "exactly-once", which distributed systems cannot actually offer |
"Exactly-once delivery" is a marketing phrase. Between two systems connected by an unreliable network there is always a moment where the sender does not know whether the receiver acted, and no protocol removes it. What is achievable is at-least-once delivery combined with idempotent handling, so the duplicates that inevitably occur are absorbed rather than transmitted. That combination is what "effectively-once" describes, and it is the honest thing to ask a vendor for.
Why it matters to a district
Duplicate alerts are not a cosmetic problem. Families that receive the same message two or three times learn that the district's messages are unreliable, and the cost of that lesson is paid on the day a message genuinely matters. Districts that have had a robocall loop — the same automated call placed six times overnight because a retry path had no deduplication — know that the resulting complaint volume dwarfs whatever the original notice was about.
The related failure, and the more dangerous one, is the opposite: a system tuned to avoid duplicates by treating uncertainty as success, so a batch that half-failed is recorded as delivered. Ask a vendor which way their system errs when it cannot tell, and what the record shows afterwards.
How Kastr's dispatch path handles it
Workers claim delivery rows with SELECT … FOR UPDATE SKIP LOCKED and a five-minute claim TTL, so a crashed worker's rows return to the pool rather than being stranded or re-sent. Network I/O to the carrier happens outside the database transaction, so a slow provider does not hold a transaction open. The row-level uniqueness key makes retries safe.
Where a single logical notification legitimately produces two deliveries — an SMS that fails terminally and triggers a voice call — the second is recorded as its own attempt with a failover_from reference to the first, so it is visible as a substitution rather than looking like a duplicate in the record.
Questions people actually ask
Why do parents sometimes receive the same alert twice?
Almost always a retry without deduplication: a timed-out request re-sent by a client or proxy, a queue message redelivered after a worker crashed between sending and acknowledging, or a partially-failed batch replayed wholesale. The fix is a uniqueness constraint at the individual recipient-and-channel level, enforced in the database rather than checked in application code.
What is the difference between at-least-once and exactly-once delivery?
At-least-once guarantees nothing is lost but permits duplicates. Exactly-once is not achievable across an unreliable network — there is always a window where the sender cannot know whether the receiver acted. What real systems provide is at-least-once delivery plus idempotent handling, sometimes called effectively-once, which absorbs the duplicates rather than eliminating the retries.
Should an emergency alert be retried aggressively?
Yes, provided handling is idempotent. Without deduplication, aggressive retry produces the robocall loop that generates more complaints than the incident. With per-recipient idempotency, retry costs nothing but latency, so the safe configuration is retry hard and deduplicate at the delivery row.
Where should an idempotency key be scoped?
At the smallest unit of work that has an external side effect — for messaging, the individual recipient and channel within a broadcast. Batch-level keys force a choice between abandoning the unsent remainder and re-sending everything, which is exactly the failure that produces duplicate emergency alerts.
One price. Every feature. Locked for three years.
$3.50 per student per year under 5,000 students. No tiers, no add-on modules, no per-message fees. Published on the site because you should not have to book a call to learn a price.