Wait Until
waitUntil lets you run async work after the response has been sent. The worker stays alive until all registered tasks complete — even during scale-down or redeployment.
Use it for work that doesn't need to block the response: logging, analytics, cache updates, notifications.
Usage
import { waitUntil } from "@alienplatform/sdk"
app.post("/api/checkout", async (c) => {
const order = await processOrder(c.req)
waitUntil(
(async () => {
await analytics.track("order.completed", { orderId: order.id })
await cache.invalidate(`user:${order.userId}:orders`)
})()
)
return c.json({ orderId: order.id, status: "confirmed" })
})The response returns immediately. The background task runs to completion in the same process.
API
function waitUntil(promise: Promise<unknown>): voidPass an already-started promise. The runtime tracks it and keeps the worker alive until it resolves or rejects.
Errors inside the promise are logged to stderr. They don't affect the response (it was already sent).
Lifecycle
- Your handler calls
waitUntil. The task starts running immediately. - The response is sent to the caller.
- The worker instance stays alive while tasks are pending.
- During graceful shutdown (scale-down, redeployment), the runtime waits for all tasks to finish before terminating.
You can call waitUntil multiple times in a single request. Each task is tracked independently — a failure in one doesn't cancel others.
When to Use
Good fit: logging, analytics, cache invalidation, sending notifications, writing audit trails, cleanup.
Not a good fit: work that must succeed before the user sees a result. If you're charging a credit card or writing a critical database record, do it before sending the response.