Next and Vercel Runtime
Run the Crux Runtime Engine on serverless deployments with Postgres state and QStash wake delivery.
Use the serverless runtime when work must continue after a request ends and the deployment may be cold between wakes.
Install
pnpm add @use-crux/core @use-crux/postgres @use-crux/upstash pg @upstash/qstashConfigure runtime
import { config } from "@use-crux/core";
import { serverless } from "@use-crux/core/runtime";
import { postgres } from "@use-crux/postgres/runtime";
import { qstash } from "@use-crux/upstash/runtime";
export default config({
runtime: serverless({
store: postgres({ url: process.env.DATABASE_URL }),
wake: qstash(),
publicUrl: process.env.CRUX_PUBLIC_URL,
// Optional on Vercel: production and preview namespaces are inferred.
namespace: process.env.CRUX_RUNTIME_NAMESPACE,
retention: {
events: "24h",
terminalWork: "7d",
terminalSnapshots: "30d",
},
}),
});publicUrl can be omitted when Crux can infer a stable URL from Vercel environment variables. Production setup fails with PUBLIC_URL_UNRESOLVED when no stable URL exists.
namespace is also optional on Vercel. VERCEL_ENV=production resolves to production; previews resolve to preview-<sanitized-VERCEL_GIT_COMMIT_REF>, such as preview-feature-foo. An explicit namespace or CRUX_RUNTIME_NAMESPACE still wins when you need a custom partition.
Generate the route
Run generation before framework build:
crux runtime generateGenerated Next files target the public handler API:
import { createRuntimeHandler } from "@use-crux/core/runtime";
import { reviewFlow } from "@/flows/review";
import { embedDocument } from "@/tasks/embed-document";
export const { GET, POST } = createRuntimeHandler({
targets: [reviewFlow, embedDocument],
});POST verifies the wake request before durable writes. GET returns health metadata for setup and preflight without exposing secrets.
When deployable Evals are discovered, the same generated module also exports
DELETE and dispatches authenticated /manifest and /jobs/* requests to
the durable Eval host. Mount it from an optional catch-all route such as
app/api/crux/[[...path]]/route.ts; set CRUX_EVAL_HOST_DEPLOYMENT_ID and
CRUX_EVAL_HOST_TOKEN in the deployment secret store.
Verify setup
crux setup --check
crux runtime statusUse crux setup --apply only when you want Crux to create missing Crux-owned Postgres resources. It is additive only.
Production notes
- Keep
DATABASE_URL, QStash credentials, andCRUX_PUBLIC_URLin deployment secrets. - Vercel production and preview deployments receive distinct inferred namespaces. Set
CRUX_RUNTIME_NAMESPACEornamespacewhen you need a custom partition; non-Vercel production deployments must set one orserverless()throwsNAMESPACE_AMBIGUOUS. - Keep
retention.idempotencyKeysat least as long as QStash's max wake delay, or set it tofalse. - Regenerate artifacts in CI and fail builds on
ARTIFACTS_STALE. - Inspect stuck work with
crux runtime inspect <workId>; retry blocked/dead-letter work withcrux runtime retry <workId>after fixing the cause.
Related
- Reference: Runtime Engine
- Reference: @use-crux/postgres
- Reference: @use-crux/upstash