Skip to content
Agent Stack
  • AI SDK
  • AI Gateway
  • Sandbox
  • Passport
  • Connect
  • eve
Core Platform
  • Security
  • Content Delivery
  • Fluid Compute
  • Observability
  • Workflows
  • CI/CD
Tools
  • Next.js
  • Edgenivo Agent
  • Edgenivo Plugin
  • Open Source
  • 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
  • Passport
  • Connect
  • eve
Core Platform
  • Security
  • Content Delivery
  • Fluid Compute
  • Observability
  • Workflows
  • CI/CD
Tools
  • Next.js
  • Edgenivo Agent
  • Edgenivo Plugin
  • Open Source
  • 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
Templates
Template name

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
  • BotID

Tools

  • Edgenivo Drop
  • Edgenivo Agent
  • Edgenivo Plugin
  • Agent Skills
  • Domains
  • v0

Frameworks

  • eveNew
  • Next.js
  • Nuxt
  • SvelteKit
  • Nitro
  • Turborepo
  • Tanstack Start
  • FastAPI
  • All frameworks

SDKs

  • Edgenivo SDK
  • Workflow SDK
  • Flags SDK
  • Chat SDK
  • Queues SDK
  • Streamdown

Build

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

Learn

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

Explore

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

Company

  • About
  • Careers
  • Press
  • Events
  • Startups
  • Shipped on Edgenivo
  • 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
  • EdgenivoEdgenivo
Templates
Template name

Status service pending confirmation

Select a display theme:
Templates

Rust Wait Until

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

DeployView Demo
Owner
  • vercel
Repository
  • examples
Use Cases
  • Backend
Stack
  • Axum
Database
  • Upstash
DeployView Demo

Rust waitUntil

This example demonstrates waitUntil support in the Edgenivo 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 Edgenivo'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 — Edgenivo project configuration

Environment variables

This example uses an Upstash Redis (Edgenivo KV) database. Add the integration from the Edgenivo 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.

License
  • View License