Streams
Create a stream, pick its format, and decide when it goes away.
A stream is an append-only log at its own URL. Writers add to the end, and every reader sees the same messages in the same order.
These pages follow one example: an AI agent streams its reply into chat/session-1, and a browser shows it as it arrives.
Create a stream
Pick any path. Slashes are fine, and there is nothing to register first.
import { DurableStream } from "@durable-streams/client";
// One stream per chat session
const stream = await DurableStream.create({
url: "http://127.0.0.1:8642/durable-streams/v1/stream/chat/session-1",
contentType: "application/json",
// Delete the stream after a day with no reads or writes
ttlSeconds: 86400,
});
console.log("created", stream.url);
Creating the same stream twice is safe. Creating it again with different settings returns 409 Conflict.
Choose JSON or bytes
The content type is set at creation and never changes.
application/json: each append is one message, and reads return a JSON array. Use it for chat, events, and agent output.- Anything else, such as
text/plainorapplication/octet-stream: one continuous run of bytes. Frame messages yourself, for example one JSON object per line.
Clean up automatically
Set one of these when you create the stream, or neither to keep it until you delete it:
ttlSeconds: delete after this many seconds with no reads or writes. An active stream never expires.expiresAt: delete at a fixed time, such as2027-01-01T00:00:00Z.
To delete a stream now, call stream.delete().
On Rivet, each stream is its own Rivet Actor, so streams scale independently and sleep when no one is using them.