Skip to content
GitHub Get Started
Reference

Persistence & Sleep

  • Persistent filesystem backs /home/user automatically
  • Session transcripts persisted with sequence numbers for replay
  • Configurable sleep with a 15-minute grace period by default
  • Automatic wake when a client connects or a cron job triggers
DataStoragePersists?
Files in /home/userPersistent filesystemYes
Session recordsSQLite (agent_os_sessions)Yes
Session event historySQLite (agent_os_session_events)Yes
Preview URL tokensSQLite (agent_os_preview_tokens)Yes
Cron job definitionsActor stateYes
Running processesVM kernelNo
Active shellsVM kernelNo
In-memory mountsVM memoryNo
VM kernel stateVM memoryNo

The actor stays awake as long as any of these are active:

  • Active sessions (created but not closed/destroyed)
  • Running processes (spawned but not exited)
  • Active shells (opened but not closed)
  • Pending hooks (server-side callbacks still executing)

When all activity stops, the sleep grace period begins.

After all activity stops, the actor waits 15 minutes before sleeping. This allows for brief pauses between interactions without restarting the VM.

Activity stops ──> 15 min grace period ──> Actor sleeps
(VM shutdown, processes killed)
New client connects ──> Actor wakes ──> VM boots ──> Filesystem restored
SleepDestroy
FilesystemPreservedDeleted
Session recordsPreservedDeleted
Event historyPreservedDeleted
Preview tokensPreservedDeleted
VM stateLostLost
ProcessesKilledKilled

Subscribe to vmBooted and vmShutdown events to track VM lifecycle.

client.ts
import { createClient } from "rivetkit/client";
import type { registry } from "./server";
const client = createClient<typeof registry>("http://localhost:6420");
const agent = client.vm.getOrCreate(["my-agent"]);
agent.on("vmBooted", () => {
console.log("VM is ready");
});
agent.on("vmShutdown", (data) => {
console.log("VM shutdown reason:", data.reason);
// reason: "sleep" | "destroy" | "error"
});

When the actor wakes up:

  1. The VM boots and the filesystem is restored from SQLite
  2. Session records and event history are available immediately
  3. Processes and shells from the previous session are gone
  4. Clients can reconnect and resume sessions using resumeSession
  5. Use getSessionEvents to replay missed events
client.ts
import { createClient } from "rivetkit/client";
import type { registry } from "./server";
const client = createClient<typeof registry>("http://localhost:6420");
const agent = client.vm.getOrCreate(["my-agent"]);
// List sessions from before sleep
const sessions = await agent.listPersistedSessions();
console.log("Previous sessions:", sessions.length);
// Resume the most recent session
if (sessions.length > 0) {
const last = sessions[0];
await agent.resumeSession(last.sessionId);
// Replay events for transcript
const events = await agent.getSessionEvents(last.sessionId);
for (const e of events) {
console.log(e.seq, e.event.method);
}
}

Stores the virtual filesystem.

ColumnTypeDescription
pathTEXT PRIMARY KEYFile or directory path
is_directoryINTEGER1 for directory, 0 for file
contentBLOBFile content
modeINTEGERPOSIX mode bits
sizeINTEGERFile size in bytes
atime_msINTEGERAccess time (ms)
mtime_msINTEGERModification time (ms)
ctime_msINTEGERChange time (ms)
birthtime_msINTEGERBirth time (ms)

Stores session metadata.

ColumnTypeDescription
session_idTEXT PRIMARY KEYUnique session identifier
agent_typeTEXTAgent type (e.g. “pi”)
capabilitiesTEXT (JSON)Agent capabilities
agent_infoTEXT (JSON)Agent metadata
created_atINTEGERCreation timestamp (ms)

Stores session event history.

ColumnTypeDescription
idINTEGER PRIMARY KEYAuto-incrementing ID
session_idTEXTSession reference
seqINTEGERSequence number within session
eventTEXT (JSON)JSON-RPC notification
created_atINTEGERTimestamp (ms)