Skip to main content
workerd is built on a modular architecture that separates concerns between configuration, worker execution, I/O management, and the JavaScript runtime.

Core components

Server layer

The server layer orchestrates the entire runtime and is defined in src/workerd/server/:
  • CliMain: Entry point that dispatches subcommands (serve, compile, test)
  • Server class: Central orchestrator that parses Cap’n Proto configuration, constructs services, and manages the event loop
  • WorkerdApi: Registers all JavaScript API types and compiles worker modules

Worker lifecycle

Workers progress through several stages managed by classes in src/workerd/io/:
  • Isolate: V8 isolate wrapper, shared across workers with identical configuration
  • Script: Compiled JavaScript/WebAssembly bound to an isolate
  • Worker: Worker instance that can handle multiple requests
  • Actor: Durable Object instance with persistent storage

I/O subsystem

The I/O layer bridges JavaScript promises with the KJ async framework:
  • IoContext: Per-request context object (“god object”) accessible via IoContext::current()
  • InputGate/OutputGate: Consistency primitives for Durable Object request ordering
  • ActorCache: Write-back LRU cache over storage operations
  • ActorSqlite: SQLite-backed storage implementation

JavaScript engine integration

The JSG (JavaScript Glue) layer in src/workerd/jsg/ provides:
  • Type wrappers between C++ and JavaScript
  • Promise handling and memory management
  • Module system implementation
  • Automatic garbage collection integration

Request flow

When a request arrives at workerd:
  1. Socket receives request: A configured socket (HTTP/HTTPS) receives the incoming request
  2. Service routing: The request is routed to the named service specified in the socket configuration
  3. Worker acquisition: An available worker instance is selected or created
  4. IoContext creation: A new per-request IoContext is established
  5. JavaScript execution: The worker’s fetch handler executes in V8
  6. I/O operations: Fetch calls, KV operations, and Durable Object calls flow through the I/O subsystem
  7. Response delivery: The Response object is serialized and sent back through the socket

Service types

workerd supports multiple service types beyond workers:

Worker service

Executes JavaScript/WebAssembly code in response to requests. See Workers.

Network service

Provides access to network resources with configurable allow/deny lists:
(name = "internet",
 network = (
   allow = ["public"],
   tlsOptions = (trustBrowserCas = true)
 ))

External server

Forwards requests to a specific remote server:
(name = "backend",
 external = (
   address = "internal.example.com:8080",
   http = ()
 ))

Disk directory

Exposes a local directory through an HTTP interface:
(name = "assets",
 disk = (
   path = "/var/www/static",
   writable = false
 ))

Configuration system

workerd uses Cap’n Proto text format for configuration. The schema is defined in src/workerd/server/workerd.capnp. A minimal configuration requires:
  • At least one service definition
  • At least one socket to expose services
  • For workers: compatibility date and source code
Example structure:
using Workerd = import "/workerd/workerd.capnp";

const config :Workerd.Config = (
  services = [(name = "main", worker = .myWorker)],
  sockets = [(
    name = "http",
    address = "*:8080",
    http = (),
    service = "main"
  )]
);

const myWorker :Workerd.Worker = (
  serviceWorkerScript = embed "worker.js",
  compatibilityDate = "2024-01-01"
);

Thread model

workerd currently runs in a single-threaded event loop:
  • All JavaScript execution is single-threaded
  • I/O operations are asynchronous and non-blocking
  • Multiple worker instances cannot execute simultaneously on the same isolate
  • To utilize multiple cores, run multiple workerd instances with load balancing
This architecture ensures:
  • No race conditions in JavaScript code
  • Predictable performance characteristics
  • Simple debugging and reasoning about execution

Dependencies

workerd builds on several core dependencies:
DependencyPurpose
V8JavaScript engine
Cap’n ProtoSerialization, RPC, and KJ base library
BoringSSLTLS and cryptography
SQLiteDurable Object storage backend
ICUInternationalization
These dependencies are vendored via Bazel and include custom patches maintained by the workerd team.

Memory management

workerd uses tcmalloc for memory allocation, providing:
  • Fast allocation for small objects
  • Reduced lock contention
  • Better memory utilization
The runtime also includes:
  • V8’s garbage collector for JavaScript heap
  • KJ’s reference counting for C++ objects
  • IoOwn/IoPtr smart pointers for cross-heap references

Build docs developers (and LLMs) love