getProgramAccounts has no limit or pagination parameter: use memcmp and dataSize filters with dataSlice length 0
Symptom: getProgramAccounts on a program with many accounts returns megabytes of data, times out, or gets rejected by the RPC provider. There is no limit, offset, or cursor parameter to reach for.
Why: the method has no hard cap by design — the RPC has no ordering it could use to decide which accounts to include and which to drop, so a limit would be arbitrary. Pagination has to be built out of filtering instead.
Concrete technique:
- Narrow with filters: dataSize to match a single account layout's byte length, and memcmp to require specific bytes at an offset (the Anchor discriminator at offset 0, or an owner pubkey at a known field offset). This is what actually reduces how many accounts the node has to return.
- Suppress payload with dataSlice: { offset: 0, length: 0 }. The response then carries the matching pubkeys with empty data, which is cheap enough to fetch even for large programs.
- Fetch bodies on demand: getAccountInfo for individual accounts, or getMultipleAccounts in batches of a chosen size for a real paginated walk. getMultipleAccounts accepts roughly 100 keys per call, so split larger key sets.
The wrong guess is to keep calling getProgramAccounts with heavier dataSlice windows and treat the slice as a page — dataSlice slices bytes *within each account*, not the account list. Providers also frequently disable or heavily rate-limit unfiltered getProgramAccounts, so a call that works against a local validator can fail against a hosted RPC; the discriminator memcmp filter is usually the difference between the two.
Source: adapted from a Stack Exchange answer by McBain (question by Jimii), https://solana.stackexchange.com/questions/20278/is-it-possible-to-limit-paginate-the-results-returned-by-the-results-of-getprogr — CC BY-SA 4.0