KubeMQ
Client SDKsNode.jsHow-to guidesEvents Store

Replay from Sequence

Replay events starting from a specific sequence number

Which to use

Use sequence-based replay for exact, gap-free resumption when you've persisted the last processed sequence (e.g. crash recovery). For approximate, wall-clock-based replay — "everything since 10 minutes ago" or "since the last deploy" — see Replay from Time.

Overview

Replaying from a sequence number lets a consumer resume an events-store subscription from an exact point in a channel's history, instead of re-reading everything or only catching new traffic. It's the checkpoint-recovery pattern: a worker persists the last sequence it processed, and after a crash or redeploy it reopens the subscription right there — no gap, no reprocessing everything that came before.

Sequence numbers are broker-assigned per channel, starting at 1 and increasing monotonically with every stored event; they never reset unless the channel is purged. Setting startFrom: EventStoreStartPosition.StartAtSequence with startValue: 3 tells the broker to begin delivery at that sequence inclusive, replaying stored events from that point, then transitioning the subscription to live delivery for anything published afterward.

Gotchas: the sequence value is inclusive, so startValue: 3 still delivers event 3 — off by one and you'll reprocess or silently drop a message; you must track and persist the "last processed" sequence yourself, KubeMQ doesn't checkpoint it for you; and requesting a sequence past the current head isn't an error — you'll just get nothing until new events catch up to it.

Prerequisites

  • KubeMQ server running on localhost:50000
  • Node.js SDK installed (npm install kubemq-js)

Code

replay-from-sequence.ts
/**
 * Example: Replay Events from a Specific Sequence Number
 *
 * Demonstrates subscribing to an event store starting from a specific
 * sequence number. Useful for resuming processing after a crash by
 * tracking the last processed sequence.
 *
 * Prerequisites:
 *   - KubeMQ server running on localhost:50000
 *
 * Run: npx tsx examples/events-store/replay-from-sequence.ts
 */
import { KubeMQClient, createEventStoreMessage, EventStoreStartPosition } from 'kubemq-js';

async function main(): Promise<void> {
  const client = await KubeMQClient.create({
    address: 'localhost:50000',
    clientId: 'js-events-store-replay-from-sequence-client',
  });

  try {
    // Publish several events.
    for (let i = 1; i <= 5; i++) {
      await client.sendEventStore(
        createEventStoreMessage({
          channel: 'js-events-store.replay-from-sequence',
          body: `Payment #${i}: $${(i * 49.99).toFixed(2)}`,
        }),
      );
    }

    // Subscribe from sequence 3 — only events #3, #4, #5 are received.
    const subscription = client.subscribeToEventsStore({
      channel: 'js-events-store.replay-from-sequence',
      startFrom: EventStoreStartPosition.StartAtSequence,
      startValue: 3,
      onEvent: (event) => {
        console.log(`[seq=${event.sequence}] ${new TextDecoder().decode(event.body)}`);
      },
      onError: (err) => {
        console.error('Subscription error:', err.message);
      },
    });

    await new Promise((resolve) => setTimeout(resolve, 2000));
    subscription.cancel();
  } finally {
    await client.close();
  }
}

main().catch(console.error);

How It Works

  • StartAtSequence with startValue: 3 tells the server to replay only events with sequence ≥ 3, skipping events 1 and 2.
  • This pattern enables crash recovery: persist the last processed event.sequence and resume from startValue: lastProcessed + 1 on restart.
  • The 5 events are published first (before subscribing), demonstrating that the event store retains messages regardless of subscriber connectivity.
  • Sequence numbers are server-assigned, monotonically increasing per channel — they do not reset between runs unless the channel is purged.

Was this page helpful?

On this page