- Solana reports two metrics: slots, which are scheduled opportunities to produce a block, and blocks, which only increment when a block is actually produced.
- This leads to a discrepancy: the slot count typically exceeds the block count by millions because many slots go unfilled.
- For transaction expiry, Solana uses block height (150 blocks), not slots, so empty slots do not affect how long your transaction remains valid.
- Be mindful that RPC calls and explorers often mix the terminology, so always verify whether you’re dealing with a slot or a block.
Main article
Solana’s architecture can be a bit confusing at first glance—especially when you notice that the chain reports two different numbers for blocks and slots. Understanding how these concepts differ is key to interpreting the output of Solana’s RPC methods correctly. In this article, we’ll walk through:- What a slot is.
- What a block is.
- Why slot numbers and block numbers differ (sometimes by millions).
- How this affects transaction validity, especially when using the
getLatestBlockhash
RPC call.
What is a Solana slot?
A slot is essentially a scheduled spot for a validator to produce a block. Solana runs on a proof-of-stake model (it’s proof-of-history with a lot of modifications, but for this article’s context it’s the underlying proof-of-stake model that matters), where validators take turns producing blocks in these scheduled slots. However, a validator may not produce a block for each slot. When a slot is missed (i.e., no block is produced), it still counts toward the slot count, but it does not generate a corresponding block. So you can think of each slot as:A timeslot allocated for a potential block.
What is a Solana block?
A block is only created if the validator assigned to the slot actually produces a block. Blocks contain the transactions, state changes, and other essential data that get committed to the chain. Because not every slot results in a block, the total block count tends to lag behind the slot count. This is why block heights and slot heights almost always diverge—and can differ by millions. In the past, there have been observations that some Solana validators had the incentives and the means to skip block production for some slots in return for a higher reward. This seems to have been fixed since then. You can read about it here: Everstake claims some validators were optimized to skip block production. If you’ve been on Solana for some time, you’ll remember a few network outages. These have also contributed to the block vs slot numbers disparity. As the network halted and no blocks were produced, the slots kept incrementing. As an example, let’s take the very first outage of September 14, 2021—it lasted for 17 hours and was restarted around block96542804
.
So if we take a few blocks before that, we’ll see that there are empty slots with not blocks produced:
You can also run a getBlock | Solana call and provide the slot number and you’ll see that it’s missing. Note that you need a Chainstack Solana archive node to be able to make the call, since it’s a slot far in the past:
Example: Slot height vs. block height
As of January 1, 2025, here’s an example of Solana’s reported values:- Slot height:
311118891
- Block height:
289445888
Where this matters: getLatestBlockhash
method
The getLatestBlockhash
RPC method returns three key pieces of data:
slot
: The slot number at which the block hash was produced.blockhash
: The latest block hash to use for a new transaction.lastValidBlockHeight
: The block height until which the transaction is considered valid before expiring (150 blocks from the “current” block height).
- The
"slot": 311115149
matches the slot height. - The
"lastValidBlockHeight": 289442306
is about 22 million behind the slot number.
How Solana decides transaction validity
Solana nodes consider 150 blocks to determine if a transaction is still valid. Specifically, a transaction lives in the pending pool until the chain surpasseslastValidBlockHeight
. After 150 blocks have passed from the latest block height at the time of your transaction creation, your transaction is dropped if it wasn’t included.
Importantly:
- Blocks, not slots, are used in these calculations.
- If some slots are empty, they do not count toward that total of 150—because no block was produced there!
lastValidBlockHeight
, it’s really telling you: “You have until block N + 150 to have your transaction included on-chain.”
Quick illustration with getBlock
Let’s do a getBlock
call using the slot number from our getLatestBlockhash
example above:
- The slot passed in as a parameter is
311115149
. - The block height returned is
289442156
.
289442156
with our lastValidBlockHeight
(289442306
), you’ll see there’s exactly a difference of 150 blocks—just as expected for the transaction validity window.
Getting the latest slot vs. the latest block
- getSlot | Solana gives you the latest slot height.
- getBlockHeight | Solanagives you the latest block height.
- getBlockTime | Solana gives you the latest block time but you need to use the slot as a parameter in the call. If you are not using an archive node, make sure you provide the slot that is about within the last 24 hours.
Common pitfalls
-
Mistaking a slot for a block Many Solana explorers incorrectly label URLs or pages with the word “block” while they’re actually referencing a slot. For instance:
- Solscan’s URL might say
block/311115149
, but that number is a slot. - The official Solana explorer also says
block/311115149
, but again, it’s a slot, not a block.
- Solscan’s URL might say
- Transaction expiration If you assume 150 slots for expiration instead of 150 blocks, you’ll miscalculate how long your transaction can remain in the mempool. In reality, empty slots do not affect transaction expiry. Only blocks do.
-
RPC naming confusion The
getBlock
method uses a slot number as its parameter. But the response includes the block height (blockHeight
). Don’t let the naming fool you—this is a “fetch block by slot” call.
Why slot and block numbers are always different
- Slots: Every slot increments by one whether or not a block is produced.
- Blocks: Only increment when a block is actually produced.