Skip to content

Repository files navigation

Durable Streams and Rivet

Durable Streams for Rivet Actors

Real-time streams with durable history. Powered by open-source, self-hostable infrastructure.

Guide · Announcement · Discord

What are Durable Streams?

Durable Streams are an open standard for real-time data streaming with durable history. You write data to a stream, and readers can read from any offset in the stream: catch up from the beginning, resume from where they left off, or tail it live.

They are a good fit for:

  • Agent sessions: prompts and responses survive restarts, and clients reconnect without losing a token.
  • CRDT sync: a durable, ordered log of updates for collaborative editing with Yjs and similar libraries.
  • Database sync: stream changes to every client and replay from any offset.

This repository is the Rivet implementation of the protocol, powered by Rivet Actors. It supports binary and JSON streams, catch-up reads, long polling, SSE, idempotent producers, TTLs, stream closure, forks, and a read-only inspector. Existing Durable Streams clients work unchanged.

Why Rivet

  • Bottomless SQLite: streams are not capped by a per-object SQLite size limit.
  • SSD-backed with S3-tiered storage: hot reads and writes are served from local SSDs, and history is tiered to S3 so storage is cheap, durable, and independent of any single machine.
  • Multi-region edge network: each stream lives in the region closest to the clients reading and writing it.
  • Same code locally and in production: what runs on your laptop is what runs in production. No mocks and no emulators.
  • Built in Rust: the server is native Rust for high-performance streams.
  • Open-source and self-hostable: run it in your own VPC or on-prem, so your data stays with you.

Getting started

Start the server

Already running Rivet Actors with the RivetKit TypeScript SDK? Durable Streams are already available to you on RivetKit 2.3.12 and later. No separate server needed.

Otherwise, start a local Rivet Engine and the Durable Streams server:

npx @rivet-dev/services dev

Your streams are at http://127.0.0.1:8642/durable-streams/v1/stream/<path>.

Use it via curl

# Create a stream with an initial record
curl -i -X PUT \
  -H 'content-type: application/json' \
  --data '[{"message":"hello"}]' \
  http://127.0.0.1:8642/durable-streams/v1/stream/demo

# Append to it
curl -i -X POST \
  -H 'content-type: application/json' \
  --data '{"message":"world"}' \
  http://127.0.0.1:8642/durable-streams/v1/stream/demo

# Read from the beginning
curl 'http://127.0.0.1:8642/durable-streams/v1/stream/demo?offset=-1'

Use it via TypeScript

Install the official client:

npm install @durable-streams/client
import { DurableStream } from "@durable-streams/client";

const stream = await DurableStream.create({
	url: "http://127.0.0.1:8642/durable-streams/v1/stream/demo",
	contentType: "application/json",
});

await stream.append(JSON.stringify({ message: "hello" }));

const res = await stream.stream<{ message: string }>();
res.subscribeJson(async (batch) => {
	for (const item of batch.items) {
		console.log(item.message);
	}
});

Deploying

Durable Streams runs as a single service on Rivet Cloud or on your own Rivet Engine. See the integration guide for both.

Resources

Contributing

See CONTRIBUTING.md for running the server from source and testing.

License

Apache 2.0

About

A native implementation of the Durable Streams protocol for Rivet Actors

Resources

Contributing

Stars

8 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages