# Yellowstone Keepalive and Replay

> Keep gRPC subscriptions healthy and request recent updates from a slot.

Canonical: https://nolimitnodes.com/docs/api-reference/grpc/keepalive-replay

Long-running gRPC streams need liveness checks, reconnect logic, and gap recovery.

## Reply to server pings

Yellowstone sends ping updates on active subscriptions. Write a request with the same ping ID.

```typescript
stream.on("data", (update) => {
  if (!update.ping) return

  stream.write({
    accounts: {},
    slots: {},
    transactions: {},
    transactionsStatus: {},
    blocks: {},
    blocksMeta: {},
    entry: {},
    accountsDataSlice: [],
    ping: { id: update.ping.id },
  })
})
```

Keep your full active filter set when the client or server expects replacement semantics.

## Track progress

Store the highest processed slot after your downstream write succeeds.

Do not advance the checkpoint before database or queue acknowledgement.

## Request replay

Set `fromSlot` on the subscription request after reconnect.

```typescript
stream.write({
  accounts: {},
  slots: { recovery: {} },
  transactions: {},
  transactionsStatus: {},
  blocks: {},
  blocksMeta: {},
  entry: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.CONFIRMED,
  fromSlot: lastStoredSlot,
})
```

Replay depth depends on your plan and current server retention.

Call `SubscribeReplayInfo` before requesting an old slot. Compare `firstAvailable` with your checkpoint.

## Duplicate handling

Replay overlaps are normal.

- Transactions: use the signature as the primary key.
- Account updates: use account address, slot, and write version.
- Slots: use slot and status.
- Blocks: use slot or block height.

Make downstream writes idempotent.
