Skip to content
Getting started / Architecture

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

  • container

  • container

  • 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
Your Docker containers, in any cloud, connect out to the Rivet control plane, which is backed by S3.

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 toRuns on
Self-hostedAny cloud, Hetzner or on-prem
Rivet CloudA dedicated cluster on AWS or Google Cloud, in the region you choose
BYOCYour 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 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.
Email 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.

LimitOpenOrangeCloudflare (Workers Paid)
Memory per WorkerThe Node.js heap of the runtime process128 MB
CPU time per requestNo limit30 s default, 5 min max
Subrequests per requestOS limits10,000
Alarm wall timeAbout 24.8 days, the longest Node.js timer15 min
Node.js APIsNode.js modules, with workerd-shaped process and fsnodejs_compat subset
Native npm modulesNot testedNo

Cloudflare figures checked 2026-10-08.