SMS, from the seeded template. The channel allows 20 per minute, so a burst of 25 overflows the bucket — the excess waits in rate limited until it refills.
Rate limiter
redis token bucketwaiting for metrics…
A worker that cannot take a token puts the job back with a 10s delay instead of blocking.
Transitions
diffed each pollSend something — every state change shows up here.
POST /notifications
accepted in last 60s
validate → idempotency key → insert
notifications table
- scheduled
- 0
- pending
- 0
- delivered
- 0
- failed
- 0
advisory lock · promotes due jobs
nothing scheduled
depth 0 · visible 0
queue empty
polling for visible jobs
no jobs claimed
provider handlers
no sends in the last minute
fail 0% / 1m
terminal · providerMessageId stored
nothing delivered yet
invisible until the timeout expires → back to queue
no jobs waiting on backoff
permanent 4xx, or maxAttempts exhausted
no dead letters