Getting started
Architecture
How OpenOrange runs your Cloudflare project: standard Docker containers in any cloud, scaled by the Rivet control plane, with state in S3.
OpenOrange is powered by Rivet, a scalable control plane that runs your Cloudflare workloads. Your code ships as standard Docker containers, so it runs anywhere Docker runs.
Any cloud AWS · Google Cloud · Azure · your servers
-
Docker container
-
Docker container
-
Docker container
Each holds your Workers, Durable Objects and the rest of your Cloudflare code, on Node.js.
Rivet control plane
Places each Actor on one of your containers, routes requests to it, and scales the load across them.
Open source · self-hosted, Rivet Cloud or BYOC
S3
Cheap, durable and scalable
- Your code, built into an image by
orange deploy - One Rivet Actor, such as a Durable Object
- Rivet
- Storage
Powered by Rivet, backed by S3
Rivet is an open-source control plane. Each Durable Object runs as a Rivet Actor: Rivet finds it, wakes it on one of your containers, and routes each request to it.
Rivet keeps state in S3, which is cheap, durable and scalable. Scaling out is a matter of adding machines. See Rivet Actors.
Standard Docker containers, in any cloud
orange deploy builds your Worker and the OpenOrange runtime into a standard
Docker image, so it runs anywhere Docker runs.
Each container holds your Workers, Durable Objects, Workflows and the rest of your Cloudflare code. The containers connect out to Rivet, which spreads the load across them. To add capacity, add containers.
Self-hosted is this architecture as drawn: you run the containers and Rivet. Rivet Cloud and BYOC run the same setup, operated by Rivet.
| Deploy to | Runs on |
|---|---|
| Self-hosted | Any cloud, Hetzner or on-prem |
| Rivet Cloud | A dedicated cluster on AWS or Google Cloud, in the region you choose |
| BYOC | Your AWS, Google Cloud or Azure account |
See Deploy and self-host.
Each binding maps to the best-fit service
Your bindings and your code stay the same. Stateful bindings run on Rivet Actors. The rest plug into services you already use.
-
The OpenOrange runtime, on Node.js
Your fetch handler and Workers globals, in a Node.js process in your container.
-
Rivet Actors
One Actor per object, namespace, database, queue or Workflow instance. Rivet places them across your containers.
-
A Rivet Actor, or any S3-compatible store
An Actor by default. Point a bucket at Amazon S3, Google Cloud Storage, Cloudflare R2 or Backblaze B2.
-
Any SMTP server
Such as Amazon SES, Resend, Postmark, SendGrid or Mailgun.
-
Any OpenAI-compatible endpoint
OpenRouter by default, or OpenAI, Groq, Together AI or Fireworks AI.
-
Your sandbox provider
E2B, Daytona, Freestyle or an agentOS VM. Other container images do not run.
-
Your browser, over the DevTools Protocol
Headless Chrome, or Browserbase, Browserless or Steel.
-
Your Postgres or MySQL database
A direct connection with the connection string you already have.
Not supported yet: Vectorize, Images, Media, Stream, Pipelines, AI Search, mTLS certificates, VPC, Legacy blobs. These bindings load, and each call throws.
Each binding’s page has how it runs and what differs: see the bindings overview.
Real Node.js, not the Workers runtime
Your Worker runs in a Node.js process, so you’re not limited to the part of
Node.js that the Workers runtime supports. Node.js APIs are always on, without
nodejs_compat, and the machines you choose set the memory and CPU time.
That opens up the Node.js ecosystem: npm packages that need Node.js APIs the Workers runtime doesn’t have. See OpenOrange vs workerd.
AI context Full service map and runtime limits
Written for LLMs and coding agents: every edge case, measurement, and known deviation. You do not need it to use the feature.
Full service map
Every Cloudflare service, with its status and what differs.
| Cloudflare | OpenOrange | Status | Notes |
|---|---|---|---|
| Workers | OpenOrange runtime | Drop-in | The Workers API surface (fetch handler, env bindings, waitUntil, Cache) on Node.js. Your code and wrangler config load unchanged. |
| Durable Objects | Rivet Actors | Partial | One Rivet Actor per object, with SQLite storage and alarms. Same class, same bindings. |
| Workers KV | Actor-backed KV | Drop-in | The KV binding API, one Actor per namespace. Strongly consistent instead of eventually. |
| Queues | Actor-backed queues | Drop-in | Producers and consumers keep the Queues API, with batching, retries and dead-letter queues. One batch runs at a time per queue. |
| Workflows | Cloudflare's own Workflows engine | Partial | The engine that wrangler dev runs, copied from @cloudflare/workflows-shared, with one Rivet Actor per instance. Steps, sleeps, events and retries work. instance.subscribe() is not available. |
| Cron Triggers | Actor schedules | Drop-in | Same cron syntax in your config. Crons fire in orange dev too. |
| D1 | SQLite on Rivet | Drop-in | The D1 binding API on one SQLite database in a Rivet Actor. |
| R2 | A Rivet Actor, or your S3-compatible store | Pluggable | A bucket is an Actor by default. Point it at any S3-compatible store instead. |
| Workers AI | An OpenAI-compatible provider | Pluggable | The AI binding calls any OpenAI-compatible endpoint you already pay for. Text and embedding models. |
| Sandboxes | Your sandbox provider Locally: agentOS VM, Local directory | Pluggable | The Sandbox SDK runs on a hosted provider, an agentOS VM or a local directory. Other Container images are not run. |
| Hyperdrive | Direct connection | Drop-in | Works unchanged. You are already in the VPC, so env.HYPERDRIVE passes the connection string straight through. |
| Browser Run | Your browser | Pluggable | @cloudflare/puppeteer drives your Chrome or a hosted browser over the DevTools Protocol. |
| Your SMTP server | Pluggable | send_email sends through your SMTP server. Inbound mail reaches email() from your provider's webhook. | |
| Vectorize, Images, Pipelines | Bring your own | Not supported | The bindings load and every call throws. Call a replacement such as pgvector with fetch() today. |
Drop-in: the binding API works unchanged. Pluggable: the binding works unchanged and you choose the backend. Partial: it runs, but some documented APIs throw or act differently. Not supported: calls throw.
Runtime limits, compared
OpenOrange next to Cloudflare’s Workers Paid plan.
| Limit | OpenOrange | Cloudflare (Workers Paid) |
|---|---|---|
| Memory per Worker | The Node.js heap of the runtime process | 128 MB |
| CPU time per request | No limit | 30 s default, 5 min max |
| Subrequests per request | OS limits | 10,000 |
| Alarm wall time | About 24.8 days, the longest Node.js timer | 15 min |
| Node.js APIs | Node.js modules, with workerd-shaped process and fs | nodejs_compat subset |
| Native npm modules | Not tested | No |
Cloudflare figures checked 2026-10-08.