Newsletter
Join the Community
Subscribe to our newsletter for the latest news and updates
Run background work after the response is sent using waitUntil in the Vercel Rust runtime.
Rust waitUntil is a Vercel starter template that demonstrates scheduling background work after the HTTP response is sent, using the waitUntil API in the Vercel Rust runtime (vercel_runtime 2.4.0+). It takes incoming requests to /api/wait-until, captures request metadata, writes it to Upstash Redis in the background, and returns the response immediately so the client never waits for the side effect.
Rust waitUntil is a reference implementation published by Vercel that shows how to use the waitUntil function in Rust serverless functions. It receives HTTP requests, extracts timestamp, method, user agent, and the visitor's country from the x-vercel-ip-country edge header, then schedules a Redis write via AppState::wait_until. The output is a JSON response to the client and a record stored in Upstash Redis containing the last 10 requests. It runs on Vercel's Rust runtime and is part of the official Vercel examples repository.
waitUntil API support — registers a future via AppState::wait_until that is spawned immediately, decoupled from the response, and drained at process shutdown with a 30-second timeout./pipeline endpoint to run LPUSH and LTRIM key 0 9, keeping only the 10 most recent records.KV_REST_API_TOKEN and reads use KV_REST_API_READ_ONLY_TOKEN, so read endpoints don't have write access.x-vercel-ip-country (ISO 3166-1 alpha-2) to display a flag emoji, without storing the visitor's IP.index.html fires a request and renders the last 10 records from /api/recent.api/wait-until.rs, api/recent.rs, Cargo.toml, and vercel.json for deployment configuration.Rust developers deploying to Vercel who want to offload non-critical work from the request path. Backend engineers learning how waitUntil behaves in the Rust runtime compared to Node.js. Teams using Upstash Redis (Vercel KV) who need a minimal example of background writes with read-only access for separate endpoints.
The handler in api/wait-until.rs builds a JSON record with timestamp, method, user agent, and country, then calls state.wait_until with an async closure that writes the record to Upstash. The runtime spawns the future immediately, returns the response to the client, and drains any pending work at shutdown within a 30-second budget. A separate endpoint /api/recent reads back the last 10 records using LRANGE.
state.wait_until(async move {
// Runs after the response has been sent. The client never waits for this.
if let Err(e) = store_request(&record).await {
eprintln!("[waitUntil] Failed to store request record: {e}");
}
});The example intentionally uses println!/eprintln! for logging from background tasks because log_context attaches to the request invocation, which closes when the response is sent. stdout/stderr are captured independently of request context, ensuring background logs appear in function logs.
The template requires vercel_runtime version 2.4.0 or higher for waitUntil support.
No. The background task is decoupled from the response — the handler returns immediately and the client receives the response without waiting for the Redis write to finish.
The panic is isolated and does not affect the response or other background work. Tasks are drained at process shutdown within a 30-second timeout.
Because log_context is tied to the current request invocation, which closes when the response is sent. println! and eprintln! are captured independently of request context, so they reliably appear in function logs.
Clone the Vercel examples repository, install Rust, run vercel env pull .env.local to fetch your environment variables, then start with vc dev and open the printed URL.
