Skip to main content
TLDR:
  • getBlock is a core Solana RPC method that can dramatically impact performance if misused; don’t pull more data than you need.
  • Use json, jsonParsed, base58, or base64 encoding strategically; always enable compression (gzip) to reduce huge payloads.
  • Apply concurrency limits, caching, and backoff retry logic to avoid node overload and handle network hiccups gracefully.
  • Use robust error handling and consider block ranges for larger-scale data fetches.

Main article

Solana’s getBlock RPC method is a fundamental method that can be tricky and will screw up your application performance in a jiffy if you are not paying attention. This guide provides a comprehensive overview of how to use getBlock efficiently, with practical examples in Python and curl.

Get your own node endpoint today

Start for free and get your app to production levels immediately. No credit card required.You can sign up with your GitHub, X, Google, or Microsoft account.

Understanding getBlock

The getBlock method returns detailed information about a confirmed block in Solana’s ledger. A block in Solana contains:
  • A set of transactions
  • Metadata like block hash, previous block hash
  • Timing information
  • Reward data
If you think you have a grasp now, check out Understanding the difference between blocks and slots on Solana. Solana is amazing but not for the faint heart.

What data does getBlock return?

A typical response includes:
  • blockhash — the unique hash (ID) of this block (base-58 encoded)
  • previousBlockhash — the hash of the parent block
  • parentSlot — the slot number of the parent block
  • blockHeight — the sequential block height (the number of blocks beneath this block)
  • blockTime — the timestamp when the block was produced, which is yet another trick. See Solana: Understanding block time.
  • transactions — an array of transactions in the block (if requested)
  • signatures — an array of transaction signatures in the block (if requested)
  • rewards — an array of block rewards (if requested)

Parameters

When calling getBlock, you can specify several parameters to control what data you receive:
  • commitmentfinalized (default) or confirmed
  • encodingjson (default), jsonParsed, base64, or base58.
  • transactionDetailsfull (default), accounts, signatures, or none
  • rewards — boolean to include block rewards
  • maxSupportedTransactionVersion — for handling versioned transactions

Basic example with curl

Let’s start with the simplest way to fetch a block using curl:
This request fetches block 329849011 with full transaction details in JSON format. Note two things here:
  • We are using jsonParsed, which produces the largest output on the node side and gets transported to you. You should never do this in production with a heavy load. This more of a one-off inspection call than anything else.
  • If you are using a full and not an archive Solana node, use a block number within the last 20 hours or so. Otherwise this will be an archive call. See Limits at the bottom for the archive node methods availability.

Getting just the signatures

If you’re only interested in transaction signatures (hashes), which is much lighter:
Same note on the block number in params as above. Make sure you stay within the last 20 hours or so, unless you want to use an archive call, which is also fine as Chainstack is extremely affordable & transparent with pricing — a full node request is counted as one request, and an archive node request is counted as 2 requests, and that’s it.

Using compression (gzip) for better performance

HTTP compression is critical when working with Solana’s getBlock method due to the large size of block data. Here’s why compression is essential and how to implement it:

Why use compression

  1. Dramatic size reduction — Solana block data with full transaction details easily take several MBs in JSON format. Gzip compression typically reduces this by 70-90%, bringing it down to a few hundred KB.
  2. Faster response times — less data transmitted means faster responses, especially important when:
    • Working with blocks containing many transactions
    • Operating on networks with limited bandwidth
    • Fetching multiple blocks in sequence
  3. Reduced bandwidth costs — If you’re paying for bandwidth (e.g., in cloud environments), compression significantly reduces costs.
  4. Server-friendly — compression reduces load on both the RPC node and your client’s network connection.

Compression example with curl

Adding compression is simple with curl—just add the Accept-Encoding: gzip header and the --compressed flag:
When you run this command:
  1. The Accept-Encoding: gzip header tells the server you can handle compressed responses
  2. The server compresses the JSON data before sending it
  3. The --compressed flag tells curl to automatically decompress the data on receipt
  4. You see the normal JSON output, but the actual network transfer was much smaller

Understanding the compression process

Here’s what happens under the hood:
  1. Request — your client sends a request with Accept-Encoding: gzip
  2. Server processing — the server generates the JSON response
  3. Compression — the server compresses this data using gzip
  4. Transfer — the compressed data (much smaller) is sent over the network
  5. Decompression — your client decompresses the data
  6. Processing — you work with the original JSON data
Most HTTP libraries handle steps 1, 4, and 5 automatically when configured correctly.

Example of handling the compressed (gzip) data manually

For illustration purposes and to compare the actual size in compressed & decompressed state:
Decompress the block_data.gz file:
See the ~80% reduction in size when you compare block_data.gz to block_data.json.

Compression in HTTP libraries

Most modern HTTP libraries support compression automatically:
  • Python requests — add headers={"Accept-Encoding": "gzip"} or set requests.get(..., stream=True)
  • Node.js — most HTTP clients like Axios support this out of the box
  • Rust — libraries like reqwest have compression features
