From 1f4dde5d106e4f7e0f4f8393577d4a931edb1089 Mon Sep 17 00:00:00 2001 From: Gremlin Date: Wed, 17 Jun 2026 10:28:47 +0000 Subject: [PATCH 1/6] docs(compute): add KeepAwakeGuard documentation page --- .../content/docs/compute/keep-awake-guard.mdx | 132 ++++++++++++++++++ apps/docs/content/docs/compute/meta.json | 1 + 2 files changed, 133 insertions(+) create mode 100644 apps/docs/content/docs/compute/keep-awake-guard.mdx diff --git a/apps/docs/content/docs/compute/keep-awake-guard.mdx b/apps/docs/content/docs/compute/keep-awake-guard.mdx new file mode 100644 index 0000000000..9dcd7a9983 --- /dev/null +++ b/apps/docs/content/docs/compute/keep-awake-guard.mdx @@ -0,0 +1,132 @@ +--- +title: KeepAwakeGuard +description: "Keep a compute instance awake and prevent it from scaling to zero with the KeepAwakeGuard primitive from @prisma/compute." +url: /compute/keep-awake-guard +metaTitle: "KeepAwakeGuard | Prisma Compute" +metaDescription: Learn how to use KeepAwakeGuard from @prisma/compute to keep compute instances awake and prevent scale-to-zero, including the signal fallback option and waitUntil-style API. +--- + +`KeepAwakeGuard` is a primitive from `@prisma/compute` that keeps a compute instance awake, preventing it from [scaling to zero](/compute/pricing). Use it when your app needs to stay alive for long-running work, background tasks, or any scenario where the compute must not be suspended between requests. + +## Overview + +By default, Prisma Compute [scales idle instances to zero](/compute/pricing) to save cost. Most apps only need compute during an active request, but some workloads — such as long-running jobs, WebSocket connections, or background processing — require the instance to stay alive even when no request is in flight. + +`KeepAwakeGuard` provides a guard approach: while the guard is active, the compute instance will not scale to zero. When the guard completes or is released, normal scaling behavior resumes. + +### Renamed from ScaleToZeroGuard + +`KeepAwakeGuard` was previously named `ScaleToZeroGuard`. The rename happened in `@prisma/compute@0.1.0-dev.4.1`. The old name still works but is deprecated — update your imports to use `KeepAwakeGuard`. + +:::note + +`ScaleToZeroGuard` is a deprecated alias for `KeepAwakeGuard`. It will be removed in a future release. Migrate to `KeepAwakeGuard` when you update to `@prisma/compute@0.1.0-dev.4.1` or later. + +::: + +## Usage + +Import `KeepAwakeGuard` from `@prisma/compute` and instantiate it to keep the current compute instance awake: + +```ts title="src/index.ts" +import { KeepAwakeGuard } from "@prisma/compute"; + +const guard = new KeepAwakeGuard(); + +// The compute instance will stay awake as long as this guard is active. +``` + +The guard keeps the instance alive until it is explicitly released or goes out of scope. Use it around any block of work that must complete without the instance being suspended: + +```ts title="src/index.ts" +import { KeepAwakeGuard } from "@prisma/compute"; + +async function processBatch() { + const guard = new KeepAwakeGuard(); + try { + await fetchAllRecords(); + await transformData(); + await writeResults(); + } finally { + guard.release(); + } +} +``` + +Calling `guard.release()` signals that the work is done and the instance can resume normal scaling behavior. + +### Using with `waitUntil` + +The `KeepAwakeGuard` API follows the `waitUntil`-style pattern familiar from [Cloudflare Workers](https://developers.cloudflare.com/workers/) and [Service Worker APIs](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerGlobalScope/waitUntil). This design choice makes the guard intuitive for developers already working with edge and worker runtimes: + +```ts title="src/index.ts" +import { KeepAwakeGuard } from "@prisma/compute"; + +export default { + fetch(req: Request, env: Env, ctx: ExecutionContext) { + const guard = new KeepAwakeGuard(); + + ctx.waitUntil( + processInBackground(req).finally(() => guard.release()) + ); + + return new Response("Accepted"); + }, +}; +``` + +By passing the guard's lifetime to `waitUntil`, the runtime knows the instance must stay alive until the background work finishes, even though the response has already been sent. + +## The `signal` option + +`KeepAwakeGuard` accepts a `signal` option that serves as a **fallback** for extreme cases where the instance might still be shut down despite the guard being active: + +```ts title="src/index.ts" +import { KeepAwakeGuard } from "@prisma/compute"; + +const controller = new AbortController(); + +const guard = new KeepAwakeGuard({ + signal: controller.signal, +}); +``` + +:::warning + +The `signal` option is a **fallback**, not the primary mechanism for cancelling your work. It is intended for rare cases where the platform cannot honor the keep-awake guarantee (for example, during infrastructure maintenance or forced shutdowns). Do not use `signal` as the cancellation signal for your underlying work — your own cancellation logic should remain independent. + +::: + +When the fallback `signal` fires, it means the platform is about to shut down the instance despite the guard. Use it only for emergency cleanup, not for normal workflow control: + +```ts title="src/index.ts" +import { KeepAwakeGuard } from "@prisma/compute"; + +const controller = new AbortController(); + +const guard = new KeepAwakeGuard({ + signal: controller.signal, +}); + +controller.signal.addEventListener("abort", () => { + // Emergency cleanup only — this is a fallback, not normal flow. + flushBuffersSync(); +}); +``` + +The `signal` API design aligns with the `AbortSignal` patterns used in Cloudflare Workers and Service Worker APIs, so the interface is familiar if you have worked with those platforms. + +## API reference + +| Property | Type | Description | +| -------------- | --------------- | ---------------------------------------------------------------------------------------------------- | +| `signal` | `AbortSignal` | Fallback signal that fires if the platform cannot honor the keep-awake guarantee. Not for cancelling your work. | +| `release()` | `() => void` | Releases the guard, allowing the instance to resume normal scaling behavior. | + +## What's next + +- [Pricing](/compute/pricing): how scale-to-zero billing works. +- [Deployments](/compute/deployments): build, deploy, logs, promote, and roll back. +- [Environment variables](/compute/environment-variables): scoped configuration and secrets. +- [Configuration](/compute/configuration): the `prisma.compute.ts` file reference. +- [Known limitations](/compute/limitations): what the beta can and can't do. diff --git a/apps/docs/content/docs/compute/meta.json b/apps/docs/content/docs/compute/meta.json index f4a336b1f9..1d0cd15106 100644 --- a/apps/docs/content/docs/compute/meta.json +++ b/apps/docs/content/docs/compute/meta.json @@ -11,6 +11,7 @@ "deployments", "environment-variables", "domains", + "keep-awake-guard", "---Integrations---", "github", "---Reference---", From 451f14cc7518e6425212f25082637d11b8dece63 Mon Sep 17 00:00:00 2001 From: Ankur Datta <64993082+ankur-arch@users.noreply.github.com> Date: Fri, 19 Jun 2026 12:20:44 +0200 Subject: [PATCH 2/6] docs(compute): reframe KeepAwakeGuard page as "Long-running servers" - Rename the page to "Long-running servers" (searchable by intent) and lead with the use case; KeepAwakeGuard stays documented as the API - Slug/url -> /compute/long-running-servers; reposition in the nav under Features right after Deployments - Make "Next steps" start with "Get started with Prisma Compute" - Remove em dashes, tighten for coherence (add a "When to use it" section) Co-Authored-By: Claude Opus 4.8 (1M context) --- .../content/docs/compute/keep-awake-guard.mdx | 132 ----------------- .../docs/compute/long-running-servers.mdx | 139 ++++++++++++++++++ apps/docs/content/docs/compute/meta.json | 2 +- 3 files changed, 140 insertions(+), 133 deletions(-) delete mode 100644 apps/docs/content/docs/compute/keep-awake-guard.mdx create mode 100644 apps/docs/content/docs/compute/long-running-servers.mdx diff --git a/apps/docs/content/docs/compute/keep-awake-guard.mdx b/apps/docs/content/docs/compute/keep-awake-guard.mdx deleted file mode 100644 index 9dcd7a9983..0000000000 --- a/apps/docs/content/docs/compute/keep-awake-guard.mdx +++ /dev/null @@ -1,132 +0,0 @@ ---- -title: KeepAwakeGuard -description: "Keep a compute instance awake and prevent it from scaling to zero with the KeepAwakeGuard primitive from @prisma/compute." -url: /compute/keep-awake-guard -metaTitle: "KeepAwakeGuard | Prisma Compute" -metaDescription: Learn how to use KeepAwakeGuard from @prisma/compute to keep compute instances awake and prevent scale-to-zero, including the signal fallback option and waitUntil-style API. ---- - -`KeepAwakeGuard` is a primitive from `@prisma/compute` that keeps a compute instance awake, preventing it from [scaling to zero](/compute/pricing). Use it when your app needs to stay alive for long-running work, background tasks, or any scenario where the compute must not be suspended between requests. - -## Overview - -By default, Prisma Compute [scales idle instances to zero](/compute/pricing) to save cost. Most apps only need compute during an active request, but some workloads — such as long-running jobs, WebSocket connections, or background processing — require the instance to stay alive even when no request is in flight. - -`KeepAwakeGuard` provides a guard approach: while the guard is active, the compute instance will not scale to zero. When the guard completes or is released, normal scaling behavior resumes. - -### Renamed from ScaleToZeroGuard - -`KeepAwakeGuard` was previously named `ScaleToZeroGuard`. The rename happened in `@prisma/compute@0.1.0-dev.4.1`. The old name still works but is deprecated — update your imports to use `KeepAwakeGuard`. - -:::note - -`ScaleToZeroGuard` is a deprecated alias for `KeepAwakeGuard`. It will be removed in a future release. Migrate to `KeepAwakeGuard` when you update to `@prisma/compute@0.1.0-dev.4.1` or later. - -::: - -## Usage - -Import `KeepAwakeGuard` from `@prisma/compute` and instantiate it to keep the current compute instance awake: - -```ts title="src/index.ts" -import { KeepAwakeGuard } from "@prisma/compute"; - -const guard = new KeepAwakeGuard(); - -// The compute instance will stay awake as long as this guard is active. -``` - -The guard keeps the instance alive until it is explicitly released or goes out of scope. Use it around any block of work that must complete without the instance being suspended: - -```ts title="src/index.ts" -import { KeepAwakeGuard } from "@prisma/compute"; - -async function processBatch() { - const guard = new KeepAwakeGuard(); - try { - await fetchAllRecords(); - await transformData(); - await writeResults(); - } finally { - guard.release(); - } -} -``` - -Calling `guard.release()` signals that the work is done and the instance can resume normal scaling behavior. - -### Using with `waitUntil` - -The `KeepAwakeGuard` API follows the `waitUntil`-style pattern familiar from [Cloudflare Workers](https://developers.cloudflare.com/workers/) and [Service Worker APIs](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerGlobalScope/waitUntil). This design choice makes the guard intuitive for developers already working with edge and worker runtimes: - -```ts title="src/index.ts" -import { KeepAwakeGuard } from "@prisma/compute"; - -export default { - fetch(req: Request, env: Env, ctx: ExecutionContext) { - const guard = new KeepAwakeGuard(); - - ctx.waitUntil( - processInBackground(req).finally(() => guard.release()) - ); - - return new Response("Accepted"); - }, -}; -``` - -By passing the guard's lifetime to `waitUntil`, the runtime knows the instance must stay alive until the background work finishes, even though the response has already been sent. - -## The `signal` option - -`KeepAwakeGuard` accepts a `signal` option that serves as a **fallback** for extreme cases where the instance might still be shut down despite the guard being active: - -```ts title="src/index.ts" -import { KeepAwakeGuard } from "@prisma/compute"; - -const controller = new AbortController(); - -const guard = new KeepAwakeGuard({ - signal: controller.signal, -}); -``` - -:::warning - -The `signal` option is a **fallback**, not the primary mechanism for cancelling your work. It is intended for rare cases where the platform cannot honor the keep-awake guarantee (for example, during infrastructure maintenance or forced shutdowns). Do not use `signal` as the cancellation signal for your underlying work — your own cancellation logic should remain independent. - -::: - -When the fallback `signal` fires, it means the platform is about to shut down the instance despite the guard. Use it only for emergency cleanup, not for normal workflow control: - -```ts title="src/index.ts" -import { KeepAwakeGuard } from "@prisma/compute"; - -const controller = new AbortController(); - -const guard = new KeepAwakeGuard({ - signal: controller.signal, -}); - -controller.signal.addEventListener("abort", () => { - // Emergency cleanup only — this is a fallback, not normal flow. - flushBuffersSync(); -}); -``` - -The `signal` API design aligns with the `AbortSignal` patterns used in Cloudflare Workers and Service Worker APIs, so the interface is familiar if you have worked with those platforms. - -## API reference - -| Property | Type | Description | -| -------------- | --------------- | ---------------------------------------------------------------------------------------------------- | -| `signal` | `AbortSignal` | Fallback signal that fires if the platform cannot honor the keep-awake guarantee. Not for cancelling your work. | -| `release()` | `() => void` | Releases the guard, allowing the instance to resume normal scaling behavior. | - -## What's next - -- [Pricing](/compute/pricing): how scale-to-zero billing works. -- [Deployments](/compute/deployments): build, deploy, logs, promote, and roll back. -- [Environment variables](/compute/environment-variables): scoped configuration and secrets. -- [Configuration](/compute/configuration): the `prisma.compute.ts` file reference. -- [Known limitations](/compute/limitations): what the beta can and can't do. diff --git a/apps/docs/content/docs/compute/long-running-servers.mdx b/apps/docs/content/docs/compute/long-running-servers.mdx new file mode 100644 index 0000000000..1dca8f622b --- /dev/null +++ b/apps/docs/content/docs/compute/long-running-servers.mdx @@ -0,0 +1,139 @@ +--- +title: Long-running servers +description: "Keep a Prisma Compute instance awake for long-running work, background tasks, and WebSocket connections so it does not scale to zero, using the KeepAwakeGuard primitive from @prisma/compute." +url: /compute/long-running-servers +metaTitle: "Long-running servers and background work | Prisma Compute" +metaDescription: Keep a Prisma Compute instance awake to run long-running jobs, background tasks, and WebSocket connections. Use the KeepAwakeGuard primitive from @prisma/compute to prevent scale-to-zero, with a signal fallback and a waitUntil-style API. +--- + +By default, Prisma Compute [scales idle instances to zero](/compute/pricing) to save cost: an instance only needs to run while it is handling a request. Some workloads need more than that. Long-running jobs, background processing, and open WebSocket connections all need the instance to keep running even when no request is in flight. + +`KeepAwakeGuard`, a primitive from `@prisma/compute`, keeps the current instance awake for exactly those cases. While a guard is active, the instance does not scale to zero. When you release the guard, normal scaling resumes. + +## When to use it + +Reach for `KeepAwakeGuard` when your app must keep running between requests, for example: + +- A long-running job that outlives the request that started it. +- Background processing you kick off after returning a response. +- A WebSocket connection that must stay open. + +If your work always finishes inside a single request, you do not need a guard. Let the instance scale to zero as usual. + +### Renamed from ScaleToZeroGuard + +`KeepAwakeGuard` was previously named `ScaleToZeroGuard`. The rename happened in `@prisma/compute@0.1.0-dev.4.1`. The old name still works but is deprecated, so update your imports to use `KeepAwakeGuard`. + +:::note + +`ScaleToZeroGuard` is a deprecated alias for `KeepAwakeGuard` and will be removed in a future release. Migrate to `KeepAwakeGuard` when you update to `@prisma/compute@0.1.0-dev.4.1` or later. + +::: + +## Usage + +Import `KeepAwakeGuard` from `@prisma/compute` and instantiate it to keep the current compute instance awake: + +```ts title="src/index.ts" +import { KeepAwakeGuard } from "@prisma/compute"; + +const guard = new KeepAwakeGuard(); + +// The compute instance stays awake as long as this guard is active. +``` + +The guard keeps the instance alive until you release it. Wrap it around any block of work that must finish without the instance being suspended: + +```ts title="src/index.ts" +import { KeepAwakeGuard } from "@prisma/compute"; + +async function processBatch() { + const guard = new KeepAwakeGuard(); + try { + await fetchAllRecords(); + await transformData(); + await writeResults(); + } finally { + guard.release(); + } +} +``` + +Calling `guard.release()` signals that the work is done and the instance can resume normal scaling behavior. + +### Using with `waitUntil` + +The `KeepAwakeGuard` API follows the `waitUntil`-style pattern from [Cloudflare Workers](https://developers.cloudflare.com/workers/) and the [Service Worker API](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerGlobalScope/waitUntil), so it reads naturally if you have built on edge or worker runtimes: + +```ts title="src/index.ts" +import { KeepAwakeGuard } from "@prisma/compute"; + +export default { + fetch(req: Request, env: Env, ctx: ExecutionContext) { + const guard = new KeepAwakeGuard(); + + ctx.waitUntil( + processInBackground(req).finally(() => guard.release()) + ); + + return new Response("Accepted"); + }, +}; +``` + +Passing the guard's lifetime to `waitUntil` tells the runtime the instance must stay alive until the background work finishes, even though the response has already been sent. + +## The `signal` option + +`KeepAwakeGuard` accepts a `signal` option that acts as a fallback for the rare case where the instance might still be shut down while a guard is active: + +```ts title="src/index.ts" +import { KeepAwakeGuard } from "@prisma/compute"; + +const controller = new AbortController(); + +const guard = new KeepAwakeGuard({ + signal: controller.signal, +}); +``` + +:::warning + +The `signal` option is a fallback, not the primary way to cancel your work. It is meant for rare cases where the platform cannot honor the keep-awake guarantee, such as infrastructure maintenance or a forced shutdown. Keep your own cancellation logic independent of this signal. + +::: + +When the fallback `signal` fires, the platform is about to shut the instance down despite the guard. Use it only for emergency cleanup, not for normal workflow control: + +```ts title="src/index.ts" +import { KeepAwakeGuard } from "@prisma/compute"; + +const controller = new AbortController(); + +const guard = new KeepAwakeGuard({ + signal: controller.signal, +}); + +controller.signal.addEventListener("abort", () => { + // Emergency cleanup only. This is a fallback, not normal flow. + flushBuffersSync(); +}); +``` + +The `signal` follows the `AbortSignal` pattern used in Cloudflare Workers and the Service Worker API, so the interface is familiar if you have worked with those platforms. + +## API reference + +| Property | Type | Description | +| ----------- | ------------- | --------------------------------------------------------------------------------------------------------------- | +| `signal` | `AbortSignal` | Fallback signal that fires if the platform cannot honor the keep-awake guarantee. Not for cancelling your work. | +| `release()` | `() => void` | Releases the guard, allowing the instance to resume normal scaling behavior. | + +## Next steps + +- [Get started with Prisma Compute](/compute/getting-started): deploy your first app. +- [Pricing](/compute/pricing): how scale-to-zero billing works. +- [Deployments](/compute/deployments): build, deploy, logs, promote, and roll back. +- [Environment variables](/compute/environment-variables): scoped configuration and secrets. +- [Configuration](/compute/configuration): the `prisma.compute.ts` file reference. +- [Known limitations](/compute/limitations): what the beta can and can't do. diff --git a/apps/docs/content/docs/compute/meta.json b/apps/docs/content/docs/compute/meta.json index 1d0cd15106..e2ab5fc0b8 100644 --- a/apps/docs/content/docs/compute/meta.json +++ b/apps/docs/content/docs/compute/meta.json @@ -9,9 +9,9 @@ "---Features---", "branching", "deployments", + "long-running-servers", "environment-variables", "domains", - "keep-awake-guard", "---Integrations---", "github", "---Reference---", From 6b81800ff39fdf141f537c2999861eebfb5ad863 Mon Sep 17 00:00:00 2001 From: Ankur Datta <64993082+ankur-arch@users.noreply.github.com> Date: Fri, 19 Jun 2026 12:22:47 +0200 Subject: [PATCH 3/6] docs(compute): retitle to "Keeping instances awake" for accuracy "Long-running servers" implied an always-on server. The feature actually keeps an instance awake (prevents scale-to-zero) while work outlives a request, so title/slug/url -> "Keeping instances awake" / /compute/keeping-instances-awake. Co-Authored-By: Claude Opus 4.8 (1M context) --- ...running-servers.mdx => keeping-instances-awake.mdx} | 10 +++++----- apps/docs/content/docs/compute/meta.json | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) rename apps/docs/content/docs/compute/{long-running-servers.mdx => keeping-instances-awake.mdx} (90%) diff --git a/apps/docs/content/docs/compute/long-running-servers.mdx b/apps/docs/content/docs/compute/keeping-instances-awake.mdx similarity index 90% rename from apps/docs/content/docs/compute/long-running-servers.mdx rename to apps/docs/content/docs/compute/keeping-instances-awake.mdx index 1dca8f622b..9c670280f1 100644 --- a/apps/docs/content/docs/compute/long-running-servers.mdx +++ b/apps/docs/content/docs/compute/keeping-instances-awake.mdx @@ -1,9 +1,9 @@ --- -title: Long-running servers -description: "Keep a Prisma Compute instance awake for long-running work, background tasks, and WebSocket connections so it does not scale to zero, using the KeepAwakeGuard primitive from @prisma/compute." -url: /compute/long-running-servers -metaTitle: "Long-running servers and background work | Prisma Compute" -metaDescription: Keep a Prisma Compute instance awake to run long-running jobs, background tasks, and WebSocket connections. Use the KeepAwakeGuard primitive from @prisma/compute to prevent scale-to-zero, with a signal fallback and a waitUntil-style API. +title: Keeping instances awake +description: "Keep a Prisma Compute instance awake so it does not scale to zero while you run background work, long-running jobs, or WebSocket connections, using the KeepAwakeGuard primitive from @prisma/compute." +url: /compute/keeping-instances-awake +metaTitle: "Keeping instances awake | Prisma Compute" +metaDescription: Keep a Prisma Compute instance awake and prevent scale-to-zero while you run background work, long-running jobs, or WebSocket connections. Use the KeepAwakeGuard primitive from @prisma/compute, with a signal fallback and a waitUntil-style API. --- By default, Prisma Compute [scales idle instances to zero](/compute/pricing) to save cost: an instance only needs to run while it is handling a request. Some workloads need more than that. Long-running jobs, background processing, and open WebSocket connections all need the instance to keep running even when no request is in flight. diff --git a/apps/docs/content/docs/compute/meta.json b/apps/docs/content/docs/compute/meta.json index e2ab5fc0b8..1ea2668efe 100644 --- a/apps/docs/content/docs/compute/meta.json +++ b/apps/docs/content/docs/compute/meta.json @@ -9,7 +9,7 @@ "---Features---", "branching", "deployments", - "long-running-servers", + "keeping-instances-awake", "environment-variables", "domains", "---Integrations---", From 283569d848d49b42d01a05defc94200ccbc6cd40 Mon Sep 17 00:00:00 2001 From: Ankur Datta <64993082+ankur-arch@users.noreply.github.com> Date: Fri, 19 Jun 2026 12:25:39 +0200 Subject: [PATCH 4/6] docs(compute): drop internal dev version, point to @prisma/compute@latest The 0.1.0-dev.4.1 version is not user-facing. Reword the rename note to install @prisma/compute@latest and migrate imports to KeepAwakeGuard. Co-Authored-By: Claude Opus 4.8 (1M context) --- apps/docs/content/docs/compute/keeping-instances-awake.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/docs/content/docs/compute/keeping-instances-awake.mdx b/apps/docs/content/docs/compute/keeping-instances-awake.mdx index 9c670280f1..6e44dc4ab7 100644 --- a/apps/docs/content/docs/compute/keeping-instances-awake.mdx +++ b/apps/docs/content/docs/compute/keeping-instances-awake.mdx @@ -22,11 +22,11 @@ If your work always finishes inside a single request, you do not need a guard. L ### Renamed from ScaleToZeroGuard -`KeepAwakeGuard` was previously named `ScaleToZeroGuard`. The rename happened in `@prisma/compute@0.1.0-dev.4.1`. The old name still works but is deprecated, so update your imports to use `KeepAwakeGuard`. +`KeepAwakeGuard` was previously named `ScaleToZeroGuard`. The old name still works as a deprecated alias, so update your imports to use `KeepAwakeGuard`. :::note -`ScaleToZeroGuard` is a deprecated alias for `KeepAwakeGuard` and will be removed in a future release. Migrate to `KeepAwakeGuard` when you update to `@prisma/compute@0.1.0-dev.4.1` or later. +`ScaleToZeroGuard` is a deprecated alias for `KeepAwakeGuard` and will be removed in a future release. Install the current release with `@prisma/compute@latest` and update your imports to `KeepAwakeGuard`. ::: From 53a1a84274564d054a38373a5e37771f81001d90 Mon Sep 17 00:00:00 2001 From: Tyler Benfield Date: Fri, 19 Jun 2026 08:11:55 -0400 Subject: [PATCH 5/6] Document waitUntil for keep-awake lifetimes --- .../docs/compute/keeping-instances-awake.mdx | 139 ++++++++++-------- 1 file changed, 79 insertions(+), 60 deletions(-) diff --git a/apps/docs/content/docs/compute/keeping-instances-awake.mdx b/apps/docs/content/docs/compute/keeping-instances-awake.mdx index 6e44dc4ab7..54a9458d2a 100644 --- a/apps/docs/content/docs/compute/keeping-instances-awake.mdx +++ b/apps/docs/content/docs/compute/keeping-instances-awake.mdx @@ -1,48 +1,70 @@ --- title: Keeping instances awake -description: "Keep a Prisma Compute instance awake so it does not scale to zero while you run background work, long-running jobs, or WebSocket connections, using the KeepAwakeGuard primitive from @prisma/compute." +description: "Keep a Prisma Compute instance awake so it does not scale to zero while you run background work, long-running jobs, or WebSocket connections." url: /compute/keeping-instances-awake metaTitle: "Keeping instances awake | Prisma Compute" -metaDescription: Keep a Prisma Compute instance awake and prevent scale-to-zero while you run background work, long-running jobs, or WebSocket connections. Use the KeepAwakeGuard primitive from @prisma/compute, with a signal fallback and a waitUntil-style API. +metaDescription: Keep a Prisma Compute instance awake and prevent scale-to-zero while you run background work, long-running jobs, or WebSocket connections with waitUntil and KeepAwakeGuard from @prisma/compute. --- -By default, Prisma Compute [scales idle instances to zero](/compute/pricing) to save cost: an instance only needs to run while it is handling a request. Some workloads need more than that. Long-running jobs, background processing, and open WebSocket connections all need the instance to keep running even when no request is in flight. +By default, Prisma Compute [scales idle instances to zero](/compute/pricing) to save cost: idle instances sleep with a memory snapshot, then resume with memory intact in milliseconds. Some workloads need the instance to keep running instead. Long-running jobs, background processing, and open WebSocket connections all need the instance awake after a request ends or while no request is in flight. -`KeepAwakeGuard`, a primitive from `@prisma/compute`, keeps the current instance awake for exactly those cases. While a guard is active, the instance does not scale to zero. When you release the guard, normal scaling resumes. +`@prisma/compute` provides two primitives for these cases: -## When to use it +- `waitUntil`: keeps the current instance awake until a background promise settles. +- `KeepAwakeGuard`: keeps the current instance awake until you release the guard. -Reach for `KeepAwakeGuard` when your app must keep running between requests, for example: +## When to keep instances awake + +Reach for `waitUntil` or `KeepAwakeGuard` when your app must keep running between requests, for example: - A long-running job that outlives the request that started it. - Background processing you kick off after returning a response. - A WebSocket connection that must stay open. -If your work always finishes inside a single request, you do not need a guard. Let the instance scale to zero as usual. +If your work always finishes inside a single request, you do not need either primitive. Let the instance sleep as usual. -### Renamed from ScaleToZeroGuard +## Use `waitUntil` for background promises -`KeepAwakeGuard` was previously named `ScaleToZeroGuard`. The old name still works as a deprecated alias, so update your imports to use `KeepAwakeGuard`. +Use `waitUntil` when you have a promise for background work that should keep the instance awake. This is the most direct API for work you start during a request but do not await before returning a response: -:::note +```ts title="src/index.ts" +import { waitUntil } from "@prisma/compute"; -`ScaleToZeroGuard` is a deprecated alias for `KeepAwakeGuard` and will be removed in a future release. Install the current release with `@prisma/compute@latest` and update your imports to `KeepAwakeGuard`. +export default { + fetch(req: Request) { + waitUntil(processInBackground(req), { + // Optional. Prevents a hanging Promise from indefinitely preventing sleep + signal: AbortSignal.timeout(30_000), + }); -::: + return new Response("Accepted"); + }, +}; +``` + +`waitUntil` follows the same pattern as [Cloudflare Workers](https://developers.cloudflare.com/workers/runtime-apis/context/#waituntil) and the [Service Workers API](https://developer.mozilla.org/en-US/docs/Web/API/ExtendableEvent/waitUntil): the instance stays awake until the promise settles. Prisma Compute adds an optional caller-owned `signal` value so you can bound the keep-awake lifetime if a promise hangs or never settles. + +## Use `KeepAwakeGuard` for block-scoped or manual lifetimes -## Usage +Use `KeepAwakeGuard` when the keep-awake lifetime does not map cleanly to one promise, or when a block scope should control when the instance can resume normal scaling. -Import `KeepAwakeGuard` from `@prisma/compute` and instantiate it to keep the current compute instance awake: +`KeepAwakeGuard` implements the JavaScript [`Disposable` interface](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Resource_management), so you can use the `using` keyword to release it automatically at the end of the scope: ```ts title="src/index.ts" import { KeepAwakeGuard } from "@prisma/compute"; -const guard = new KeepAwakeGuard(); +async function processBatch() { + using guard = new KeepAwakeGuard(); -// The compute instance stays awake as long as this guard is active. + await fetchAllRecords(); + await transformData(); + await writeResults(); +} ``` -The guard keeps the instance alive until you release it. Wrap it around any block of work that must finish without the instance being suspended: +While the guard is active, the instance does not sleep. When the scope exits, `using` disposes the guard and normal scaling resumes. + +If `using` is not available in your runtime or build setup, or if you need more granular control, release the guard in a `finally` block. This prevents a thrown error from leaving the guard active longer than intended: ```ts title="src/index.ts" import { KeepAwakeGuard } from "@prisma/compute"; @@ -59,75 +81,72 @@ async function processBatch() { } ``` -Calling `guard.release()` signals that the work is done and the instance can resume normal scaling behavior. - -### Using with `waitUntil` - -The `KeepAwakeGuard` API follows the `waitUntil`-style pattern from [Cloudflare Workers](https://developers.cloudflare.com/workers/) and the [Service Worker API](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerGlobalScope/waitUntil), so it reads naturally if you have built on edge or worker runtimes: - -```ts title="src/index.ts" -import { KeepAwakeGuard } from "@prisma/compute"; - -export default { - fetch(req: Request, env: Env, ctx: ExecutionContext) { - const guard = new KeepAwakeGuard(); - - ctx.waitUntil( - processInBackground(req).finally(() => guard.release()) - ); - - return new Response("Accepted"); - }, -}; -``` - -Passing the guard's lifetime to `waitUntil` tells the runtime the instance must stay alive until the background work finishes, even though the response has already been sent. +Calling `guard.release()` signals that the work is done and the instance can resume normal scaling behavior. Always release manually created guards, preferably from `finally`, unless `using` owns the lifetime for you. ## The `signal` option -`KeepAwakeGuard` accepts a `signal` option that acts as a fallback for the rare case where the instance might still be shut down while a guard is active: +`KeepAwakeGuard` accepts a caller-owned `signal` option. Use it as a safety fallback to release the guard if your code does not reach `release()`. ```ts title="src/index.ts" import { KeepAwakeGuard } from "@prisma/compute"; -const controller = new AbortController(); - const guard = new KeepAwakeGuard({ - signal: controller.signal, + // Optional. Prevents a leaked guard from indefinitely preventing sleep + signal: AbortSignal.timeout(30_000), }); ``` :::warning -The `signal` option is a fallback, not the primary way to cancel your work. It is meant for rare cases where the platform cannot honor the keep-awake guarantee, such as infrastructure maintenance or a forced shutdown. Keep your own cancellation logic independent of this signal. +The `signal` option is a fallback, not the primary way to control your work. Prefer `using` or `try`/`finally` for normal guard lifetimes. Use `signal` to cap the maximum lifetime of a guard and avoid dangling guards. ::: -When the fallback `signal` fires, the platform is about to shut the instance down despite the guard. Use it only for emergency cleanup, not for normal workflow control: +For example, combine `AbortSignal.timeout()` with `try`/`finally` when a job should keep the instance awake, but never for longer than a fixed duration: ```ts title="src/index.ts" import { KeepAwakeGuard } from "@prisma/compute"; -const controller = new AbortController(); - -const guard = new KeepAwakeGuard({ - signal: controller.signal, -}); +async function processBatch() { + const guard = new KeepAwakeGuard({ + // Optional. Prevents a leaked guard from indefinitely preventing sleep + signal: AbortSignal.timeout(30_000), + }); -controller.signal.addEventListener("abort", () => { - // Emergency cleanup only. This is a fallback, not normal flow. - flushBuffersSync(); -}); + try { + await fetchAllRecords(); + await transformData(); + await writeResults(); + } finally { + guard.release(); + } +} ``` -The `signal` follows the `AbortSignal` pattern used in Cloudflare Workers and the Service Worker API, so the interface is familiar if you have worked with those platforms. +The `signal` follows the standard `AbortSignal` pattern, so you can pass any signal you control. ## API reference -| Property | Type | Description | -| ----------- | ------------- | --------------------------------------------------------------------------------------------------------------- | -| `signal` | `AbortSignal` | Fallback signal that fires if the platform cannot honor the keep-awake guarantee. Not for cancelling your work. | -| `release()` | `() => void` | Releases the guard, allowing the instance to resume normal scaling behavior. | +### `waitUntil` + +```ts title="@prisma/compute" +waitUntil(promise: Promise, options?: { signal?: AbortSignal }): void; +``` + +Keeps the instance awake until `promise` settles. Pass `options.signal` as a caller-owned fallback to release the keep-awake lifetime if the promise hangs or never settles. + +### `KeepAwakeGuard` + +```ts title="@prisma/compute" +new KeepAwakeGuard(options?: { signal?: AbortSignal }); +``` + +Creates a guard that keeps the instance awake until the guard is disposed, released, or its optional caller-owned `signal` aborts. + +| Member | Type | Description | +| ------------ | ---------------- | --------------------------------------------------------------------------- | +| `release()` | `() => void` | Releases the guard, allowing the instance to resume normal scaling behavior. | +| `Disposable` | `Symbol.dispose` | Enables automatic release with `using`. | ## Next steps From c62bc6d66b6ec4147a8566ef58c59dd06ccc9510 Mon Sep 17 00:00:00 2001 From: Tyler Benfield Date: Fri, 19 Jun 2026 08:14:09 -0400 Subject: [PATCH 6/6] Clarify keep-awake signal behavior --- .../docs/compute/keeping-instances-awake.mdx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/docs/content/docs/compute/keeping-instances-awake.mdx b/apps/docs/content/docs/compute/keeping-instances-awake.mdx index 54a9458d2a..ac12aa44ea 100644 --- a/apps/docs/content/docs/compute/keeping-instances-awake.mdx +++ b/apps/docs/content/docs/compute/keeping-instances-awake.mdx @@ -33,7 +33,7 @@ import { waitUntil } from "@prisma/compute"; export default { fetch(req: Request) { waitUntil(processInBackground(req), { - // Optional. Prevents a hanging Promise from indefinitely preventing sleep + // Optional. Prevents a hanging promise from keeping the instance awake indefinitely. signal: AbortSignal.timeout(30_000), }); @@ -42,7 +42,7 @@ export default { }; ``` -`waitUntil` follows the same pattern as [Cloudflare Workers](https://developers.cloudflare.com/workers/runtime-apis/context/#waituntil) and the [Service Workers API](https://developer.mozilla.org/en-US/docs/Web/API/ExtendableEvent/waitUntil): the instance stays awake until the promise settles. Prisma Compute adds an optional caller-owned `signal` value so you can bound the keep-awake lifetime if a promise hangs or never settles. +`waitUntil` follows the same pattern as [Cloudflare Workers](https://developers.cloudflare.com/workers/runtime-apis/context/#waituntil) and the [Service Worker API](https://developer.mozilla.org/en-US/docs/Web/API/ExtendableEvent/waitUntil): the instance stays awake until the promise settles. Prisma Compute adds an optional caller-owned `signal` value so you can stop the keep-awake effect if a promise hangs or never settles. The signal does not cancel the promise or the work it started. ## Use `KeepAwakeGuard` for block-scoped or manual lifetimes @@ -85,20 +85,20 @@ Calling `guard.release()` signals that the work is done and the instance can res ## The `signal` option -`KeepAwakeGuard` accepts a caller-owned `signal` option. Use it as a safety fallback to release the guard if your code does not reach `release()`. +`KeepAwakeGuard` accepts a caller-owned `signal` option. Use it as a safety fallback to release the guard if your code does not reach `release()`. The signal releases the keep-awake guard; it does not cancel the work protected by the guard. ```ts title="src/index.ts" import { KeepAwakeGuard } from "@prisma/compute"; const guard = new KeepAwakeGuard({ - // Optional. Prevents a leaked guard from indefinitely preventing sleep + // Optional. Prevents a leaked guard from keeping the instance awake indefinitely. signal: AbortSignal.timeout(30_000), }); ``` :::warning -The `signal` option is a fallback, not the primary way to control your work. Prefer `using` or `try`/`finally` for normal guard lifetimes. Use `signal` to cap the maximum lifetime of a guard and avoid dangling guards. +The `signal` option is a fallback, not the primary way to control your work. Prefer `using` or `try`/`finally` for normal guard lifetimes. Use `signal` to cap the maximum keep-awake lifetime and avoid dangling guards. ::: @@ -109,7 +109,7 @@ import { KeepAwakeGuard } from "@prisma/compute"; async function processBatch() { const guard = new KeepAwakeGuard({ - // Optional. Prevents a leaked guard from indefinitely preventing sleep + // Optional. Prevents a leaked guard from keeping the instance awake indefinitely. signal: AbortSignal.timeout(30_000), }); @@ -133,7 +133,7 @@ The `signal` follows the standard `AbortSignal` pattern, so you can pass any sig waitUntil(promise: Promise, options?: { signal?: AbortSignal }): void; ``` -Keeps the instance awake until `promise` settles. Pass `options.signal` as a caller-owned fallback to release the keep-awake lifetime if the promise hangs or never settles. +Keeps the instance awake until `promise` settles. Pass `options.signal` as a caller-owned fallback to stop keeping the instance awake if the promise hangs or never settles. The signal does not cancel the promise. ### `KeepAwakeGuard` @@ -141,7 +141,7 @@ Keeps the instance awake until `promise` settles. Pass `options.signal` as a cal new KeepAwakeGuard(options?: { signal?: AbortSignal }); ``` -Creates a guard that keeps the instance awake until the guard is disposed, released, or its optional caller-owned `signal` aborts. +Creates a guard that keeps the instance awake until the guard is disposed, released, or its optional caller-owned `signal` aborts. The signal releases the guard; it does not cancel the work protected by the guard. | Member | Type | Description | | ------------ | ---------------- | --------------------------------------------------------------------------- |