Skip to main content
S2 integrates with Mastra through @s2-dev/mastra-pubsub. The package provides an S2PubSub implementation for Mastra durable agents. Each durable-agent topic maps to an S2 stream. When S2PubSub appends an event, the S2 sequence number becomes the event’s Mastra index. Live delivery and replay therefore use the same index, which lets Mastra replay and deduplicate events without a separate counter. A durable agent reconnecting after a browser refresh

Install

The package requires Node.js 22.13 or later and @mastra/core 1.45 or later in the 1.x release line. @mastra/core is a peer dependency. Create a basin with Create Stream on Append and Create Stream on Read enabled. These settings let S2PubSub create a run stream when it first writes or reads the topic. You can create the basin in the dashboard or with the CLI:
Set the basin, access token, and model provider key:

Configure Mastra

Create an S2PubSub and pass it to the Mastra instance that registers your durable agent:
src/mastra/index.ts
src/mastra/agents/research-agent.ts
Registered durable agents use the Mastra instance’s pubsub. By default, S2PubSub persists topics beginning with agent.stream.; other topics only use the live-delivery transport.

Reconnect to a run

Starting a durable-agent stream returns a runId. Keep that ID where a reconnecting client can retrieve it.
After a browser refresh or dropped connection, call observe with the same runId:
Pass an offset when the caller already has part of the stream. The offset is the first event index to replay, so use 42 if index 41 was the last event processed:

How persistence works

S2PubSub extends Mastra’s CachingPubSub and replaces its in-memory history operations for persisted topics:
  1. publish serializes the event and appends it to the topic’s S2 stream. It adds the returned seqNum as the event index, then sends the event through the inner pubsub for live delivery.
  2. getHistory reads the S2 stream from the requested offset and restores each record’s seqNum as its event index.
  3. clearTopic deletes the corresponding S2 stream.
If an append fails, S2PubSub logs the error and still sends the event through the inner pubsub without an index. That event is available to live subscribers but cannot be replayed from S2.

Cleanup and retention

When Mastra cleans up a run, it calls clearTopic, which deletes that run’s S2 stream. Do not treat these streams as permanent run history. If a process exits before cleanup, its stream can remain. You can apply an age-based retention policy and delete_on_empty in the basin’s default stream configuration to remove these orphaned streams. Keep the retention period longer than the maximum run time and reconnection window you support.

Options

new S2PubSub(config, options?)

S2 Lite

Install the S2 SDK for its environment helper:
To use S2 Lite, set S2_ACCOUNT_ENDPOINT and S2_BASIN_ENDPOINT, then pass the parsed endpoints to S2PubSub:

Example

The package repository includes a runnable example adapted from Mastra’s durable-agents example: examples/durable-agents.