Actors are lightweight, stateful serverless functions that maintain persistent state and provide real-time communication. They’re the core building blocks of RivetKit applications.

Getting Started

Key Features

Long-Lived, Stateful Compute

Each unit of compute is like a tiny server that remembers things between requests – no need to reload data or worry about timeouts. Like AWS Lambda, but with memory and no timeouts.

Blazing-Fast Reads & Writes

State is stored on the same machine as your compute, so reads and writes are ultra-fast. No database round trips, no latency spikes.

Realtime, Made Simple

Update state and broadcast changes in realtime. No external pub/sub systems, no polling – just built-in low-latency events.

Store Data Near Your Users

Your state lives close to your users on the edge – not in a faraway data center – so every interaction feels instant.

Use Cases

Actors are perfect for applications that need persistent state and real-time updates:

Real-time Communication

  • Chat rooms: Real-time messaging with message history and user presence
  • Collaborative documents: Multiple users editing documents simultaneously
  • Live events: Broadcasting updates to many participants

AI & Automation

  • AI agents: Stateful AI assistants with conversation history
  • Workflow automation: Long-running business processes with state persistence
  • Stream processing: Real-time data processing with persistent state

Data & Synchronization

  • Local-first sync: Offline-first applications with server synchronization
  • Per-user databases: Isolated data stores for each user or tenant
  • Per-tenant SaaS: Multi-tenant applications with isolated state
  • CRDT collaboration: Conflict-free replicated data types for real-time editing

Gaming & Interactive Applications

  • Multiplayer games: Game state management with real-time updates
  • Rate limiting: Distributed rate limiting with persistent counters

State Management

Actors maintain persistent state that survives restarts, crashes, and deployments. State can be defined as a constant or created dynamically:

import { actor } from "@rivetkit/actor";

const counter = actor({
  state: { count: 0 },
  
  actions: {
    increment: (c) => {
      c.state.count++;
      return c.state.count;
    },
    
    getCount: (c) => c.state.count,
  }
});

Learn more about state management.

Actions

Actions are the primary way to interact with actors. They’re type-safe functions that can modify state and communicate with clients:

import { actor } from "@rivetkit/actor";

const chatRoom = actor({
  state: { messages: [] as Array<{text: string, userId: string}> },
  
  actions: {
    sendMessage: (c, userId: string, text: string) => {
      const message = { text, userId };
      c.state.messages.push(message);
      c.broadcast("newMessage", message);
      return message;
    },
    
    getMessages: (c) => c.state.messages
  }
});

Actions can be called from your backend, your clients, or other actors:

const room = client.chatRoom.getOrCreate(["general"]);
const message = await room.sendMessage("user-123", "Hello everyone!");

Learn more about actions and communicating with actors.

Real-time Communication

Actors support real-time bidirectional communication through WebSocket and SSE connections. Clients can establish persistent connections to receive live updates.

For example, to send events to all connected clients:

import { actor } from "@rivetkit/actor";

const liveAuction = actor({
  state: { currentBid: 0 },
  
  actions: {
    placeBid: (c, amount: number) => {
      c.state.currentBid = amount;
      c.broadcast("newBid", { amount });
      return amount;
    }
  }
});

Clients connect and listen for real-time updates:

const auction = client.liveAuction.getOrCreate(["auction-123"]);
const connection = auction.connect();

connection.on("newBid", (data) => {
  console.log(`New bid: $${data.amount}`);
});

await auction.placeBid(150);

Learn more about events and client communication.

Scheduling & Lifecycle

Actors support scheduled tasks and lifecycle management:

import { actor } from "@rivetkit/actor";

const reminder = actor({
  state: { message: "" },
  
  actions: {
    setReminder: (c, message: string, delayMs: number) => {
      c.state.message = message;
      c.schedule.after(delayMs, "sendReminder");
    },
    
    sendReminder: (c) => {
      c.broadcast("reminder", { message: c.state.message });
    }
  }
});

Learn more about actor lifecycle.

Type Safety

RivetKit provides end-to-end TypeScript safety between clients and actors:

const userManager = actor({
  state: { users: {} as Record<string, {name: string}> },
  
  actions: {
    createUser: (c, name: string) => {
      const userId = crypto.randomUUID();
      c.state.users[userId] = { name };
      return { userId, name };
    },
    
    getUser: (c, userId: string) => c.state.users[userId]
  }
});