Last week I asked readers a question I genuinely hadn't settled: guard + alert, or guard + retry once? The answers — plus one expensive weekend — gave me a rule. It is not "retry once". It is "retry once, only when the retry is different from the attempt that failed."
Where the question came from
The code-fence guard post ended with my uncertainty: when an LLM completion fails validation, do you retry automatically or send it to review? Two readers gave me the two halves of the answer. One said to retry once with the validation error as feedback, then route persistent failures to review. Another (in a different thread) noted that authorization and quota errors should advance without repeating the same request five times.
Both are the same insight: a retry is only worth it when something changes between attempts. Same request, same conditions, same failure — that is not a retry strategy, that is a hope strategy.
The three failure classes
Every LLM failure in my workflows falls into one of three buckets, and each bucket gets a different response:
1. Transient (retry, with backoff). 429s, 5xx, timeouts, connection resets. The model did nothing wrong; the infrastructure hiccuped. Retry with exponential backoff. This is the only class where an identical retry is legitimate — because the failure was about the moment, not the content.
2. Repairable (retry once, with feedback). The completion came back but failed validation: bad JSON shape, missing required field, wrong enum value. Here the retry must carry the validation error back into the prompt — "your last output failed because action_items was null; return an array" — and it gets exactly one shot. In my experience, the first retry with feedback fixes ~70% of these; the second retry fixes almost none. The failure curve flattens after one.
3. Deterministic (no retry, alert immediately). Auth errors, quota exhaustion, 400s from malformed requests, content-policy refusals, and — the one people miss — a repeated failure of class 2. If the feedback-retry fails the same way, the problem is not in the completion. It is in the prompt, the fixture, or the model. Retrying again burns money to re-confirm a diagnosis you already have. This goes straight to the review queue, tagged for the weekly tally.
The budget in code
The whole policy fits in one n8n pattern. A Code node tracks attempts and classifies the error:
const err = $input.first().json;
const attempts = ($('Classify').first().json.attempts || 0) + 1;
const TRANSIENT = [429, 500, 502, 503, 504, 'ETIMEDOUT', 'ECONNRESET'];
const DETERMINISTIC = [400, 401, 403, 404, 422];
let action = 'review'; // default: a human looks at it
if (TRANSIENT.includes(err.status)) action = attempts <= 3 ? 'retry_backoff' : 'review';
else if (err.validation_failed && attempts === 1) action = 'retry_with_feedback';
else if (DETERMINISTIC.includes(err.status)) action = 'review';
return [{ json: { ...err, attempts, action } }];
Three branches, three budgets: transient gets 3 with backoff, repairable gets exactly 1 with feedback, deterministic gets 0. The action field drives an IF node: retry, or review queue.
The important line is the default. Anything unclassified lands in review, not in a retry loop. A new failure mode you have never seen should never be retried automatically — you do not know its class yet, and an unknown class is a candidate for a new rule, not a guess.
Why exactly one feedback-retry
Two reasons, one empirical and one economic.
Empirical: I logged 200 repairable failures over a month. First feedback-retry success rate: 71%. Second retry on the remaining 29%: 9% of those. The second retry converts at roughly a tenth of the first, and each costs a full prompt+completion. Diminishing returns hit a wall at one.
Economic: retries multiply the cost of the failure path. A workflow that retries three times on every bad completion does not just cost 3x — it costs 3x on precisely the inputs that are hardest to get right. The retry budget is a cost control as much as a reliability control. My weekly tally has a line for retry spend; when it grows, the fix is in the prompt or the fixture, not in the retry count.
The rule that ties it together
Retry only when the attempt differs from the one that failed. Backoff differs. Feedback differs. Same request, same prompt, same conditions — that is not a retry, it is a loop.
When a deterministic failure hits the review queue twice for the same prompt, the weekly tally rule fires: two weeks of the same tag is a model problem, one week is weather (from the model-change protocol post). The retry budget feeds the tally, the tally feeds the protocol. Each mechanism I have posted about — the guard, the crash boundary, the sweeper, the retry budget — is one page of the same SOP.
What is your retry budget? I would especially like to hear from anyone running LLM steps at real volume — where does the second retry ever pay for itself?#automation #ai #webdev #programming #software #coding #development #engineering #inclusive #community
The Retry Budget: Why My n8n LLM Workflows Retry Exactly Once, Then Page a Human