External API Failures in n8n Without Blocking Other Workflows

I’m curious how experienced n8n users handle external APIs that become slow or temporarily unavailable.
For example:
Workflow

API Request

Timeout / 503

Retry

Still failing?

Recovery Workflow
My concern is that repeated retries could tie up workers and affect other workflows.
How do you decide when to retry versus fail immediately?
Do you use exponential backoff and concurrency limits?
How do you prevent one unreliable API from affecting the rest of your n8n instance?
Do you use a separate queue or recovery workflow for these cases?

Describe the problem/error/question

What is the error message (if any)?

Please share your workflow

(Select the nodes on your canvas and use the keyboard shortcuts CMD+C/CTRL+C and CMD+V/CTRL+V to copy and paste the workflow.)

Share the output returned by the last node

Information on your n8n setup

  • n8n version:
  • Database (default: SQLite):
  • n8n EXECUTIONS_PROCESS setting (default: own, main):
  • Running n8n via (Docker, npm, n8n cloud, desktop app):
  • Operating system:

Hi @Kabrooks A good approach is to treat external API failures as temporary until you know they aren’t, but avoid retrying forever.

API Request

Temporary Error?
↓ Yes
Wait + Backoff

Retry

Still Failing?

Recovery Workflow

I’d use exponential backoff for things like timeouts, 429, and 5xx errors, while permanent errors like invalid authentication or bad input should fail immediately.

It also helps to set a maximum retry count and concurrency limit so one unreliable API doesn’t consume all your workers.

For critical workflows, I’d send repeatedly failed requests to a recovery or dead-letter workflow so they can be investigated or replayed later.

The main goal is to make the workflow resilient without allowing retries to become a bottleneck for everything else.

Hi @Kabrooks
Retry On Fail keeps the execution running for the whole Wait Between Tries, so a long backoff on the node is what eats the slot. Do the backoff in a Wait node set above 65 seconds and loop back into the HTTP Request. Past that threshold n8n offloads the execution data to the database and the process stops running until it resumes, so a 5 minute backoff costs you nothing while it waits.
On self-hosted, N8N_CONCURRENCY_PRODUCTION_LIMIT queues production executions over the limit in FIFO order, but it only counts webhook and trigger executions. Sub-workflow and error executions bypass it, so a recovery workflow called that way is not throttled by that limit and can still pile up.

I’d separate two things here: retry logic and workflow isolation.

Retries are useful, but I would not let a flaky API hold the main workflow hostage forever. After a small retry budget, I’d move the failed request into a recovery path and let the main workflow either finish cleanly or fail with a clear reason.

One pattern I like is:

Main workflow prepares the payload

API sub-workflow handles the request

The sub-workflow returns either success or a normalized failure object

Failures get logged somewhere reviewable with status code, response body, execution ID, original payload, and next action

Temporary errors like timeouts, 429s, and 5xx responses can retry with backoff. Auth errors, bad input, or schema problems should fail fast.

The big thing is making retries replayable and bounded. If the workflow already created something in another system, retrying the whole flow can create duplicates. I’d rather retry the smallest risky step and keep enough context to recover manually if needed.