apps/docs/content/troubleshooting/edge-functions-worker-timeouts-and-websocket-drops.mdx
Edge Functions run inside V8 isolates managed by a supervisor in edge-runtime.
The supervisor enforces resource limits:
worker_timeout_ms)It may retire early (EarlyDrop event) if the isolate is idle Isolate is considered idle if following conditions are met:
EdgeRuntime.waitUntil() promises have resolved.If both are true during a resource check, the isolate can be terminated even with open WebSocket connections.
EarlyDrop or wall clock warning events.After Deno.upgradeWebSocket(req) returns a response, the HTTP request is considered acknowledged. If there is no unresolved waitUntil work, the worker may look idle and be retired early.
EarlyDrop around disconnect time.EdgeRuntime.waitUntil() promise tied to socket lifecycle.Keep a promise pending until the socket closes.
Deno.serve((req) => {
const { socket, response } = Deno.upgradeWebSocket(req)
const socketClosedPromise = new Promise<void>((resolve) => {
socket.onclose = () => resolve()
})
EdgeRuntime.waitUntil(socketClosedPromise)
socket.onmessage = (event) => {
socket.send(event.data)
}
return response
})
EdgeRuntime.waitUntil() prevents early retirement, but it does not extend the hard wall clock limit.
546 or cancellation errors.The function exceeded the configured wall clock budget.
pg_net, pgmq, or webhooks) for chunked processing.CPU budget and wall clock budget are independent. A function can run out of CPU time long before wall clock is exhausted.
[DONE] token or normal close marker.The worker hits wall clock or early retirement conditions while forwarding a long stream.
Keep the isolate alive for the stream piping lifecycle:
Deno.serve(async (_req) => {
const upstream = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${Deno.env.get('OPENAI_API_KEY')}`,
},
body: JSON.stringify({ stream: true }),
})
const { readable, writable } = new TransformStream()
EdgeRuntime.waitUntil(upstream.body!.pipeTo(writable))
return new Response(readable, {
headers: { 'Content-Type': 'text/event-stream' },
})
})
504 or worker creation timeout).Large dependency trees or expensive top-level initialization can exceed startup budget.
await work.EarlyDrop: early retirement when worker appears idle.WallClockTime: hard runtime ceiling reached.