Overview
getProgramAccountsV2 is an enhanced version of the standard getProgramAccounts method, designed for applications that need to efficiently query large sets of accounts owned by specific Solana programs. This method introduces cursor-based pagination and incremental update capabilities.
New Features in V2:
Cursor-based pagination : Configure limits from 1 to 10,000 accounts per request
Incremental updates : Use changedSinceSlot to fetch only recently modified accounts
Better performance : Prevents timeouts and reduces memory usage for large datasets
Backward compatibility : Supports all existing getProgramAccounts parameters
Key Benefits
Scalable Queries Handle programs with millions of accounts by paginating through results efficiently
Real-time Sync Use changedSinceSlot for incremental updates and real-time data synchronization
Prevent Timeouts Large queries that previously timed out now work reliably with pagination
Memory Efficient Process data in chunks instead of loading everything into memory at once
Important Pagination Behavior : End of pagination is only indicated when no accounts are returned . The API may return fewer accounts than your limit due to filtering - always continue pagination until paginationKey is null.
let allAccounts = [];
let paginationKey = null ;
do {
const response = await fetch ( `https://mainnet.helius-rpc.com/?api-key= ${ API_KEY } ` , {
method: 'POST' ,
headers: { 'Content-Type' : 'application/json' },
body: JSON . stringify ({
jsonrpc: '2.0' ,
id: '1' ,
method: 'getProgramAccountsV2' ,
params: [
"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" ,
{
encoding: 'base64' ,
filters: [{ dataSize: 165 }],
limit: 5000 ,
... ( paginationKey && { paginationKey })
}
]
})
});
const data = await response . json ();
allAccounts . push ( ... data . result . accounts );
paginationKey = data . result . paginationKey ;
} while ( paginationKey );
Incremental Updates
// Get only accounts modified since slot 150000000
const incrementalUpdate = await fetch ( `https://mainnet.helius-rpc.com/?api-key= ${ API_KEY } ` , {
method: 'POST' ,
headers: { 'Content-Type' : 'application/json' },
body: JSON . stringify ({
jsonrpc: '2.0' ,
id: '1' ,
method: 'getProgramAccountsV2' ,
params: [
programId ,
{
encoding: 'jsonParsed' ,
limit: 1000 ,
changedSinceSlot: 150000000
}
]
})
});
Optimal Limit Size : For most use cases, a limit of 1,000-5,000 accounts per request provides the best balance of performance and reliability.
Start with smaller limits (1000) and increase based on your network performance
Use appropriate encoding : jsonParsed for convenience, base64 for performance
Apply filters to reduce the dataset size before pagination
Store paginationKey to resume queries if interrupted
Monitor response times and adjust limits accordingly
Migration from getProgramAccounts
Migrating from the original method is straightforward - simply replace the method name and add pagination parameters:
{
"jsonrpc": "2.0",
"id": "1",
- "method": "getProgramAccounts",
+ "method": "getProgramAccountsV2",
"params": [
"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
{
"encoding": "base64",
"filters": [{ "dataSize": 165 }],
+ "limit": 5000
}
]
}
Request Parameters
The Solana program public key (address) to query accounts for, as a base-58 encoded string.
The commitment level for the request.
confirmed
finalized
processed
The minimum slot that the request can be evaluated at.
Wrap the result in an RpcResponse JSON object.
Encoding format for the returned account data.
jsonParsed
base58
base64
base64+zstd
Request a slice of the account’s data.
Number of bytes to return.
Byte offset from which to start reading.
Maximum number of accounts to return per request (1-10,000).
Base-58 encoded pagination cursor for fetching subsequent pages. Use the paginationKey from previous response.
Only return accounts that were modified at or after this slot number. Useful for incremental updates.
Powerful filtering system to efficiently query specific Solana account data patterns.
Your Helius API key. You can get one for free in the dashboard .
jsonrpc
enum<string>
default: 2.0
required
The JSON-RPC protocol version.
A unique identifier for the request.
method
enum<string>
default: getProgramAccountsV2
required
The name of the RPC method to invoke.
Available options:
getProgramAccountsV2
params
(string | object)[]
required
Parameters for the enhanced paginated method.
The Solana program public key (address) to query accounts for, as a base-58 encoded string.
Example: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
Successfully retrieved paginated program accounts.
The JSON-RPC protocol version.
Identifier matching the request.
Paginated program accounts with navigation metadata.