Skip to main content
Never miss a beat: LaserStream’s Historical Replay ensures you can recover from disconnections and backfill missing data from the last 24 hours of blockchain activity.

What is Historical Replay?

Historical Replay is LaserStream’s feature that lets you replay recent blockchain data by setting a fromSlot starting point. This is useful for handling disconnections and ensuring data continuity in real-time apps.

How Far Back You Can Replay

You can replay up to ~24 hours (~216,000 slots) of history, regardless of which commitment level you subscribe with. Pass a fromSlot within that window and LaserStream streams forward from there to the present. Older replays return finalized data. LaserStream keeps roughly the last ~20 minutes of slots in memory; anything older is served from a historical store that holds finalized blocks only. So when you replay a fromSlot older than ~20 minutes, the data reflects the finalized chain — you won’t see forked or dropped slots or intra-slot account updates in that range, even on a processed or confirmed subscription. Slots within the last ~20 minutes carry true commitment semantics, including forks and intra-slot account updates.
Limited Time Window: Historical replay only covers the last ~24 hours. You cannot replay data from arbitrary points in the past.

Handle Disconnections

Recover data lost during brief disconnections (up to 24 hours)

Bootstrap Applications

Start applications with recent context from the last 24 hours

Analyze Recent Events

Review recent transactions and account changes

Test with Recent Data

Use real recent data for testing and development

How It Works

1

Specify Starting Point

Use the fromSlot parameter to set your replay starting point (must be within last ~216,000 slots)
2

Stream Historical Data

LaserStream delivers all events from your specified slot forward
3

Catch Up to Real-Time

Historical data streams until you reach the current slot
4

Continue Live Streaming

Seamlessly transition to real-time data streaming
Automatic Reconnection: The LaserStream SDK handles reconnections and replay automatically. No additional code required!

Quickstart

Get started with LaserStream from your Helius Dashboard. Mainnet requires a Business or Professional plan; Devnet is available on Developer and above. See Plans & Pricing for details.
import { subscribe, CommitmentLevel, LaserstreamConfig, SubscribeRequest } from 'helius-laserstream';

// Pick a slot within the last ~216,000 slots (≈24 h). For a real start
// value, call `getSlot` first and subtract however far back you want to replay.
// Note: replays older than ~20 min return finalized data even at processed/confirmed;
// slots within the last ~20 min carry true commitment semantics.
const fromSlot = 419_800_000;

const subscriptionRequest: SubscribeRequest = {
  transactions: {
    "token-filter": { // user-defined label for this filter
      accountInclude: ['TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'],
      vote: false,
      failed: false
    }
  },
  commitment: CommitmentLevel.CONFIRMED,
  accounts: {},
  slots: {},
  blocks: {},
  blocksMeta: {},
  entry: {},
  accountsDataSlice: [],
  fromSlot, // u64 slot number; must fall inside the replay window
};

const config: LaserstreamConfig = {
  apiKey: 'YOUR_API_KEY',
  endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com', // Choose your closest region
};

await subscribe(config, subscriptionRequest, 
  async (data) => {
    console.log('Received data:', data);
  }, 
  async (error) => {
    console.error('Error:', error);
  }
);

Configuration Options

fromSlot
number
required
The slot number to start replaying from, as a u64. Must be within the replay window (last ~216,000 slots / ~24 hours from the current slot), at any commitment level.Example: currentSlot - 1000Important: If you pass a slot older than the window, LaserStream rejects the request with Operation was attempted past the valid range.

Use Cases

When your application reconnects after a short disconnection (under 24 hours), you can use Historical Replay to ensure no data is missed. getCurrentSlot calls the Helius RPC; lastProcessedSlot is kept in memory below — persist it however suits your app (Redis, Postgres, a file, etc.).
async function getCurrentSlot(): Promise<number> {
  const r = await fetch(`https://mainnet.helius-rpc.com/?api-key=${process.env.HELIUS_API_KEY}`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'getSlot', params: [{ commitment: 'confirmed' }] }),
  });
  const { result } = await r.json();
  return result as number;
}

// Load the last slot you processed from wherever you store it.
let lastProcessedSlot = Number(process.env.LAST_PROCESSED_SLOT ?? 0);

// Check if it's still within the replay window
const currentSlot = await getCurrentSlot();
const maxReplaySlot = currentSlot - 216_000;

if (lastProcessedSlot < maxReplaySlot) {
  console.warn('Disconnection too long, some data may be lost');
  lastProcessedSlot = maxReplaySlot;
}

const subscriptionRequest: SubscribeRequest = {
  // ... your subscription config
  fromSlot: lastProcessedSlot, // pass as number, not string
};

await subscribe(config, subscriptionRequest,
  async (data) => {
    // your handler here
    if (data.transaction?.slot) {
      lastProcessedSlot = Number(data.transaction.slot);
      // persist `lastProcessedSlot` here so the next reconnect picks up
    }
  }
);
Start your application with recent context from the last few minutes:
// Get a slot from 10 minutes ago (within the 24-hour window)
const currentSlot = await getCurrentSlot();
const startSlot = currentSlot - 1500; // ~10 minutes ago

const subscriptionRequest: SubscribeRequest = {
  // ... your subscription config
  fromSlot: startSlot, // u64 number
};
Use recent historical data for testing (limited to last 24 hours):
// Test with data from the last 5 minutes
const currentSlot = await getCurrentSlot();
const testStartSlot = currentSlot - 750; // ~5 minutes ago
const testEndSlot = currentSlot - 150;   // ~1 minute ago

const subscriptionRequest: SubscribeRequest = {
  // ... your subscription config
  fromSlot: testStartSlot, // u64 number
};

// Stop processing when reaching the test end slot
const stream = await subscribe(config, subscriptionRequest,
  async (data) => {
    const slot = Number(data.transaction?.slot ?? data.account?.slot ?? 0);
    if (slot >= testEndSlot) {
      stream.cancel();
      return;
    }
    // your test handler here
  }
);

Next Steps

LaserStream gRPC

Learn more about gRPC streaming capabilities and features

Get Started

Enable LaserStream from your Helius Dashboard and start streaming.

SDK Documentation

View the complete SDK docs

Contact Support

Get help with your implementation