Retry budget for the events consumer
SH
consumer retries forever on a poisoned message. want a budget
08:10
Count attempts on the message, not on the consumer, or a restart resets everyone's budget:
workers/consumer.ts
const MAX_ATTEMPTS = 5
export async function handle(message: QueueMessage) { try { await process(message.body) await message.ack() } catch (error) { if (message.attempts >= MAX_ATTEMPTS) { await deadLetter.put(message, { reason: String(error) }) await message.ack() return } await message.retry({ delayMs: backoff(message.attempts) }) }}08:11
SH
and backoff
08:19
Exponential with jitter, capped. Without jitter the whole batch that failed together retries together, which is how one bad deploy turns into five identical spikes.
08:20
SH
ok. dead letter needs a replay path though
08:24
There is one already, in the Dead letter replay script thread. It reads from the same store this writes to, so nothing new is needed here beyond making sure reason is populated: replay filters on it.
08:25
ReUI Chat can make mistakes. Check important info.