Skip to content

Cloudflare Workers: Not Lambda, Not Containers — It's V8 Isolates

Mar 27, 2026 1 min
TL;DR Cloudflare Workers uses V8 Isolates instead of containers — no cold starts, global edge deployment, and direct access to D1, R2, KV, and AI via Bindings. Great for APIs, SSR, and lightweight backends; not suited for long-running tasks.

🌏 中文版

Cloudflare Workers is often compared to AWS Lambda, but the two have fundamentally different architectures. Lambda runs in containers; Workers runs in V8 Isolates. That single difference shapes everything.

V8 Isolates vs. Containers

Lambda’s cold start problem is essentially the cost of container startup: pulling an image, allocating resources, booting the runtime — best case a few hundred milliseconds, worst case several seconds.

Workers uses V8 Isolates — the same engine that runs JavaScript in Chrome. Isolates are memory-isolated from each other but share the same V8 engine, so there’s no new process or container to spin up. Startup time sits between 0–5ms. When Cloudflare claims “no cold starts,” it’s not marketing — it’s architecturally true.

The other key difference is where code runs. Lambda executes in the AWS region you choose; Workers is automatically deployed to Cloudflare’s 300+ global PoPs. A request from Taiwan gets handled at a nearby edge node — no round-tripping across the globe.

Limitations Up Front

Workers isn’t a silver bullet. The constraints are hard:

  • CPU time: 10ms on the free tier, 30ms on paid (extendable to 5 minutes via ctx.waitUntil())
  • Memory: 128MB per Worker
  • Request duration: 30 seconds max per request (subrequests have separate limits)
  • No native Node.js APIs: fs, net, child_process are unavailable — though most pure-JS packages work fine
  • Not for long-running work: batch jobs, scheduled crawlers, video transcoding are all poor fits

The Workers runtime is built on the Service Worker API plus a subset of Web APIs — it’s not a full Node.js environment. Some Node.js built-ins like node:crypto and node:buffer are available via compatibility flags, but you have to explicitly opt in.

The Simplest Possible Worker

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const url = new URL(request.url);

    if (url.pathname === "/") {
      return new Response("Hello from the edge", { status: 200 });
    }

    return new Response("Not found", { status: 404 });
  },
};

env is where Bindings come in — more on that below.

Building an API with Hono

Writing a full API with raw fetch handlers gets tedious fast — you end up rolling your own routing. Hono is a Web framework designed specifically for edge runtimes: tiny bundle size, native support for the Workers API.

import { Hono } from "hono";
import { cors } from "hono/cors";

type Bindings = {
  DB: D1Database;
  KV: KVNamespace;
  AI: Ai;
};

const app = new Hono<{ Bindings: Bindings }>();

app.use("*", cors());

app.get("/api/posts", async (c) => {
  const posts = await c.env.DB.prepare(
    "SELECT id, title, created_at FROM posts ORDER BY created_at DESC LIMIT 20"
  ).all();

  return c.json(posts.results);
});

app.post("/api/posts", async (c) => {
  const body = await c.req.json<{ title: string; content: string }>();

  const result = await c.env.DB.prepare(
    "INSERT INTO posts (title, content) VALUES (?, ?)"
  )
    .bind(body.title, body.content)
    .run();

  return c.json({ id: result.meta.last_row_id }, 201);
});

export default app;

c.env gives you type-safe access to your Workers Bindings, with full IDE autocomplete.

The wrangler CLI

wrangler is Cloudflare’s official developer tool, covering everything from project initialization to production deployment.

# Install
npm install -g wrangler

# Authenticate
wrangler login

# Local development (simulates the Workers environment)
wrangler dev

# Deploy
wrangler deploy

# Stream live logs
wrangler tail

wrangler dev starts a local server that simulates the Workers runtime. Bindings (D1, KV, R2) can point to either local emulators or real Cloudflare resources — switch between them with --remote.

wrangler.toml is your configuration file:

name = "my-api"
main = "src/index.ts"
compatibility_date = "2024-01-01"

[[d1_databases]]
binding = "DB"
database_name = "my-db"
database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

[[kv_namespaces]]
binding = "KV"
id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

[ai]
binding = "AI"

The Bindings System

Bindings are how Workers connects to Cloudflare services. They’re injected via the env object — no API keys required, no network overhead (inside a Worker, a Binding is a direct runtime connection).

Key Bindings:

BindingPurpose
D1DatabaseSQLite relational database
KVNamespaceKey-value store, ideal for caching
R2BucketObject storage, S3-compatible
AiWorkers AI — embeddings and LLMs
QueueMessage queue for async job processing
DurableObjectNamespaceStateful single-instance objects
FetcherService binding to call another Worker

Cloudflare KV is eventually consistent — global reads are fast but writes have propagation delay. Cloudflare R2 is the right choice for static assets and user-uploaded media, with no egress fees.

Pricing

Free tier:

  • 100,000 requests per day
  • CPU time: 10ms per request
  • KV, D1, and R2 each include a free usage quota

Paid tier (Workers Paid, $5/month):

  • 10,000,000 requests per month (additional at $0.30 per million)
  • CPU time raised to 30ms, extendable
  • Significantly higher D1, KV, and R2 quotas

The free tier covers most side projects and small-to-medium applications. At $5/month, Workers Paid is one of the cheapest serverless options in the industry — equivalent Lambda + API Gateway setups cost considerably more.

How NobodyClimb Uses Workers

NobodyClimb runs its entire backend on Workers with no traditional server:

  • Web SSR: Next.js 15 deployed to Workers via @opennextjs/cloudflare — dynamic routes handled by Workers, static assets served via Cloudflare Assets
  • API: A Hono Worker connected to D1 (user data, climbing records) and KV (caching, rate limiting)
  • AI: The RAG Pipeline also runs in Workers — embeddings and LLM calls go through env.AI via Workers AI

The core reasoning: a climbing community platform has unpredictable traffic. Running a persistent server wastes money when traffic is low. Workers bills per request — idle time costs nothing, and when traffic spikes, it responds fast from the nearest edge node worldwide.

When to Use Workers — and When Not To

Good fits for Workers:

  • REST APIs, GraphQL endpoints
  • SSR with Next.js, Nuxt, or similar adapters
  • Edge middleware (auth, redirects, A/B testing)
  • Webhook handlers
  • Lightweight scheduled tasks (via Cron Triggers)

Poor fits for Workers:

  • Tasks running longer than 30 seconds (video processing, large batch jobs)
  • Heavy CPU-bound workloads (ML training, image processing)
  • Packages that depend on native Node.js APIs (some database drivers, native addons)
  • Persistent WebSocket connections (Durable Objects can help, but complexity increases)
  • Anything requiring a local filesystem (fs is unavailable)

Compared to traditional VPS or container setups: Workers trades execution flexibility (time limits, memory caps, API restrictions) for zero infrastructure management, global deployment, and very cheap billing. If your application fits within those constraints, Workers is an excellent choice. If it doesn’t, use containers.

References