A subscription delivers updates while the connection and service support it. A reliable consumer also stores progress, reconnects and resubscribes, then reconciles missed activity through an appropriate historical source. Refreshing a current balance and reconstructing every event are different recovery tasks.
Choose the notification that matches your task
accountSubscribe notifies you when an account's lamports or data change at the chosen commitment. logsSubscribe reports matching transaction logs. These methods answer different questions: current account state versus observed transaction activity.
The service returns a subscription ID used to manage that subscription. It is not a globally durable event cursor. Store the logical subscription configuration so you can create it again after reconnecting.
A connection can close because of a network interruption, provider limit or maintenance. Your application can also miss processing while it restarts. A reconnect does not by itself deliver everything that happened in between.
Distinguish tentative processed updates from settled ones. Under current migrated-mainnet guidance, use finalized when your application requires final state; do not import old confirmation timing assumptions into the consumer.
A current balance needs snapshot reconciliation
Suppose a teaching balance view last observed 10 tokens. The connection drops, and the real balance changes to 8 before reconnecting. Showing 10 until the next notification could leave the screen stale indefinitely if no further change happens.
After reconnecting, refresh the current state through HTTP and rebuild subscriptions. Record the snapshot's context. That recovers the latest balance even when you cannot reconstruct the intermediate events from account notifications.
At startup, account for the race between subscribing and fetching. One workable design buffers notifications while taking a snapshot, then reconciles using their contexts. If ordering or same-context handling is ambiguous, refresh again rather than merging by arrival time alone.
A current-state consumer may coalesce updates and display the newest accepted value. It should preserve the observation context and mark the screen stale during recovery.
A payment ledger needs recoverable event history
Now change the task: an invoice system must discover every eligible payment during the outage. Reading a current balance cannot distinguish one incoming transfer from several transfers followed by an outgoing one.
Persist the last durably processed cursor or record for the chosen history source. On reconnect, query the missing range, validate each candidate transaction and apply the business rule. Resume live processing with an overlap to cover the handoff.
getSignaturesForAddress can help when the relevant address appears in transaction account keys. It is not a universal complete wallet ledger. A payment service may need all receiving token accounts, program references or an indexed source with a documented coverage contract.
If retained history no longer reaches the cursor, surface a coverage gap. Silently skipping to now creates an apparently complete ledger with missing payments.
Recover state or recover events
Make overlap safe with durable deduplication
A recovery pass and live subscription can report the same transaction. Repeated delivery is expected in a resilient design. Store an identity appropriate to the record, such as cluster, signature and instruction or event index.
Use a durable uniqueness rule when writing the ledger. An in-memory set disappears after a restart. For an external side effect, record the business action and queue its delivery transactionally before marking source progress.
Advance the durable cursor only after the event's intended processing is committed. Saving the cursor first can lose work if the process crashes before applying the event.
One signature can contain several instructions. A transaction-level dedup key alone can discard legitimate separate events if your application models more than one event per transaction.
Walk through a disconnect and restart
Choose a teaching ledger whose last committed record is event A. The socket disconnects. Events B and C settle while offline. After reconnecting, the live stream reports C and D.
The backfill starts from the durable boundary around A and returns B and C. The application validates B, inserts it once, then inserts C once. When the live copy of C arrives, the uniqueness rule recognises it. D is processed after the source's required conditions are met.
The labels describe event order for this example, not slot numbering or guaranteed provider delivery order. A real implementation uses the source's actual pagination and ordering contract.
Restart the worker at each handoff during testing. Confirm that it produces one committed business record per eligible event, with no gap after the chosen overlap and no duplicate side effect.
Monitor recovery rather than connection alone
A connected socket can still be stale. Track last notification time, latest observed context, durable processing boundary, pending backfill and distance from the source's newest available data.
Reconnect with bounded backoff and recreate subscriptions from stored configuration. Limit parallel recovery jobs so a widespread reconnect does not overload your RPC allowance.
Test a quiet account, a busy account, a dropped connection, duplicate delivery and a history gap. The payment reconciliation guide applies this pattern to invoices and fulfilment.
Common questions
Does reconnecting replay missed account notifications?
Do not assume it. Use the service’s documented replay capability or reconcile through snapshots and history appropriate to the task.
Can I recover payments by comparing balances?
A balance gives current state. Several different payment and withdrawal histories can produce the same balance.
Is the subscription ID my durable checkpoint?
No. Store the source identity and a cursor or processing boundary suitable for recovery, together with the logical subscription configuration.
Sources and documentation
- accountSubscribe
- logsSubscribe
- getSignaturesForAddress
- getTransaction
- Choosing a Solana RPC provider
- Solana Foundation: Alpenglow status and migration
Found an error or an outdated detail? Send a correction.
