From 4f045cc962561c76e00b3940323ec3b7e6cbe79f Mon Sep 17 00:00:00 2001 From: Shane Ossa Date: Thu, 15 Oct 2026 17:41:20 +0000 Subject: [PATCH 1/2] Document that D1 binding has no per-call timeout option (DEE-3968) --- .../docs/d1/observability/debug-d1.mdx | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/content/docs/d1/observability/debug-d1.mdx b/src/content/docs/d1/observability/debug-d1.mdx index b093e67d6f4..0d97ff5eca5 100644 --- a/src/content/docs/d1/observability/debug-d1.mdx +++ b/src/content/docs/d1/observability/debug-d1.mdx @@ -118,3 +118,25 @@ You should include as much of the following in any bug report: * Learn [how to debug Workers](/workers/observability/). * Understand how to [access logs](/workers/observability/logs/) generated from your Worker and D1. * Use [`wrangler dev`](/workers/wrangler/commands/general/#dev) to run your Worker and D1 locally and [debug issues before deploying](/workers/local-development/). + +## D1 binding timeout behavior + +D1 binding methods — `run()`, `all()`, `first()`, and `batch()` — do not accept a timeout option or an `AbortSignal`. There is no per-call timeout built into the D1 binding client. + +Workers have no wall-time limit on incoming HTTP requests while the client connection is open — see [Workers limits](/workers/platform/limits/). If the Durable Object backing a D1 database is temporarily unreachable, a D1 binding call blocks until the operation completes, an internal limit is reached, or the Worker is terminated by an external event such as the client disconnecting. + +To limit how long your Worker waits on a D1 call, use `Promise.race` with a timer: + +```js +const timeout = new Promise((_, reject) => + setTimeout(() => reject(new Error('D1 call timed out')), 5000) +); +const result = await Promise.race([ + db.prepare('SELECT 1').first(), + timeout, +]); +``` + +:::caution[Write operations and Promise.race] +`Promise.race` bounds how long your Worker waits — it does not cancel the D1 query. A write that loses the race may still commit in the background. Always confirm the outcome of a write before retrying to avoid duplicate writes. +::: From 12758958380a98893da2341bca68bd062bfe987e Mon Sep 17 00:00:00 2001 From: Lambros Petrou Date: Tue, 20 Oct 2026 22:31:38 +0100 Subject: [PATCH 2/2] Update src/content/docs/d1/observability/debug-d1.mdx --- src/content/docs/d1/observability/debug-d1.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/d1/observability/debug-d1.mdx b/src/content/docs/d1/observability/debug-d1.mdx index 0d97ff5eca5..4261741c6d3 100644 --- a/src/content/docs/d1/observability/debug-d1.mdx +++ b/src/content/docs/d1/observability/debug-d1.mdx @@ -123,7 +123,7 @@ You should include as much of the following in any bug report: D1 binding methods — `run()`, `all()`, `first()`, and `batch()` — do not accept a timeout option or an `AbortSignal`. There is no per-call timeout built into the D1 binding client. -Workers have no wall-time limit on incoming HTTP requests while the client connection is open — see [Workers limits](/workers/platform/limits/). If the Durable Object backing a D1 database is temporarily unreachable, a D1 binding call blocks until the operation completes, an internal limit is reached, or the Worker is terminated by an external event such as the client disconnecting. +Workers have no wall-time limit on incoming HTTP requests while the client connection is open — see [Workers limits](/workers/platform/limits/). If the D1 database is temporarily unreachable, a D1 binding call blocks until the operation completes, an internal limit is reached, or the Worker is terminated by an external event such as the client disconnecting. To limit how long your Worker waits on a D1 call, use `Promise.race` with a timer: