Skip to content
VercelLogotypeVercelLogotype
LoginSign Up

Rust Wait Until

Run background work after the response is sent using waitUntil in the Vercel Rust runtime.

DeployView Demo

Rust waitUntil

This example demonstrates waitUntil support in the Vercel Rust runtime (vercel_runtime 2.4.0+). waitUntil lets you schedule background work that keeps running after the HTTP response has already been sent to the client — the Rust analog of waitUntil in the Node.js runtime.

This is ideal for fire-and-forget side effects the client shouldn't have to wait for, such as flushing analytics, warming a cache, sending a webhook, or writing to a database.

Here, every request to /api/wait-until records itself — timestamp, method, user agent, and the visitor's country (with a flag emoji) — into Upstash Redis after the response is sent. The front-end then reads the last 10 records from /api/recent.

The country comes from Vercel's x-vercel-ip-country request header (an ISO 3166-1 alpha-2 code injected at the edge), which is converted to a flag emoji in country_to_flag. The IP itself is never stored.

How it works

api/wait-until.rs defines a handler that receives the runtime's AppState. AppState::wait_until registers a future that is:

  1. Spawned immediately, so it makes progress between requests.
  2. Decoupled from the response — the handler returns right away and the client gets its response without waiting for the background task.
  3. Drained at process shutdown (bounded by a 30s timeout), matching the Node.js runtime's behavior. A panic in the background task is isolated and never affects the response or other background work.
// Capture request details before moving into the background task.
let record = json!({ "timestamp": ts, "method": method, "userAgent": ua, "country": country, "flag": flag });
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 write uses the Upstash REST /pipeline endpoint to run LPUSH followed by LTRIM key 0 9, keeping only the 10 most recent records (newest first).

api/recent.rs reads them back with LRANGE key 0 9 using the read-only token and returns them as JSON for the front-end to render.

Data flow

  1. GET /api/wait-until → responds immediately, schedules the Redis write via waitUntil.
  2. Background task → LPUSH + LTRIM to Upstash (write token).
  3. GET /api/recent → LRANGE the last 10 records (read-only token).
  4. index.html → "Fire a request", then renders the recent list.

Logging from background work

The example logs from the background task with println!/eprintln! (stdout/stderr) rather than the request-scoped state.log_context. This is intentional:

  • log_context attaches each line to the current invocation's id.
  • The runtime sends the per-request end message as soon as the handler returns the response, which closes that invocation's log stream.
  • waitUntil work is drained later (at process shutdown, bounded by a 30s timeout). By then the originating request context is closed, so a log_context line emitted from the background task would not be attributed to the request and may be dropped.

stdout/stderr is captured independently of request context, so it reliably shows up in the function logs — making the background work observable. Use log_context for synchronous, in-handler logging and println!/eprintln! (or an external sink like a database/Blob) for waitUntil work.

Project Structure

  • api/wait-until.rs — records the request to Upstash in the background via waitUntil
  • api/recent.rs — reads the last 10 records back with the read-only token
  • index.html — fires requests and renders the recent list
  • Cargo.toml — Rust dependencies and binary configuration
  • vercel.json — Vercel project configuration

Environment variables

This example uses an Upstash Redis (Vercel KV) database. Add the integration from the Vercel dashboard, or set these variables on your project:

VariableUsed byPurpose
KV_REST_API_URLboth endpointsUpstash REST base URL
KV_REST_API_TOKEN/api/wait-untilRead/write token (writes records)
KV_REST_API_READ_ONLY_TOKEN/api/recentRead-only token (reads records)

For local development, copy these into a .env.local file (gitignored).

Development

Clone the repository:

git clone https://github.com/vercel/examples.git
cd examples/rust/wait-until

Install Rust if you haven't already:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Pull your project's environment variables (or create .env.local manually):

vercel env pull .env.local

Test locally:

vc dev

