# n8n HTTP retry behavior

Status: `VERIFIED`

This package compares two settings on the same n8n 2.30.5 HTTP Request
workflow:

1. no retry;
2. at most three attempts with a fixed 100 ms wait.

## Frozen protocol

The fixture is a local HTTP server reached by the container over
`host.docker.internal`. It records every request before returning a response.
The workflow receives actual HTTP responses rather than throwing synthetic
errors inside a Code node.

Each scenario runs ten times:

| Scenario | Fixture behavior |
| --- | --- |
| `control_200` | first request returns 200 |
| `recover_429` | first two requests return 429, third returns 200 |
| `recover_500` | first two requests return 500, third returns 200 |
| `recover_timeout` | first two responses wait 800 ms, third returns 200 |
| `persistent_429` | every request returns 429 |
| `persistent_500` | every request returns 500 |
| `persistent_timeout` | every response waits 800 ms |

The HTTP Request timeout is 300 ms. The retry node uses `maxTries: 3` and
`waitBetweenTries: 100`. The no-retry and retry nodes execute from the same
prepared input and both use `continueOnFail` so one branch cannot suppress the
other branch's evidence.

## Result

All 70 workflow runs and 140 strategy observations matched the frozen protocol.

| Result | No retry | Three attempts |
| --- | ---: | ---: |
| Controlled 200 success | 10 / 10 | 10 / 10 |
| Transient 429, 500 and timeout recovered | 0 / 30 | 30 / 30 |
| Persistent 429, 500 and timeout remained failed | 30 / 30 | 30 / 30 |
| Total HTTP requests | 70 | 190 |

The retry policy sent 2.714 times as many requests as the no-retry policy. It
recovered every transient failure in this deterministic protocol, but it did
not turn any persistent failure into success. The persistent-timeout median
node duration increased from 362 ms to 1,162 ms.

## Evidence

- `workflow.json`: importable n8n workflow containing both strategies.
- `runs.csv`: one row per strategy observation.
- `requests.csv`: one row per request received by the fixture.
- `samples.json`: normalized first repetition for each scenario.
- `summary.json`: scenario counts, request multiplier, timings and limitations.

`summary.json` reports zero protocol mismatches. The formal run started at
2026-07-23T08:59:39.368Z and completed at 2026-07-23T09:05:01.534Z.

An earlier collection attempt stopped after two control runs when the parent
process received `ECONNRESET` while reading fixture state. Those partial
results were excluded. The state query gained a bounded retry and the formal
run restarted from the first control case.

## Limits

- The fixture is local and deterministic. It does not model internet routing,
  shared quotas, or vendor rate-limit windows.
- This protocol uses fixed 100 ms waits. It does not test exponential backoff,
  jitter, or whether the node honors `Retry-After`.
- The workflow does not test idempotency keys, credentials, queue mode, or
  concurrent executions.
- Ten repetitions per scenario validate the frozen branches. They do not
  estimate rare production failure rates.
