Skip to main content

Retry and polling

Two settings share the Retry tab because both answer "what happens when this does not go well". They are not the same thing, and the difference decides which one you want:

  • Retry is for a request that failed. The connection was refused, the gateway returned 502, the rate limiter said 429.
  • Polling is for a request that succeeded and said "not yet". An async job that answers status: "pending" eight times has not failed eight times.

Reporting a polled job as eight failures sends somebody hunting a bug that is not there, which is why they stay separate.


Retry​

The Retry tab — attempts, backoff and multiply, with the five opt-in conditions for which failures are worth repeating

Step by step​

1. Open the Retry tab and set attempts​

Select a request, open Retry, and set attempts. This is total tries, not extra ones: 3 means the request may be sent three times. Anything below 2 leaves retry off, which is the default.

Until you set it, the tab shows one field. The rest appears once retry is actually on — a wall of options is how a simple setting stops looking simple.

2. Choose which failures are worth repeating​

Nothing is retried until you tick something. All five conditions are opt-in:

ConditionRepeats whenUse it for
no responserefused, reset, timeout — no HTTP status at allthe commonest flake there is; the request may never have reached the server
5xxthe server returned 500–599a gateway or a dependency having a moment
429rate limitedbursty suites; see Retry-After below
other 4xx400–499rarely useful — these fail the same way every time
a failing testthe response arrived and a test in the Tests tab failedsee the caution below

:::caution "a failing test" is usually not what you want A 2xx that fails a test means the answer was wrong, not flaky. Sending it again three times usually gets the same wrong answer three times. If what you actually mean is "the job is not done yet", you want polling, further down this page. :::

:::note Why nothing is pre-ticked An earlier version pre-selected no response, 5xx and 429 on the grounds that those are what the status codes mean. True — and it meant switching retry on silently carried three opinions nobody chose. A test runner that repeats requests should do it only where you asked. :::

If you set attempts and tick nothing, the tab says so, because attempts: 3 sitting there repeating nothing is the worst of both.

3. Set the wait, if the default does not suit​

  • backoff — milliseconds between tries. Default 1000.
  • multiply — multiplies the wait each try. 1 (default) is a fixed wait; 2 gives 1s, 2s, 4s.

With 429, the server's own Retry-After header wins over your backoff — ignoring it is how a 1s/2s/4s schedule turns into three more 429s. Both legal forms are read, seconds and an HTTP date, and a hostile or mistaken value is capped at a minute so one header cannot hang a suite for a day.

:::caution POST and PUT Retrying a POST after a timeout may create a second record: the request can reach the server even when the answer does not come back. Trq warns on the tab when you tick no response on a POST or PATCH. If the endpoint is not idempotent, leave that one off. :::

Seeing that it happened​

A finished run showing a retried request — the sends count beside the duration, a Retried card in the Summary, and the failure line saying how many times it was sent

Everything counts sends, the same unit attempts uses. A request configured for 3 attempts and sent 3 times reads 3 everywhere:

WhereShows
the request row, beside the duration↻3
the Summary's Retried card1 request, 3 sends in total
the failure linestatus = 201 · sent 3×
the exported reportthe same, in the summary, the row and the detail
while it runs↻ send 2 of 3 on the row, during the wait

The duration you see is the last attempt's, not the total — which is exactly why the count has to be stated rather than inferred from the timing.


Polling​

Polling keeps sending until an answer satisfies a condition. It is for the shape every async API has:

POST /v1/exports → 202 { "jobId": "e_19f3", "status": "pending" }
GET /v1/exports/e_19f3 → 200 { "status": "pending" }
GET /v1/exports/e_19f3 → 200 { "status": "pending" }
GET /v1/exports/e_19f3 → 200 { "status": "complete", "url": "…" }

Step by step​

1. Open the Retry tab and press + Poll until a condition​

Polling works on its own. Nothing in the Retry section above needs switching on — in particular you do not need to tick a failing test.

The Poll until section — a condition built from the response, how often to ask, and how long to keep asking

2. Build the condition​

The editor is the Condition tab's, control for control: the same sources, the same suggester fed by the paths found in the last response, the same operator wording.

For the example above:

sourceresponse JSON path
pathstatus
operatorequals
valuecomplete

Only three sources are offered — response status, response JSON path, response header. A variable is not one of them: polling asks about the response it just got, and a variable is not that.

3. Set how often and how long​

  • every — milliseconds between attempts. Default 1000.
  • timeout — how long to keep asking in total. Default 30000.

4. What a timeout reports​

A poll that never resolves is reported as a wait, not as a pile of failures:

Still waiting after 30s and 30 attempts — response JSON path status equals "complete"

Nothing failed thirty times. The answer never arrived, and the condition is stated last, where you scan for it.


Using both together​

They compose, and the order is the useful one: a poll attempt that fails is retried by the rules above; one that succeeds without satisfying the condition just waits and asks again.

So a job that is both flaky and slow — the first two calls 502 while the service warms up, then pending for a while, then complete — needs 5xx ticked for the warm-up and a poll condition for the wait. Neither setting alone handles it.


Where retry settings live​

Per request, on its Retry tab. A case-wide default — set it once, every request inherits it — is designed but not shipped.


See also​

  • Conditions — the same editor, deciding whether a request runs at all
  • Assertions — the tests that a failing test reacts to
  • Running a case — what the Requests panel shows during a run