Solana is known for high throughput and low latency.
But if you are building:
- a block indexer
- a transaction decoder
- real-time analytics
- monitoring or alerting systems
you will quickly realize:
Streaming blocks on Solana is not just about speed —
it’s about managing uncertainty, data volume, and trade-offs.
This post walks through:
- how block streaming actually works on Solana
- the main streaming approaches
- why RPC latency becomes a bottleneck
- and why commitment level choices matter more than you think
Solana does not really stream “blocks”
Solana is slot-based, not block-based.
Some important consequences:
- a slot occurs roughly every ~400ms
- not every slot produces a block
- blocks may arrive late
- confirmation levels change what data you receive
So when people talk about block streaming on Solana,
they are really talking about:
streaming execution results derived from slots, under different guarantees
Every streaming approach is just a different way to deal with this reality.
The three main block streaming approaches on Solana
1. RPC polling: latest slot → fetch block
The most basic approach:
- call
getSlot - fetch block data for that slot: getBlock / getParsedBlock
- decode transactions and instructions
This is often the first implementation.
Why it looks appealing
- simple to reason about
- no persistent connections
- easy to prototype
Why it breaks at scale
- slots can be skipped
- blocks may not exist yet
- retries are frequent
- RPC rate limits are hit quickly
- Large transactions, instruction data cause high latency
You end up building:
- retry loops
- backfill logic
- slot-to-block reconciliation
At low volume, it works.
At scale, it becomes fragile and expensive.
2. WebSocket streaming: blockSubscribe
A more event-driven approach:
- subscribe via WebSocket
- receive blocks pushed from the RPC node
- choose commitment level (
confirmedorfinalized)
This feels closer to traditional block streaming.
Pros
- fewer RPC round-trips
- lower latency than polling
- simpler flow control
- fewer RPC call
Cons
- typically limited to
confirmedandfinalized -
processedis usually unavailable or unreliable - blocks may still be partial: may miss some instructions / inner instructions
- provider behavior varies
You gain safety and simplicity,
but sacrifice ultra-low latency.
3. Validator-level streaming: Geyser gRPC
The most powerful — and most complex — option.
With a Geyser plugin:
- data is streamed directly from validators
- no RPC bottlenecks
- near-zero latency
- full instruction visibility
This is how serious Solana data platforms operate.
Pros
- highest completeness
- predictable performance
- minimal retries
- very low latency
Cons
- requires validator access or partnerships
- more complex infrastructure
- higher operational cost
Geyser does not remove complexity —
it moves it into infrastructure, where it belongs.
The hidden cost: Solana block data is large
One of the most underestimated aspects of Solana streaming is data volume.
A single Solana block can contain:
- hundreds or thousands of transactions
- deeply nested instructions
- large inner instruction trees
- verbose account metadata
This has direct performance consequences.
RPC latency becomes the bottleneck
When fetching blocks via RPC:
- response payloads are large
- serialization and deserialization are expensive
- network transfer dominates end-to-end latency
In practice:
-
getBlockoften takes hundreds of milliseconds - under load, it can reach seconds
- retries amplify the cost
Even with a fast decoder,
you are often waiting on the wire.
Why polling amplifies latency problems
A typical polling loop looks like:
getSlotgetBlock- retry if missing
- refetch if commitment changes
Now combine that with:
- skipped slots
- partial blocks
- confirmation re-checks
The result:
- high tail latency
- uneven block arrival
- backpressure in your pipeline
- escalating RPC costs
This is why many Solana indexers feel:
fast in tests, unstable in production
Commitment levels are not just a setting
Every Solana streaming setup must answer one question:
How wrong am I willing to be, and for how long?
Geyser gRPC: fast and stable at processed
With Geyser:
- data comes directly from the validator execution path
-
processedcommitment is commonly used in practice - latency is extremely low
- stream stability is high
Because execution data is emitted immediately:
- blocks arrive consistently
- instruction data is complete
- reprocessing logic is predictable
In practice, Geyser + processed is often:
- the fastest
- and the most operationally stable streaming setup on Solana.
This is ideal for:
- real-time decoding
- monitoring systems
- low-latency analytics
- applications that tolerate short-lived reorgs
WebSocket blockSubscribe: safer, but slower
In contrast, blockSubscribe typically:
- supports only
confirmedandfinalized - does not reliably expose
processed - varies across RPC providers
This leads to:
- higher end-to-end latency
- fewer reorgs
- simpler correction logic
It is safer,
but fundamentally different from validator-level streaming.
Streaming doesn’t remove the cost — it shifts it
WebSocket and Geyser reduce:
- redundant RPC calls
- polling overhead
But they do not change the core reality:
- transaction + instruction data is large
- decoding cost is unavoidable
- memory pressure is real
On Solana, data size is part of the protocol design, not an implementation detail.
How txdecoder.xyz handles Solana block streaming in practice
At txdecoder.xyz, we treat Solana block streaming as an infrastructure problem, not just an API choice.
Our production setup uses a hybrid streaming architecture:
- multiple Geyser gRPC block streaming workers as the primary data source
- an additional WebSocket
blockSubscribeworker as a fallback path
Why multiple Geyser gRPC workers
Geyser gRPC is:
- the fastest option
- the most complete in terms of instruction data
- stable enough to run at
processedcommitment
But like any long-lived stream:
- connections can drop
- validators can restart
- transient network issues do happen
To handle this, we:
- run multiple independent Geyser streaming workers
- de-duplicate blocks downstream
- treat each worker as a non-authoritative source
This gives us:
- higher availability
- predictable latency
- graceful degradation instead of hard failure
WebSocket streaming as a safety net
In addition to Geyser, we maintain a WebSocket blockSubscribe worker:
- used as a backup when gRPC streams disconnect
- typically running at
confirmedorfinalized - slower, but more resilient across providers
The WebSocket path is not the primary data source —
it exists to ensure:
- no long blind spots
- smoother recovery
- continuity during validator-level disruptions
The key idea: redundancy over perfection
On Solana, no single streaming method is perfect.
Instead of chasing one “ideal” solution, we:
- combine multiple imperfect streams
- accept short-lived inconsistencies
- resolve them deterministically downstream
This approach allows txdecoder.xyz to:
- stay low-latency under normal conditions
- remain correct under failure
- and avoid catastrophic data gaps
On Solana, resilience is a feature you have to build yourself.
Final takeaway
Solana block streaming is not hard because Solana is “bad”.
It is hard because Solana optimizes for:
- throughput
- parallel execution
- low confirmation latency
Those choices push complexity downstream.
If you are building Solana data infrastructure,
you are not just streaming blocks —
you are managing uncertainty, volume, and trade-offs.
There is no perfect approach.
Only conscious ones.
About txdecoder.xyz
Transaction decoding API — standardizing blockchain data into one unified, readable schema on Ethereum, Base, BSC, Solana
Website: https://txdecoder.xyz/
X: https://x.com/txdecoder_xyz
Telegram: https://t.me/txdecoder
Telegram channel: https://t.me/txdecoder_announcements
Blog: https://medium.com/@txdecoder
Top comments (0)