Skip to main content

programSubscribe

Subscribe to a program to receive notifications when the lamports or data for an account owned by the given program changes

Common use cases
Token balance monitoringSubscribe to all token accounts for a specific mint or owner to track balance changes in real-time. Common for wallet UIs displaying live balance updates or DEX interfaces monitoring liquidity pool token holdings without polling.
DeFi protocol state trackingMonitor all accounts owned by lending protocols, AMMs, or derivatives programs to track position changes, liquidation events, or pool rebalancing. More efficient than individual accountSubscribe calls when monitoring many related accounts (10-100+).
NFT marketplace activityTrack all NFT metadata accounts for a collection to detect listings, sales, or metadata updates. Enables real-time marketplace feeds and collection analytics dashboards without indexing infrastructure.
Whale wallet trackingUse memcmp filters to monitor large token holders (whales) by subscribing to token accounts with high balances. Offset 64 + memcmp on balance field to detect when whale positions change, enabling copy-trading or market sentiment analysis.
Custom indexing and cachingBuild lightweight real-time indexes for specific programs by subscribing with filters to capture account changes. Store filtered account data locally for fast queries, using programSubscribe as cheaper alternative to full indexer infrastructure for single-program focus.

Parameters

subscriptionId (string, required)

Pubkey of the program_id, as base-58 encoded string

config (object, optional)

Configuration object containing the following fields:

Fields:

  • commitment (string): The commitment describes how finalized a block is at that point in time. See Configuring State Commitment.
  • filters (array): Filter results using various filter objects. See Filtering. The resultant account must meet ALL filter criteria to be included in the returned results
  • encoding (string): Encoding format for Account data
    • base58 is slow.
    • jsonParsed encoding attempts to use program-specific state parsers to return more human-readable and explicit account state data.
    • If jsonParsed is requested but a parser cannot be found, the field falls back to base64 encoding, detectable when the data field is type string.

Request

wscat -c wss://solana-mainnet.api.syndica.io -x '{
"jsonrpc": "2.0",
"id": 1,
"method": "programSubscribe",
"params": [
"11111111111111111111111111111111",
{
"encoding": "base64",
"filters": [{ "dataSize": 80 }]
}
]
}'
Network Selection

Replace mainnet with devnet in the URL to query devnet instead.

Response

{
"jsonrpc": "2.0",
"result": 24040,
"id": 1
}

Response Fields

Return value: integer

Subscription id (needed to unsubscribe)

FAQ and Troubleshooting

How do I filter for multiple specific accounts when filters use AND logic?

You can't use OR filters—must create separate programSubscribe calls for each account or filter combination. For monitoring 2-5 disparate accounts, use individual accountSubscribe instead. For 10+ accounts with common patterns, use broader programSubscribe filter and filter client-side.

What's the difference between base58, base64, and jsonParsed encoding?

base58 is compact for public keys, base64 is standard for binary data, jsonParsed auto-decodes known program accounts (SPL Token, etc.) into JSON. Use jsonParsed for token accounts to avoid manual decoding; use base64+zstd for large accounts to reduce bandwidth; use base58 when you only need account keys.

Why do my subscriptions disconnect or miss updates at scale?

Most RPC providers limit concurrent subscriptions (100-1000 per connection) and notification throughput. For high-frequency programs, use confirmed commitment (faster) instead of finalized, apply tighter memcmp filters to reduce notification volume, or distribute subscriptions across multiple connections. Consider HTTP getProgramAccounts for initial snapshot.

How do memcmp filters work and what's the offset for token owner?

memcmp compares bytes at specified offset. For SPL Token accounts: offset 0 = mint (32 bytes), offset 32 = owner (32 bytes), offset 64 = amount (8 bytes). Use offset 32 + base58 owner pubkey to filter by token owner. Filters combine with AND logic—multiple memcmp filters must all match.

Should I use programSubscribe or getProgramAccounts for initial data load?

Use getProgramAccounts for initial snapshot (1000-10000+ accounts), then programSubscribe for real-time updates. getProgramAccounts is single HTTP call returning all matches; programSubscribe is WebSocket streaming only changes. Common pattern: snapshot on load, subscribe for live updates, unsubscribe on unmount.

programUnsubscribe
Cancel a programSubscribe subscription by subscription ID. Essential for cleanup to prevent memory leaks and excessive RPC node load. Always call in component unmount or before closing WebSocket.

accountSubscribe
Subscribe to a single specific account instead of all accounts in a program. Use when monitoring one known account rather than filtering program-wide. More efficient for 1-5 specific accounts; programSubscribe better for 10+ accounts or dynamic discovery.

getProgramAccounts
HTTP method to get a snapshot of all program accounts at a specific time. Use for initial state, then programSubscribe for real-time updates. Common pattern: getProgramAccounts (snapshot) → programSubscribe (live changes) → programUnsubscribe (cleanup).

logsSubscribe
Subscribe to transaction logs mentioning a program instead of account state changes. Use logsSubscribe for transaction monitoring (swaps, transfers, errors); use programSubscribe for account state tracking (balances, positions). Often used together for comprehensive program monitoring.

slotSubscribe
Get slot progression notifications to track when program account updates occur relative to chain state. Combine with programSubscribe to correlate account changes with specific slots for timing analysis or MEV detection.

External Resources

  • Solana Official Documentation
  • Anza agave: RPC PubSub Implementation - Official validator source code showing how WebSocket subscriptions are implemented, including programSubscribe filter processing, AND logic, commitment handling, and notification generation. Essential for understanding server-side filter behavior and limitations.
  • Solana RPC: getProgramAccounts Filter Examples - Official RPC documentation showing memcmp filter syntax with examples. Demonstrates dataSize and memcmp offset/bytes structure. Same filter format used by programSubscribe—use for filtering by account data patterns (e.g., token owner at offset 32).