Workers that outlive a request
Persistent JavaScript and TypeScript workers for queue processing, synchronization and periodic jobs, on an interval you control.
- Long-running processes
- Bundled from one entry file
- Live logs and memory visibility
Not bound to a request
A function is a background process, not a request handler with a timeout. Use it for queues, syncs and schedules you drive yourself.
One entry file
The CLI bundles local imports with esbuild. Export an async default function and pass secrets as environment variables.
Same isolation as applications
Rootless container, read-only root filesystem, dropped capabilities, hard memory limit. A worker is not a privileged citizen.
Failures are visible
Logs and memory use are in the dashboard. Exceed the hard limit and the kernel terminates the container; the restart policy retries up to five times.
Idempotency is your job
Processes restart. Claim work atomically with FOR UPDATE SKIP LOCKED and make handlers safe to run twice.
State belongs in Postgres
The container filesystem is read-only and ephemeral. Job state, cursors and checkpoints go into your database.
Write the loop you mean
Handle errors inside the loop and include a delay, otherwise a worker will happily consume a full CPU doing nothing useful. The platform will not guess an interval for you.
export default async function main() {
while (true) {
try {
await processNextBatch();
} catch (error) {
console.error(error);
}
await new Promise(resolve => setTimeout(resolve, 5000));
}
}Build the whole backend in one project
One plan, one dashboard, one command line interface. PostgreSQL, applications, functions, storage and realtime.