Cloudflare Workers request.signal testing should answer a precise question: did downstream work stop, or did your code merely hear that the visitor left? Our original 18-run local simulation shows why those outcomes need separate evidence. The version that received an abort notification without forwarding the signal kept producing all three mock chunks.
With explicit forwarding, the mock stopped before producing a chunk in the early-abort cases and after one chunk in the during-stream cases. These are executed Node.js teaching simulations, not hosted Cloudflare integration results. No production Worker, paid API, real network stream or persistent business write was involved.
The compatibility change is dated 17 November
Cloudflare’s 2 November announcement says incoming request.signal becomes enabled by default for compatibility dates of 17 November 2026 or later. Existing Workers retain their behaviour until their dates or flags change. The feature itself was introduced in May 2025; the November news concerns its default.
The announcement also distinguishes this from request_signal_passthrough. Code should explicitly pass the signal to APIs that accept it. A notification on the incoming request does not establish that a separate downstream operation received a cancellation request.
As of our 7 November research date, the announced default date is still ahead. Check the current compatibility reference when planning an implementation. For earlier dates it documents enable_request_signal; it also documents disable_request_signal for opting out. We changed no compatibility configuration for this study.
A small cancellation experiment with known conditions
We created a fictional slow catalogue lookup using local timers and an AbortController. It imitates a headers event at 100 milliseconds and three chunk events at 150, 200 and 250 milliseconds. Those are chosen fixture settings, not measurements of a Nigerian network or Cloudflare response time.
Two implementations use the same mock. One listens for the simulated incoming abort but does not forward its signal. The other explicitly supplies that signal to the mock operation, which is written to accept cancellation. Therefore, the test examines an explicit control path with a known implementation.
| Client condition | Chosen local trigger | Repeats per implementation |
|---|---|---|
| Stay connected | No abort | 3 |
| Abort before mock headers | Timer scheduled at 20 ms | 3 |
| Abort during mock stream | Timer scheduled at 160 ms | 3 |
Three conditions times two implementations times three repeats give 18 executed runs. We ran them sequentially in Node v22.23.1 on one local macOS computer. They use no network requests, account credentials or customer records. No Cloudflare runtime was started, so Workers compatibility flags were not applied by this harness.

What stopped, and what merely received a notification
All nine no-forward runs completed the downstream mock and produced three chunks. In its six abort-condition runs, the harness recorded an abort notification first. That notification did not affect the operation because the downstream mock had not received the signal.
The explicitly forwarded version also completed all three stay-connected runs. In its three early-abort runs, cancellation stopped the mock before headers or chunks appeared. In its three during-stream runs, headers and the first chunk appeared before cancellation stopped the remaining work.
The result is inspectable in the event ledger. We retain request start, abort notification, downstream cancellation request, downstream stop or completion, and invocation completion. “Unobserved” is used when an event did not occur. It is never silently converted to a zero-millisecond response.
Read relative timings as local evidence
The no-forward early-abort cases completed roughly 230–231 milliseconds after the abort notification. Its during-stream cases completed roughly 90–92 milliseconds after notification. These intervals follow the deliberately selected timers and the local event loop.
In the forwarded version, the recorded downstream stop followed notification within about 0.033–0.116 milliseconds in this run. The same-process callback sequence explains that small interval. It is not an edge-network latency target, an operating guarantee or a measure of a real service’s cancellation speed.

Use a monotonic clock for intervals within a run. Keep wall-clock timestamps for correlating separate systems, and document their synchronization limits. A timer scheduled for 20 milliseconds can fire later; preserve the observed time instead of replacing it with the intended setting.
Our harness records invocation completion after the mock settles. That is a local function boundary, not an observation of Cloudflare isolate termination. The distinction matters when comparing a teaching trace with real runtime logs.
Unlock Your Unique Tech Path
Get expert tech consulting tailored just for you. Receive personalized advice and solutions within 1-3 business days.
Get StartedCancellation cannot erase a chunk that already exists
The during-stream condition is useful because some work has already happened. In our forwarded cases, one chunk existed before the abort. Cancelling the remaining timers prevented the next two mock chunks; it did not retract the first one.

The same reasoning prevents a more consequential mistake: treating a browser abort as proof that a database write was rolled back. A completed effect needs its own transaction and application evidence. This study performs no such writes, so it offers no rollback result.
The infographic keeps four events separate. A client can leave; code can request cancellation; a downstream operation can actually stop; and a persistent effect can still require an independent check. A useful log names the event it observed rather than collapsing all four into “cancelled.”

Place background work in the right lifecycle
Cloudflare’s context documentation, checked 7 November, says HTTP-triggered waitUntil work can continue for up to 30 seconds after the response is sent or the client disconnects. That allowance is shared across the request’s waitUntil calls. It is not 30 seconds per call or a total HTTP-request duration cap.
The documentation points to a queue and separate consumer for work that cannot finish within that allowance. Our local mock does not test waitUntil, queue delivery or retries. Those require their own lifecycle design and verification.
A disposable catalogue read may be suitable for explicit cancellation. Best-effort logging needs a clear loss policy. A job that must survive the visitor leaving needs a durable design, with retry and idempotency decisions appropriate to its real effects. These categories are a planning aid, not interchangeable guarantees.
Run the mock and collect your own evidence
The runnable simulation pack includes the original Node script, raw run receipts, environment record, four CSVs and README. From the extracted root, run node scripts/run_simulation.mjs. It creates local output files and makes no external calls.
- All 18 executed run summaries (CSV)
- Full monotonic event ledger (CSV)
- Blank 18-run integration worksheet (CSV)
- Work-lifecycle planning matrix (CSV)
For a later authorized hosted test, retain the exact runtime, compatibility date, flags and downstream API. First use a read-only operation and identify which events your logs can observe. Keep that integration session separate from these local results. Do not attach the exercise to a payment or personal-data workflow merely to make the example look realistic.
Our CI checker experiment applies the same principle to badges: verify what the signal actually establishes. Our rendered-page testing fixture likewise separates measurements taken from measurements still missing.
Method and limits: Executed 7 November 2026; 18 selected timer runs on one machine, with three repeats per pairing. The code demonstrates a cancellation path it explicitly implements. It cannot establish production cost savings, Nigerian disconnection prevalence, every race condition or the behaviour of a downstream service that ignores cancellation.