Using compression is one of the simplest and most effective optimizations when working with Solana’s getBlock RPC method, especially for blocks with many transactions. So use compression.

json, jsonParsed, base58, base64

When using Solana’s getBlock RPC method, you can request data in different encoding formats based on your specific needs. Note that when you are doing a getBlock call with "encoding": "base58" or "encoding": "base64", you are getting the respective encoding on the transaction level, not the entire block. In other words, you will still get back a JSON response, it’s only the transaction data that will be encoded in base58 or base64. Let’s explore each option:

json (default)

The json encoding provides transaction data in a standard JSON format with binary data encoded as base58 strings.
Best for: General use cases where you need a balance of readability and performance. Binary data remains encoded but the overall structure is easily parseable.

jsonParsed

The jsonParsed encoding goes beyond standard JSON by attempting to decode instruction data into human-readable format:
Best for:
  • Debugging and analysis where you need to understand transaction contents
  • Decoding program instructions without additional parsing work
  • Applications that display transaction details to users
Limitations — not all programs can be parsed as you need an IDL (similar to EVM’s ABIs) or source code, and response size is larger than other encodings.

base58

The base58 encoding returns binary data for transactions as base58-encoded strings:
Best for: Compatibility with tools that expect base58 encoding, which is common in Solana’s ecosystem.

base64

The base64 encoding returns binary data for transactions as base64-encoded strings:
Best for:
  • Performance-critical applications (base64 is more compact than base58)
  • Storage efficiency when saving transaction data
  • High-throughput systems processing many blocks

Encoding comparison

Python example with json, jsonParsed, base58, base64

First, install the package:pip install solana.
Here’s an example output:

Performance optimization

Examples in Python.

Limit concurrency and throttle requests

When fetching multiple blocks, avoid sending too many requests simultaneously:
As always, make sure you get your own range of blocks in slots_to_fetch = [329849011, 329849012, 329849013, 329849014, 329849015]. Recommended encodings:
  • For most use cases: json (good balance of size and parsing speed)
  • For human-readable data: jsonParsed (larger but provides decoded instruction data)
  • For binary efficiency: base64 (efficient for storage and transmission)

Use binary encoding for bulk requests

Same script as above, but in line 18 instead ofencoding="json" use encoding="base64".

Error handling

Let’s start with a working script and explain it below:

Exponential backoff retry mechanism

The code implements classic exponential backoff where:
  • Wait time grows exponentially with each retry attempt
  • Initial wait is 1 second
  • Each subsequent wait is multiplied by backoff factor with retry count
  • This prevents overwhelming the server with rapid reconnection attempts

Differential error handling

The script intelligently handles different error types:
  • Non-retryable errors (like purged blocks) fail fast without wasting retries
  • Temporary errors proceed with standard backoff
  • Rate limit errors get special treatment with doubled backoff

Enhanced rate limit handling

Rate limits receive special handling:
  • Doubled backoff time compared to other errors
  • This helps prevent repeatedly hitting rate limits
  • The multiplier (2x) helps ensure the client stays under rate limits

Comprehensive exception handling

The script catches all exceptions including:
  • Network errors
  • Timeout errors
  • Malformed response errors
  • Client library errors

Response validation

The code thoroughly validates responses before processing:
  • Checks for valid response structure
  • Handles null responses appropriately
  • Verifies response has expected attributes

Detailed logging

The script provides detailed logging:
  • Error messages with specific error codes and descriptions
  • Retry counts and wait times
  • Final outcomes (success or failure)
  • This aids in debugging and monitoring

Parameterized retry configuration

The retry mechanism is fully customizable:
  • Configurable maximum retries
  • Adjustable backoff factor
  • This allows tuning based on network conditions or application requirements
These techniques together create a resilient implementation that gracefully handles various network issues, temporary failures, and rate limiting while providing clear feedback about what’s happening during the process.

Client-side caching

Implement a client-side cache that stores previously fetched blocks in memory, allowing applications to:
  • Retrieve frequently accessed blocks without making additional RPC calls
  • Track cache performance with hit/miss statistics
  • Maintain a configurable maximum cache size
This should reduce unnecessary calls. Example:

Block ranges

Implement flexible block range handling through a range-first processing pattern — first identify all available blocks in the target range, then systematically process them in batches.

Conclusion

Working with Solana’s getBlock RPC method efficiently requires understanding both what data you need and how to optimize your requests. By following the best practices outlined in this guide—using compression, limiting concurrency, using block ranges, requesting only what you need, and implementing proper error handling—you can build robust applications that interact with Solana blocks effectively. Remember these key takeaways:
  1. Use the appropriate encoding and detail level for your use case — json, jsonParsed, base58, base64.
  2. Always enable HTTP compression.
  3. Implement client-side caching for frequently accessed blocks.
  4. Use controlled concurrency and throttling for bulk operations.
  5. Handle errors gracefully with retries and backoff.

Ake

Ake Director of Developer Experience @ Chainstack
Talk to me all things Web3
20 years in technology | 8+ years in Web3 full time years experience
Last modified on June 22, 2026