Conrad Cloudflare

Workers and the runtime

Workers versus containers, V8 isolates and why there are practically no cold starts, the workerd runtime and nodejs_compat, what cannot run on a Worker, service bindings, and Zero Trust instead of a VPN.

From the Workers, workerd, V8 isolates, bindings and Zero Trust parts of your Cloudflare note.

Know

  • Serverless: deploy and Cloudflare runs the code in all its locations and scales it; you give up control and get limits instead (about 128 MB per isolate, CPU time per request, no long-lived process).
  • Isolates: separate V8 heaps and globals inside one shared workerd process, thousands per machine; starting one takes milliseconds, so practically no cold starts.
  • workerd: V8 for JavaScript, web standard APIs (fetch, Request, Response, URL, streams, Web Crypto), bindings to Cloudflare services.
  • nodejs_compat: native implementations of node:buffer, node:crypto, node:stream, node:events, AsyncLocalStorage and more; child_process and worker_threads only stubbed; fs is virtual. Nitro's preset fills other gaps with unenv polyfills.
  • Bindings: the Worker's handles to KV, D1, R2, Queues and other Workers, configured in Wrangler, with no keys in the code; service bindings and RPC call another Worker without a network hop.
  • Snippets: tiny edge functions on matching requests (about 5 ms, 2 MB memory, 32 KB code, no bindings) for headers, cookies to headers, JWT checks, redirects, blocking; a Worker as soon as storage or other services are involved.
  • Zero Trust: every request to an internal app is checked against identity and policy, servers connect out through a tunnel, no VPN client.

Fact check of your notes

Gotcha· The stubs come from the runtime and unenv

"Stubbed by Nitro": some of the stubs are in workerd itself, which ships placeholder modules like node:child_process that throw when called, and Nitro's Cloudflare preset adds polyfills from unenv for the rest. Either way, the import works and the call does not.

Exercise

Exercise
  • Create a Worker with nodejs_compat, use node:crypto and Buffer, then try child_process and read the error from wrangler dev.
  • Connect two Workers with a service binding and call a method over RPC; compare the timing with a fetch to the other Worker's public URL.

Be able to say

Be able to say· Why do Workers have practically no cold starts?

"Because a Worker isn't a container or a process. It's a V8 isolate: its own heap and global scope inside a workerd process that is already running with thousands of others. Starting one means creating an isolate and loading a small script, a few milliseconds, instead of booting Node and an app. The trade-off is a tighter box: limited memory and CPU per request, and nothing that lives between requests."

Your notes

Open in Notes

Nothing yet. Notes filed here show up on this page and the section overview.