# How Cloudflare OS Uses Cloudflare Workers: A Modular Full-Stack Architecture

> Discover how Cloudflare OS leverages Cloudflare Workers for a modular full-stack architecture. Explore its Router, Backend, and Gatekeeper Workers for efficient system design.

- Repository: [Cloudflare/cloudflare-os](https://github.com/cloudflare/cloudflare-os)
- Tags: architecture
- Published: 2026-09-04

---

**Cloudflare OS is built entirely as a distributed system of Cloudflare Workers, using a Router Worker for traffic distribution, a Workshop Backend Worker for core logic and RPC, isolated Gatekeeper Workers for third-party integrations, and Durable Objects for persistent state management.**

Cloudflare OS implements a full-stack "gadget" platform where every architectural layer runs as a Cloudflare Worker. According to the cloudflare/cloudflare-os source code, the system leverages **service bindings**, **Durable Objects**, and a custom **Cap'n Web RPC** protocol to create a modular, secure, and scalable serverless architecture.

## Architecture Overview

The platform consists of specialized Workers orchestrated through environment bindings defined in [`worker-configuration.d.ts`](https://github.com/cloudflare/cloudflare-os/blob/main/worker-configuration.d.ts) files. The **Router Worker** serves as the public entry point, while the **Workshop Backend Worker** handles core application logic. Third-party capabilities are isolated in **Gatekeeper Workers**, and state persists in **Durable Objects** accessed via RPC stubs.

## The Router Worker: Traffic Distribution

Located at [`packages/router/src/index.ts`](https://github.com/cloudflare/cloudflare-os/blob/main/packages/router/src/index.ts), the Router Worker handles all incoming HTTP traffic and dispatches requests using **service bindings**. It dynamically discovers Gatekeeper Workers by scanning environment variables prefixed with `GATEKEEPER_`, normalizing the suffix to URL-friendly paths.

### Dynamic Gatekeeper Discovery

The Router inspects `req.url` and forwards requests to the appropriate backend service. For paths starting with `/gatekeeper/<name>`, it routes to the corresponding service binding. API and blueprint paths route to the Workshop Backend.

```typescript
// packages/router/src/index.ts
for (const key of Object.keys(env)) {
  if (!key.startsWith("GATEKEEPER_")) continue;
  const suffix = key.slice("GATEKEEPER_".length).toLowerCase().replaceAll("_", "-");
  const prefix = `/gatekeeper/${suffix}`;
  if (url.pathname === prefix || url.pathname.startsWith(prefix + "/")) {
    // Forward the request to the gatekeeper service binding.
    return (env[key] as Fetcher).fetch(req);
  }
}

```

In development, when no `ASSETS` binding exists, the Router also proxies frontend requests to the backend for local testing.

## The Workshop Backend: Core Application Logic

The Workshop Backend Worker ([`packages/workshop-backend/src/server.ts`](https://github.com/cloudflare/cloudflare-os/blob/main/packages/workshop-backend/src/server.ts)) implements authentication, user management, gadget lifecycle operations, and analytics. It exposes a single `/api` endpoint that creates RPC sessions.

### RPC Over HTTP and WebSocket

The backend uses **Cap'n Web RPC** to provide low-overhead, promise-pipelined communication. It supports both HTTP-batch and WebSocket transports, with the latter enabling persistent connections for real-time gadget interactions.

```typescript
// packages/workshop-backend/src/server.ts
return await newWorkersRpcResponse(
  req,
  new PublicApiImpl(ctx, env, abortSession, accessPayload),
  { abortSignal: abortController.signal } // aborts the WS when the session ends
);

```

For WebSocket upgrades, the backend returns socket pairs and initializes `newWebSocketRpcSession` to maintain the connection.

### Durable Objects for State Management

State persists in **Durable Objects** like `UserDurableObject` and `OverseerDurableObject` (defined in [`packages/workshop-backend/src/overseer.ts`](https://github.com/cloudflare/cloudflare-os/blob/main/packages/workshop-backend/src/overseer.ts)). The backend creates unique IDs via `env.<DO_NAMESPACE>.newUniqueId()` and wraps stubs with telemetry.

```typescript
// packages/workshop-backend/src/server.ts (inside AuthenticatedApiImpl)
private get #user(): DurableObjectStub<UserDurableObject> {
  // Wrap the stub to add telemetry.
  return wrapDoStubForTelemetry(this.users.get(this.#userId));
}

```

The **OverseerDurableObject** represents workspaces and mediates gadget execution, while **UserDurableObject** maintains user-specific state.

## Gatekeeper Workers: Isolated Third-Party Integrations

Gatekeepers are separate Workers (e.g., [`packages/gatekeeper-zoominfo/src/zoominfo.ts`](https://github.com/cloudflare/cloudflare-os/blob/main/packages/gatekeeper-zoominfo/src/zoominfo.ts)) bound to the Router via `GATEKEEPER_<NAME>` service bindings. Each encapsulates specific external capabilities like OAuth flows or data APIs, running in isolation from the core platform.

When a gadget requires third-party access, the backend creates a gatekeeper stub through `overseerResult.newGatekeeper` and returns it to the client, which then communicates directly with the isolated Worker.

## Environment Configuration and Bindings

Workers obtain configuration, KV stores, R2 buckets, and inter-service references through typed `Env` interfaces. These are declared in each package's [`worker-configuration.d.ts`](https://github.com/cloudflare/cloudflare-os/blob/main/worker-configuration.d.ts) (e.g., [`packages/router/worker-configuration.d.ts`](https://github.com/cloudflare/cloudflare-os/blob/main/packages/router/worker-configuration.d.ts)) and accessed via the `env` argument in fetch handlers.

The shared type-only package `@gadgets/workshop-shared/api` (located in [`packages/workshop-shared/src/api.ts`](https://github.com/cloudflare/cloudflare-os/blob/main/packages/workshop-shared/src/api.ts)) defines the RPC interfaces (`PublicApi`, `AuthenticatedApi`, `AdminApi`) used across the system, with automatic validation via `@validateRpc` decorators.

## Summary

- **Router Worker** ([`packages/router/src/index.ts`](https://github.com/cloudflare/cloudflare-os/blob/main/packages/router/src/index.ts)) serves as the public entry point, dynamically routing traffic to Gatekeeper Workers or the Workshop Backend based on URL patterns and `GATEKEEPER_*` service bindings.
- **Workshop Backend** ([`packages/workshop-backend/src/server.ts`](https://github.com/cloudflare/cloudflare-os/blob/main/packages/workshop-backend/src/server.ts)) implements core logic using Cap'n Web RPC over HTTP and WebSocket, handling authentication and gadget lifecycle management.
- **Durable Objects** (`UserDurableObject`, `OverseerDurableObject`) provide persistent state storage, accessed via RPC stubs wrapped with telemetry utilities.
- **Gatekeeper Workers** run as isolated Cloudflare Workers for third-party integrations, discovered automatically by the Router through environment variable scanning.
- The platform uses **Cap'n Web RPC** for efficient, type-safe communication between clients and backend services.

## Frequently Asked Questions

### How does the Router Worker distribute traffic in Cloudflare OS?

The Router Worker inspects the `req.url` pathname and forwards requests based on routing rules. Paths matching `/gatekeeper/<name>` are forwarded to the corresponding `GATEKEEPER_*` service binding, while API routes go to the `WORKSHOP_BACKEND` binding. Static assets are served from the `ASSETS` binding in production.

### What role do Durable Objects play in Cloudflare OS?

Durable Objects like `UserDurableObject` and `OverseerDurableObject` persist user state, workspace state, and gatekeeper account information. They are instantiated using `env.<DO_NAMESPACE>.get(id)` and accessed via RPC stubs that automatically handle serialization and telemetry wrapping.

### How does Cloudflare OS handle real-time communication between clients and gadgets?

The platform uses **Cap'n Web RPC** with WebSocket upgrades. When a client connects, the Workshop Backend creates a WebSocket RPC session via `newWebSocketRpcSession`, providing a persistent channel for promise-pipelined RPC calls that remains active until the session ends.

### How are third-party integrations secured and isolated?

Third-party capabilities are encapsulated in **Gatekeeper Workers**—separate Cloudflare Workers that run in isolation and communicate only through defined service bindings. Each Gatekeeper handles its own OAuth flows and API interactions (e.g., [`packages/gatekeeper-zoominfo/src/zoominfo.ts`](https://github.com/cloudflare/cloudflare-os/blob/main/packages/gatekeeper-zoominfo/src/zoominfo.ts)), preventing external dependencies from affecting core platform stability.