# LLM API retry local HTTP experiment

Run date: 2026-09-24. This artifact tests a teaching HTTP client against a local fixture, not a provider outage, model quality or paid API billing.

## Reproduce

Use Node.js 22 (measured: v22.19.0, macOS arm64). Download or copy `retry-client.mjs` and `run-experiment.mjs` into one empty folder, inspect them, then run:

```sh
node run-experiment.mjs
```

No npm install, API keys or external requests. The experiment binds a server to `127.0.0.1` on an ephemeral port and shuts it down afterwards. `results.json` in that folder is overwritten. Copy published raw results before rerunning if you need to retain them.

## Frozen protocol and scope

The scenario table and expected outcomes are declared in `run-experiment.mjs` before any test executes. Eleven scenarios are run three times each, sequentially. Defaults are three attempts including the first request, a total 3000ms deadline, a 2000ms maximum accepted retry wait, 100ms exponential backoff base and zero test jitter. The two short-deadline scenarios override the deadline to 200ms and 80ms. The client default outside the experiment adds 0–99ms jitter, which is not performance-tested here.

Assertions compare the outcome and transmission count to declared expectations, independently count server arrivals, check minimum waits against server headers, and ensure the fixture response body is absent from events. Eleven parser cases cover seconds, zero, malformed values, dates in three HTTP forms, past dates, and an unrepresentably large integer.

## Results

`results.json` records the final PASS run (33 HTTP scenario runs, 11 parser inputs). All three repetitions preserved expected request counts and outcomes. No token usage, real model latency, provider availability, billing, streaming semantics, persistence, concurrent fleet behavior, idempotency or cross-provider fallback was measured.

During test development, the obsolete asctime HTTP-date test exposed JavaScript interpreting a timezone-free date in local time. The parser was corrected to append GMT for that HTTP form. The published result was generated after this correction. Earlier exploratory results are not reported as production evidence.

The client uses GET and non-streaming JSON. It deliberately stops after transport/body-consumption errors and marks the result unknown, because connection failure does not prove that a remote side effect was not completed. Real provider integrations need endpoint-specific adapters, POST body handling, redaction, cancellation, schema validation, operation IDs and duplicate-effect controls. This is not a drop-in production SDK.

## Primary references checked 2026-09-24

- [HTTP Retry-After, RFC 9110 §10.2.3](https://www.rfc-editor.org/rfc/rfc9110.html#name-retry-after)
- [OpenAI rate limits](https://developers.openai.com/api/docs/guides/rate-limits)
- [OpenAI error codes](https://developers.openai.com/api/docs/guides/error-codes)
- [Claude errors](https://platform.claude.com/docs/en/api/errors)
- [Claude rate limits](https://platform.claude.com/docs/en/api/rate-limits)
- [Gemini API errors](https://ai.google.dev/gemini-api/docs/api-errors)
