5 min read
Introducing Peren: Workers on your infrastructure
Peren brings the Workers programming model and recoverable state to infrastructure your team operates.
Workers are appealing because the application stays small. A module receives a request or event, uses the capabilities in its environment and returns a result. The platform handles the processes, routing and infrastructure credentials around it.
Bringing that model to your own infrastructure takes more than starting a JavaScript isolate. Stateful applications still need a single writer, durable storage, recovery after node loss, queues and scheduled work. They also need access to infrastructure without receiving unrestricted access to the host.
Peren is a self-hosted runtime for that problem. It runs JavaScript and WebAssembly Workers in V8 isolates and gives stateful work a durable execution boundary called a cell.
Let’s start at the Worker boundary, move into a cell and follow one write until it is safe to answer.
A Worker receives capabilities
A Peren service combines a Worker bundle with configuration for its entrypoints and bindings. When an HTTP request arrives, the runtime builds a web Request, supplies the service environment, calls the handler and turns the result into a bounded web Response.
Capabilities arrive through env. A service can receive KV, a queue, an R2-style bucket, a D1 database, another service or a Durable Object namespace because its deployment grants that binding. Worker code does not receive the host filesystem, provider clients or infrastructure credentials as ambient globals.
The Worker sees env.BUCKET, not an S3 client and a pair of credentials. Peren can validate the operation and enforce limits before it reaches the provider, while the application keeps one stable interface.
The model extends beyond HTTP. Alarms, scheduled events, queue batches, WebSocket activity and workflow work enter through defined handlers and run with the capabilities configured for that service.
A cell owns stateful execution
Stateless work can run wherever the service is available. Stateful work needs a stable identity and one current owner.
Peren maps each Durable Object style instance to a cell. Its ID is derived from the service, namespace and application-facing object identity, so every node refers to the same durable scope. Only the node that currently owns the cell may execute it.
While active, the cell serializes stateful work and owns its storage handle. A resident isolate may keep ordinary memory between requests, but recoverable state belongs in storage. If the process disappears, another node restores the cell rather than trusting an abandoned local file.
A successful write must be recoverable
The awkward moment comes after a local database commit but before the response reaches the client. Return too early and the client can observe a value that disappears with the node.
Peren places an output gate at that boundary. A state-changing invocation records the committed storage revision, publishes the snapshot and write-ahead-log material needed to recover it, checks that the node still owns the cell and only then releases the response.
Durable request · Step 1 of 4
Find the cell owner
Routing derives the cell ID and finds the node that currently owns it.
No state has changed.
The client is still waiting.
The final ownership check matters because ownership can change during publication. Finishing an upload is not enough if another node has already recovered the cell. The stale process must discard its output instead of answering as the owner.
Read-only invocations do not create replication work. For writes, acknowledgement follows recoverability.
Bindings keep infrastructure outside the Worker
A Worker should not need a rewrite because its operator changed queue brokers or object stores. It calls the binding in env; Peren translates that call for the configured provider.
Provider choice still affects correctness. Object storage used for cell ownership and recovery must support conditional writes, stale-write rejection and range reads. A queue broker must preserve leasing, acknowledgement, retry and dead-letter behaviour. A SQL provider must preserve the transaction behaviour Peren exposes.
That translation only works when the provider preserves the behaviour the binding promises. Peren exercises those operations directly. An S3-shaped or SQL-shaped API alone does not make an endpoint safe for durable execution.
Compatibility is something code can observe
Peren follows the Workers programming model, but a familiar API name is not enough. A feature is useful only when Worker code can reach it and get the behaviour it expects.
Some web APIs and Node modules are supported subsets. Some bindings need a configured provider. Unsupported features fail explicitly. Before moving an application, compare what it uses with the compatibility guide, then run it against Peren and the providers the deployment will use.
The whole path
The request has now crossed four parts of the system:
- The runtime executes a Worker with bounded capabilities.
- The cell serializes one durable scope under one owner.
- Replication makes an acknowledged revision recoverable.
- Providers perform the storage, queue and service operations behind each binding.
Everything else builds on those boundaries: fleet placement, tenant isolation, queues, workflows, deployment and operations.
Start with the installation and first Worker guide. Continue with Who owns a cell? for the failure sequence behind single-owner execution, or read the architecture overview for the complete component map.