DUSKELStart a project
7 min read

n8n automations that don't break at 2am

AI workflow automation is easy to build and easy to leave fragile. Here's how to make an n8n workflow retry, recover, and page you before it fails silently.

n8n makes it deceptively easy to wire up an automation. Drag a trigger, chain some HTTP nodes, connect an AI step, done. It runs, you move on. Then at 2am an upstream API returns a 503, your workflow throws, and nothing catches it. By morning you've silently dropped four hours of orders and nobody knew until a customer complained.

The gap between a workflow that runs and a workflow you can rely on is entirely about failure handling — the stuff that's invisible when everything works. Good AI workflow automation assumes every external call will eventually fail and is built to survive it. Here's what that looks like in n8n.

Retries with backoff, not just retries

Most transient failures — a rate limit, a brief timeout, a flaky third-party API — resolve themselves in seconds. n8n lets you enable retries on a node, and you should, but the default of hammering the same endpoint three times in a row is often the wrong move. If you got rate-limited, three immediate retries just get rate-limited three more times.

Space the attempts out with backoff: wait a second, then a few, then more, so a struggling upstream gets room to recover. For AI and LLM nodes this matters double, because provider rate limits and occasional 529-style overload responses are routine, not exceptional. Set retries where the failure is genuinely transient, and — this is the part people miss — make sure the operation is safe to repeat. Retrying a 'charge the card' step that actually succeeded but timed out on the response will double-charge someone. Use an idempotency key so a retry can't duplicate a side effect.

Catch failures with an error workflow

When a node fails past its retries, by default the execution just stops and turns red in the history — which nobody is watching at 2am. n8n has a proper mechanism for this: set an error workflow, a separate flow that fires automatically whenever any workflow errors out, receiving the details of what broke and where. Configure it once and every workflow inherits a safety net.

Use the per-node 'continue on fail' setting deliberately, not everywhere. For a step where one bad item shouldn't sink the whole batch, let it continue and route the failed item aside. For a step where proceeding on failure would corrupt state — a payment, a database write the rest of the flow depends on — let it stop hard. The skill is deciding, per node, whether failing loudly or continuing is the safer wrong answer.

Dead-letter the items you can't process

Retries handle the transient. But some failures are permanent for that specific item — malformed data, a record that violates a constraint, an input the AI step can't parse. Retrying those forever is wasted work, and dropping them is data loss. Borrow the dead-letter pattern from message queues: when an item fails past its retry budget, don't discard it — write it somewhere durable with the error and the original payload. A database table, a dedicated queue, even a spreadsheet for low volume.

Now a poison item can't block the rest of the batch and can't vanish. Someone reviews the dead-letter store, fixes the root cause, and replays the items. Without this, one bad record either halts everything or disappears without a trace, and you find out which only when the numbers don't reconcile.

Alert like you'll be asleep

A workflow that fails and tells no one is the same as a workflow that fails and lies to you. Your error workflow should do more than log — it should reach a human through a channel someone actually watches: a Slack channel, an email, a page to whoever's on call. Include what failed, which workflow and node, the error message, and enough of the payload to start debugging without digging through execution history.

Alert on silence too, not only on errors. A scheduled job that simply never fires — the trigger broke, the instance was down — throws no error, so error-only alerting never catches it. A dead man's switch, where a separate check expects a heartbeat every interval and alerts when it's missing, catches the failures that don't announce themselves. The scariest outages are the quiet ones.

When to reach for a custom node

n8n's built-in nodes and the code node cover most of what you need, and you should stay there as long as you can — it's visible, versionable in the workflow, and anyone on the team can read it. Reach for a custom node when you're copy-pasting the same code-node logic across many workflows, when you need real error typing and testability the visual editor can't give you, or when you're integrating a system with auth or pagination too gnarly to keep re-solving inline.

The tradeoff is real: a custom node is proper software with its own deploy and maintenance cost, and it hides logic from the visual view where the rest of the team looks first. Build one when the reliability or reuse payoff clearly beats that cost — not because writing a node feels more like real engineering than dragging boxes. At 2am, the boring, well-instrumented workflow wins.

Want automations that hold up when you're not watching? Let's build them.