BuildBot

Compute at the Edge

The Workers runtime

Lesson 1 of 5

What you'll learn

  • Write a module Worker: an export default object with an async fetch handler
  • Use the web-standard Request, Response, and URL types the runtime is built on
  • Explain why V8 isolates give Workers near-zero cold starts

A Cloudflare Worker is JavaScript that runs in Cloudflare's data centers — hundreds of cities, so your code executes a few milliseconds from whoever made the request. The modern shape is the module Worker: you export an object with an async fetch method, and the platform calls it once per incoming request.

export default {
  async fetch(request, env, ctx) {
    const url = new URL(request.url);
    if (url.pathname === "/api/hello") {
      return Response.json({ hello: "edge" });
    }
    return new Response("Not found", { status: 404 });
  },
};

Compare that to the Node server you already know, where you own the socket and the process:

// The Node way: you create the server and keep it alive.
import express from "express";
const app = express();
app.get("/api/hello", (req, res) => res.json({ hello: "node" }));
app.listen(3000);

Workers invert this. There is no listen, no port, no long-lived process you manage. You export a handler; Cloudflare owns the network. Your fetch receives a Request and must return (or resolve to) a Response — the exact same classes the browser's fetch() uses, plus URL, Headers, streams, and crypto.subtle. There is no req/res pair of mutable objects, and by default no Node APIs at all: the API surface is the web standard.

Isolates, not containers

Traditional serverless (Lambda-style) boots a container or microVM per instance of your function — hundreds of milliseconds to seconds of cold start, paid on the first request. Workers instead run inside V8 isolates: lightweight sandboxes within one already-running runtime process, the same mechanism Chrome uses to keep tabs apart. Starting an isolate means evaluating your script in a process that's already warm — typically under five milliseconds, often overlapped with the TLS handshake, so in practice cold starts round to zero. Thousands of isolates share a single process, which is also why a Worker gets a small memory footprint (128 MB) rather than a whole machine.

Web standards are the point

Because the API is fetch/Request/Response, Worker code is largely portable across Workers, Deno, Bun, and Node 18+ (which ships the same globals). That's exactly why this course's challenges run as-is: a Worker is a plain object with a fetch method, and anything can call it.

The challenge below is a Worker, minus the deploy: we play the platform's role, constructing Request objects and calling fetch ourselves.

Be the platform: invoke a Worker by hand

Run it. The worker object is a real module-Worker handler; the loop below plays Cloudflare's role, calling fetch once per request and printing each Response. Add a new route and hit it.

Loading editor…
Knowledge check

Why do Workers cold-start in single-digit milliseconds?

Next: wrangler — the config file, the local dev loop, and bindings, the concept the whole platform hangs on.

Saved on this device. Sign in to sync your progress everywhere.