Retry and DLQ policy (pricing)
BullMQ
- Main and measure queues use exponential backoff (see
src/lib/pricing/queue-client.ts). - Max attempts: 5 by default (
PRICING_DEFAULT_MAX_ATTEMPTSinretry-policy.ts). - After the final failure, jobs are forwarded to persisted Postgres
dead_letter_jobsand optionally the BullMQ DLQ queue.
Idempotency
- Operator actions (
POST /api/operator/actions) acceptIdempotency-Key(oridempotency-key). The same key + actor + payload hash returns the stored prior response without re-executing the mutation (idempotency_recordstable, migration008). - DLQ replay uses deterministic BullMQ
jobIdpatterns where possible to avoid duplicate side effects when operators double-click.
Classification
retry-policy.tslists message markers treated as likely non-retryable for tuning and observability (not automatically wired to BullMQattemptsper job type — BullMQ still retries until max attempts unless job options change).
Operations
- Monitor DLQ growth via
/api/health/deepand control plane; setLEAD_OS_DLQ_ALERT_THRESHOLDto surfacealertsin deep health when persisted DLQ rows exceed the threshold.