Open the printed URL, click Fire a request, and watch the recent list update. The response returns instantly while the record is written to Upstash in the background.

GitHub
Ownervercel
Repositoryexamples
LicenseView License
Use Cases
Backend
Stack
Axum
Database
Upstash

Related Templates

eve Chat Template

A persisted Next.js chat template for eve, built with shadcn/ui, Tailwind CSS, Streamdown, Better Auth, Drizzle, and Neon.
eve Chat Template thumbnail

Next.js Boilerplate

Get started with Next.js and React in seconds.
Next.js Boilerplate thumbnail

Image Gallery Starter

An image gallery built on Next.js and Vercel Blob.
Image Gallery Starter thumbnail

Agent Stack

  • AI SDK
  • AI Gateway
  • Sandbox
  • Workflows
  • ConnectNew
  • PassportNew
  • eveNew

Core Platform

  • CI/CD
  • Content Delivery
  • Fluid Compute
  • Observability

Security

  • Platform Security
  • WAF
  • Bot Management
  • Bot ID

Tools

  • Vercel DropNew
  • Vercel Agent
  • Vercel PluginNew
  • Agent Skills
  • Next.js
  • Domains
  • v0

Frameworks

  • eveNew
  • Nuxt
  • SvelteKit
  • Nitro
  • Turborepo
  • Tanstack Start
  • FastAPI
  • xmcp
  • All frameworks

SDKs

  • Vercel SDK
  • Workflow SDKNew
  • Flags SDK
  • Chat SDKNew
  • Queues SDKNew
  • Streamdown

Build

  • AI Apps
  • Web Apps
  • Marketing Sites
  • Platforms
  • Commerce
  • Platform Engineers
  • Design Engineers

Learn

  • Docs
  • Blog
  • Changelog
  • Knowledge Base
  • Academy
  • Articles
  • Community

Explore

  • Customers
  • Marketplace
  • Templates
  • Partner Finder
  • Vercel + AWS

Company

  • About
  • Careers
  • Press
  • Events
  • Startups
  • Shipped on Vercel
  • Open Source Program
  • Enterprise
  • Pricing
  • Help

Legal & Trust

  • Privacy Policy
  • Terms of Service
  • Cookie Policy
  • DPA
  • Acceptable Use Policy
  • Legal (all documents)
  • Trust Center
  • Status

Social

  • GitHub
  • X
  • LinkedIn
  • YouTube
  • Instagram
  • VercelVercel
Agent Stack
  • AI SDK
  • AI Gateway
  • Sandbox
  • Workflows
  • Passport
  • eve
Core Platform
  • Security
  • Content Delivery
  • Fluid Compute
  • Observability
  • CI/CD
Tools
  • Next.js
  • Vercel Agent
  • Vercel Plugin
  • Domains
  • v0
Learn
  • Docs
  • About
  • Blog
  • Changelog
  • Knowledge Base
Build
  • AI Apps
  • Web Apps
  • Marketing Sites
  • Platforms
  • Commerce
Explore
  • Customers
  • Marketplace
  • Partner Finder
  • AWS
  • Community
EnterprisePricing
Contact
Log InSign Up
Dashboard

Products

Agent Stack

  • AI SDK
  • AI Gateway
  • Sandbox
  • Workflows
  • Passport
  • eve

Core Platform

  • Security
  • Content Delivery
  • Fluid Compute
  • Observability
  • CI/CD

Tools

  • Next.js
  • Vercel Agent
  • Vercel Plugin
  • Domains
  • v0
Resources

Learn

  • Docs
  • About
  • Blog
  • Changelog
  • Knowledge Base

Build

  • AI Apps
  • Web Apps
  • Marketing Sites
  • Platforms
  • Commerce

Explore

  • Customers
  • Marketplace
  • Partner Finder
  • AWS
  • Community
Enterprise
Pricing
Sign UpLog In
Contact
DeployView Demo

Loading status…

Select a display theme: