--- id: 'function-background-tasks' title: 'Background Tasks' description: 'How to run background tasks in an Edge Function outside of the request handler' subtitle: 'Run background tasks in an Edge Function outside of the request handler.' --- Edge Function instances can process background tasks outside of the request handler. Background tasks are useful for asynchronous operations like uploading a file to Storage, updating a database, or sending events to a logging service. You can respond to the request immediately and leave the task running in the background. This allows you to: - Respond to users while processing continues - Handle async operations without blocking the response --- ## Overview You can use `EdgeRuntime.waitUntil(promise)` to explicitly mark background tasks. The Function instance continues to run until the promise provided to `waitUntil` completes. ```ts import { withSupabase } from 'npm:@supabase/server@^1' // Mark the asyncLongRunningTask's returned promise as a background task. // ⚠️ We are NOT using `await` because we don't want it to block! EdgeRuntime.waitUntil(asyncLongRunningTask()) export default { fetch: withSupabase({ auth: 'user' }, async (req, ctx) => { return Response.json({ ok: true }) }), } ``` You can call `EdgeRuntime.waitUntil` in the request handler too. This will not block the request. ```ts import { withSupabase } from 'npm:@supabase/server@^1' export default { fetch: withSupabase({ auth: 'user' }, async (req, ctx) => { // Won't block the request, runs in background. EdgeRuntime.waitUntil(asyncLongRunningTask()) return Response.json({ ok: true }) }), } ``` You can listen to the `beforeunload` event handler to be notified when the Function is about to be shut down. ```tsx import { withSupabase } from 'npm:@supabase/server@^1' EdgeRuntime.waitUntil(asyncLongRunningTask()) // Use beforeunload event handler to be notified when function is about to shutdown addEventListener('beforeunload', (ev) => { console.log('Function will be shutdown due to', ev.detail?.reason) // Save state or log the current progress }) export default { fetch: withSupabase({ auth: 'user' }, async (req, ctx) => { return Response.json({ ok: true }) }), } ``` ## Handling errors We recommend using `try`/`catch` blocks within your background task function to handle errors. You can also add an event listener to [`unhandledrejection`](https://developer.mozilla.org/en-US/docs/Web/API/Window/unhandledrejection_event) to handle any promises without a rejection handler. ```tsx addEventListener('unhandledrejection', (ev) => { console.log('unhandledrejection', ev.reason) ev.preventDefault() }) ``` The maximum duration is capped based on the wall-clock, CPU, and memory limits. The function will shut down when it reaches one of these [limits](/docs/guides/functions/limits). --- ## Testing background tasks locally When testing Edge Functions locally with Supabase CLI, the instances are terminated automatically after a request is completed. This will prevent background tasks from running to completion. To prevent that, you can update the `supabase/config.toml` with the following settings: ```toml [edge_runtime] policy = "per_worker" ```