Independent AI intelligence Two editions daily · ET
Fervor AI

Analysis · November 6, 2026 · repo

Rivetrivet-dev/rivetagent-infrastructureagent-harnessclaude-code

Your AI Agent Spends Most of Its Life Waiting. Rivet Lets It Sleep.

An open-source actor runtime gives every agent its own small, durable home that naps between messages. Here is what that buys you and where it stops.

Watch an AI agent work for an hour and count the minutes it is actually doing something.

It waits for the model to answer. It waits for a tool call. It waits for you to read its question and reply, which might take ten seconds or a whole lunch break. Then it does a burst of work and waits again. Most of an agent's life is idle time with a conversation it must not forget.

Most hosting setups ignore that shape. The common pattern is to give each agent a sandbox (a small, isolated virtual machine) and keep it alive for the whole session, idle minutes included. You pay for memory nobody is using, and if the box restarts mid-task, the agent forgets where it was.

Rivet, which launched on Hacker News on November 5, bets on a different shape. Give each agent a tiny process that holds its memory, let that process fall asleep when nothing is happening, and wake it up exactly where it left off. The idea is old. Multiplayer game servers have worked this way for years. Applied to agents, it changes the question from "how big a box does my agent need?" to "where does my agent's memory live while it naps?"

What Rivet actually is

Rivet is an open-source runtime for "actors," released under Apache-2.0. The README defines them in one line: "Rivet Actors are long-lived processes with in-memory state, a SQLite database, WebSockets, and scheduling."

If "actor" is a new word for you, picture a small office with one occupant. Each office has a name on the door (agent-123), a filing cabinet (a SQLite database, the lightweight file-based database), a phone line for live updates (a WebSocket), and an alarm clock (scheduling). Messages go to the office by name. The occupant handles one thing at a time and keeps notes in the cabinet. The README suggests you create one actor "for each agent, user, session, or tenant."

The trick is what happens when the office is quiet. Per the lifecycle docs, after sleepTimeout, "default 30 seconds" of no activity, the actor goes to sleep. "When a request arrives for a sleeping actor, it wakes up, restores its state, and handles the request." The README's pitch for this is blunt: "Idle Actors cost nothing and wake on the next request with nothing lost."

Where does the filing cabinet go while the office sleeps? Object storage. "All data lives in S3," the README says, and "S3 is the only dependency" for self-hosting. That covers Amazon S3, Google Cloud Storage, Azure Blob Storage and S3-compatible stores like MinIO or Cloudflare R2. In the Launch HN post, the founders explain how that stays fast: a write is confirmed once SSDs in two of three availability zones have it, then batched to S3 in the background, and reads come from an SSD cache with S3 as the fallback.

The founders, Nathan and Nicholas, say the design came from building a backend for multiplayer browser games. That history shows. A game lobby is mostly idle players holding state, which is a fair description of a fleet of agents too.

Why this fits agents better than a box left running

Here is the insight in one sentence: an agent's memory should outlive its process, and its process should only exist while it is working.

A sandbox couples the two. The memory lives in the box, so the box has to stay up. Rivet splits them. The conversation, the plan and the in-progress tool results sit in the actor's database, and the process comes and goes around them.

Rivet's Agents docs push this one step further, and it's the part I'd pay the most attention to: "The agent loop runs in the Actor. Model calls, retries, and the conversation run in your backend, next to your application code, where you control credentials, permissions, and logging." When the agent needs a real shell, it borrows a sandbox for that job. Rivet's docs say "your provider keys never enter the sandbox" in that setup.

Think of it as separating the brain from the hands. The brain (the loop that decides what to do next) stays somewhere durable and trusted. The hands (the shell that runs commands) live in a disposable box that can be thrown away. If the hands do something stupid, the brain and your API keys are somewhere else.

The numbers, and whose they are

Rivet publishes striking figures: a 4.99 ms p99 cold start (99 of 100 wakes finish faster than that) and 72.4 KB of memory per actor, set against 1.70 seconds and 512 MiB for a sandbox, per the README.

Read those carefully. The Rivet numbers come from Rivet's own benchmark, run on version 3.0.3 against Cloudflare Durable Objects. The sandbox side comes from somewhere else: E2B's billing docs for the 512 MiB default and ComputeSDK's October 30 benchmark for the 1.70 seconds. Two different tests, stitched into one comparison. On Hacker News, one commenter asked for numbers behind the claim that sandboxes are "expensive, mostly idle, and slow to start," and a co-founder answered that the sandbox figures were pulled from ComputeSDK's benchmarks.

None of that makes the numbers wrong. It makes them a vendor's case, not an independent result. The structural point survives either way: a process that holds kilobytes of state and naps is cheaper than one that holds a whole VM awake.

Where it gets uncomfortable: running Claude Code inside it

Rivet has a guide for running Claude Code, Anthropic's coding agent, "one session per Rivet Actor." Reading it this afternoon, the design is sensible and also more honest than most guides about its sharp edges.

