Architecture
OpenWorkers runs JavaScript and TypeScript workers in V8 isolates. This section documents the internal architecture for contributors and auditors.
Components
┌──────────────────────────────────────────────────────────────────┐
│ Dashboard │
│ (served by the API worker) │
└───────────────────────────┬──────────────────────────────────────┘
│ │
REST SSE
│ │
▼ ▼
┌──────────────────────────────────────────┐ ┌─────────────────┐
│ API │ │ Logs │
│ (TypeScript, runs as a worker) │ │ (Rust) │
│ User-facing REST API, CRUD operations │ │ │
└──────────────────────────────────────────┘ │ - NATS → DB │
│ │ - SSE streaming │
▼ └─────────────────┘
┌──────────────────────────────────────────┐ │
│ Postgate │ │
│ (Rust) │ │
│ PostgreSQL proxy, row-level security │ │
└──────────────────────────────────────────┘ │
│ │
▼ ▼
┌──────────────────────────────────────────────────────────────────┐
│ PostgreSQL │
│ Workers, environments, bindings, users, logs │
└──────────────────────────────────────────────────────────────────┘
│ │ │
│ │ │
▼ ▼ ▼
┌─────────────────────────────┐ ┌───────────┐ ┌───────────┐
│ Runner │◄──│ Scheduler │ │ CLI │
│ (Rust) │ │ (Rust) │ │ (Rust) │
│ │ │ │ │ │
│ ──► HTTP requests │ │ │ │ │
│ ──► Scheduler signal │ │ Watches │ │ Infra/ │
│ ┌────────────────────────┐ │ │ crons │ │ admin │
│ │ V8 Runtime │ │ │ │ │ │
│ │ Isolates, Web APIs, │ │ │ NATS │ │ │
│ │ native bindings │ │ │ events │ │ │
│ └────────────────────────┘ │ └───────────┘ └───────────┘
└─────────────────────────────┘ Key Principles
1. Workers Never See Credentials
Bindings inject resources without exposing secrets. The runner authenticates requests server-side.
Worker: env.STORAGE.get('file.txt')
↓
Runner: Look up binding config → Sign S3 request → Execute → Return data
↓
Worker: Receives file content (never sees S3 credentials) 2. Isolate-Based Sandboxing
Each worker runs in a V8 isolate with:
- Memory limits
- CPU time limits
- No filesystem access
- No network access except via bindings
3. Single Source of Truth
PostgreSQL is the single source of truth. All components read from/write to the same database. No local state.
4. CLI is the Only Infra Tool
The API runs as a worker on the platform (dogfooding). If the platform is down, the API is down. All infrastructure operations go through the CLI with direct DB access.
5. Logs via NATS
Workers emit logs via console.log. The flow:
- Worker calls
console.log('message') - Runner publishes to NATS (
logs.<worker_id>) - Logs service subscribes, writes to PostgreSQL
- Dashboard connects via SSE for live streaming
This decouples log ingestion from request handling.
6. Unified Database Access via Postgate
Postgate is a PostgreSQL HTTP proxy with token-based authentication. It serves two purposes:
- API access — The OpenWorkers API uses Postgate HTTP to query the platform database
- Worker bindings — The runner uses Postgate as a library for
env.DB.query()calls
Both share the same database and token system via PostgreSQL views:
┌─────────────────────────────────────────────────────────────────┐
│ PostgreSQL │
├─────────────────────────────────────────────────────────────────┤
│ database_configs │ database_tokens │
│ ───────────────── │ ──────────────── │
│ - API database │ - API token │
│ - User databases │ - User tokens (future) │
│ ▲ │ ▲ │
│ │ │ │ │
│ ┌──────┴──────────────────┴─────────┴───────┐ │
│ │ Postgate Views │ │
│ │ postgate_databases ←→ database_configs │ │
│ │ postgate_tokens ←→ database_tokens │ │
│ └───────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘ This architecture means:
- Single database — No separate Postgate database needed
- Unified tokens — Same system for API and user databases
- Future: HTTP access for users — User databases will be accessible via Postgate HTTP (for debugging, migrations, CI/CD)
Dogfooding
The API runs as a worker on OpenWorkers, and serves the dashboard UI:
- Same deployment model as user workers
- The CLI stays the only infra tool, for recovery when the platform is down
Deep Dives
| Topic | Description |
|---|---|
| Bindings | How bindings work internally |
| HTTP Flow | Request/response flow, streaming support |
| Event Loop | V8 ↔ Rust async communication |
| Stream Cancellation | Client disconnect during streaming |
| Security | Isolation, limits, threat model |
Source Code
OpenWorkers is open source. Contributions welcome!
| Repository | Description |
|---|---|
| openworkers-runner | Core runtime, executes workers |
| openworkers-runtime-v8 | V8 isolate integration |
| openworkers-core | Shared types and operations |
| openworkers-api | REST API and dashboard (TypeScript) |
| openworkers-scheduler | Cron job execution |
| openworkers-logs | Log ingestion (NATS → DB) and SSE streaming |
| openworkers-cli | Admin/infra tool |
| postgate | PostgreSQL proxy for DB bindings |
| openworkers-infra | Docker Compose setup for self-hosting |