In that guide the actor keeps the transcript and session id, and Claude Code itself runs inside an E2B sandbox, launched with claude -p and --dangerously-skip-permissions. The guide's reasoning: "because nobody is there to approve them. The sandbox is the boundary."

Then it says the quiet part out loud. The Anthropic key goes to the Claude Code process as an environment variable, and "code in the sandbox can read it. Give the sandbox a key with a spending limit."

That is the correct advice, and it shows the limit of this pattern for third-party agents. When the whole agent, loop included, runs inside the box, the brain-and-hands split disappears. You get Rivet's durability for the session record. You don't get the credential separation that the Agents docs describe for loops running in the actor.

Put this into practice

The lowest-friction path is local, on your own machine, before any cloud account.

1. Try an actor in a Node project. Install the library:

npm install rivetkit

The README's example builds an actor with actor({ ... }), registers it with setup({ use: { agent } }), and talks to it from a client. The client side looks like this, trimmed from the README on the main branch as I read it on November 6 (the full server code is there too). sendMessage is an action that example defines, not a built-in, and the copy of the README at the v3.0.5 tag uses a plain string key and an agent.chat(...) action instead, so follow the README for the version you install:

import { createClient } from "rivetkit/client";

const client = createClient<typeof registry>();
const agent = client.agent.getOrCreate(["agent-123"]).connect();

agent.on("token", (t) => process.stdout.write(t));
await agent.sendMessage("Summarize yesterday's failing tests");

The key you pass to getOrCreate is the office name on the door. Use your conversation id or user id, and every message for that conversation lands in the same actor with its history intact.

2. Run the engine yourself when you want real persistence. The self-hosting guide runs it as one container, after you create the small rivet.json config file the guide provides:

export RIVET_TOKEN="$(openssl rand -hex 32)"
docker run -d --name rivet \
  -e RIVET__AUTH__ADMIN_TOKEN="$RIVET_TOKEN" \
  -p 6420:6420 \
  -v "$PWD/rivet.json:/etc/rivet/config.json:ro" \
  -v rivet-log:/var/lib/rivet/log \
  -v rivet-objects:/var/lib/rivet/objects \
  rivetdev/engine:latest
curl http://localhost:6420/health

Then point your app at it with export RIVET_ENDPOINT="http://localhost:6420". The quickstart config stores objects on local disk. Production setups swap in an S3 bucket and run three or more instances, per the docs. The engine refuses to start without at least 4 GiB free on disk, so a cramped laptop will tell you quickly. For anything beyond a test, pin the image to a version you tested instead of latest.

3. Write the sleep rules into your design from day one. Three lines from the lifecycle docs will bite you if you skip them:

  • Saved state survives sleep. Temporary vars "are not persisted." Put anything you need after a nap in state or the database.
  • "In-flight actions are not waited on during shutdown." A long tool call should be tracked in the database, so a woken actor can tell whether it finished.
  • Outbound fetch calls don't count as activity, so an actor waiting on a slow model API can fall asleep mid-call unless you account for it. c.keepAwake() holds off idle sleep while a promise runs, while c.waitUntil() only buys time inside the 15-second shutdown grace window. Neither makes a ten-minute tool call safe on its own.

4. Check the costs before you choose cloud. Self-hosting has no Rivet license or usage fee under Apache-2.0, though you still pay for your own servers and storage. On Rivet Cloud, the control plane is the coordinator that routes requests and tracks where each actor lives, and actor nodes are the machines your actors actually run on. The pricing page lists a free tier with one control plane node and one included actor node, a $10 Hobby plan and a $120 Team plan, and on paid plans actor nodes are added on top, starting at $4.20 a month.

Honest limitations

This is a young major version. Rivet 3.0.0 tagged on November 1, its release notes include a README update "for Rivet 3.0 preview," and 3.0.5 followed four days later. Expect API churn.

The limits are real for agent work. Actions have a 60-second soft timeout and a wake has a 45-second hard timeout, per the limits page. Long tool calls belong in a sandbox or a background job that reports back, not inside one action.

Sleep loses connections. WebSockets close when an actor sleeps, and clients have to reconnect. Hibernatable WebSockets exist, but the docs mark them beta and "disabled by default."

The performance story is self-reported, as covered above. And the credential separation that makes the design appealing applies only when the agent loop runs in the actor. Wrap an off-the-shelf agent like Claude Code in a sandbox and you are back to trusting the box with your key.

What to take from it

You don't have to adopt Rivet to use its best idea. Ask where your agent's memory lives while the agent is doing nothing. If the answer is "in a VM we keep running," you're paying rent on a waiting room, and a restart wipes the guest book.

Move the memory somewhere durable. Let the process come and go. Keep the shell in a box you can throw away, and keep your keys out of it. Rivet is one clean way to build that. Your own queue, database and sandbox can be another, as long as the shape is right.

Sources: rivet-dev/rivet README (read on main November 6, latest release v3.0.5 tagged 2026-11-05); Launch HN: Rivet (YC W23); Rivet actor lifecycle docs; Rivet limits; Rivet Agents docs; Run Claude Code guide; Self-hosting with Docker; Rivet pricing; releases feed.