Blog » Solana Transaction Confirmation – All you need you know

Solana Transaction Confirmation – All you need you know

6 min read

The Solana blockchain has quickly emerged as a strong contender in the world of decentralized finance and digital assets due to its impressive speed, low fees, and scalability. As a result, more and more users are entering the Solana ecosystem, seeking reliable and secure wallets to manage their SOL tokens, stake their assets, and interact with Solana-based applications. Selecting the best Solana wallet is essential for a seamless experience, as well as ensuring the safety of your digital assets.

Encountering transaction confirmation issues is a widespread challenge for novice developers when creating applications on the Solana blockchain. This article is dedicated to enhancing your grasp of Solana’s transaction confirmation mechanism, while also providing valuable best practices for a smoother development experience.

Table of Contents:

  • Transaction confirmation lifecycle
  • Blockhash and commitment levels
  • Transaction expiration
  • Automatic retries by OMNIA RPC
  • Conclusions

Transaction lifecycle and confirmation

Below is a high level view of the lifecycle of a transaction. Steps 5-6 are critical because in times of network congestion it might cause transactions being dropped.

  1. Client creates a list of instructions along with the list of accounts that instructions need to read and write
  2. Fetch a recent blockhash and use it to prepare a transaction message
  3. Simulate the transaction (client side, i.e. within web3 library) to ensure it behaves as expected
  4. Prompt user to sign the prepared transaction message with their private key
  5. Send the transaction to an RPC node which attempts to forward it to the current block producer (see diagram below)
  6. Hope that a block producer does not drop the transactions but also that validates and commits the transaction into their produced block
  7. Confirm the transaction has either been included in a block or detect when it has expired

Blockhash and commitment levels

In step 2 above we mentioned that clients fetches a recent blockhash. Let’s dive into the details of this step.

What is a Blockhash?

A “blockhash” refers to the last Proof of History (PoH) hash for a “slot” (see table below). Since Solana uses PoH as a trusted clock, a transaction’s recent blockhash can be thought of as a timestamp!

UnitEquivalent to…Use case
Hashn/aTrusted source of time and a historical record of processed transaction ids.
Tick12,500 hashesTick hashes are shared to validators so that they can quickly verify a blockhash in parallel.
Slot64 ticks (or 800,00 hashes)Each slot is assigned to a staked validator from the leader schedule to give them a turn to produce a block for that slot.
Epoch432,000 slotsLength of leader schedule

When fetching a recent blockhash, the client also must choose the comitment level desired. Let’s go through this below.

Commitment level

The commitment level measures the network confirmation for a specific block.

There are three specific commitment statuses:
* finalized – This is the highest level of commitment and transactions are irreversible. The RPC node will query the most recent block confirmed by the supermajority of the cluster as having reached maximum lockout, meaning the cluster has recognized this block as finalized. Transactions at this level also tend to have a higher transaction fee.
* confirmed – This commitment level is usually used for transactions that have been included in a block, but have not yet been confirmed by the network. The node will query the most recent block that has been voted on by the supermajority of the cluster (optimistic confirmation)
* processed – Here, the node will query its most recent block but the block may still be skipped by the cluster if the transaction fails. This is the least secure of all the three levels and transactions in this level are usually used for testing and development purposes and are not recommended for use in production environments.

As you can see, the natural state of progression for commitment levels on Solana is: 

processed → confirmed → finalized.

In general, the higher the commitment level of a transaction, the more secure it is and the less likely it is to be reversed.

Received blockXXX
Block on majority forkXXX
Block contains target txXXX
66%+ stake voted on blockXX
31+ confirmed blocks built atop blockX

Official Solana recommendation: Use confirmed commitment when fetching recent blockhash. This will provide a better (extended with aprox. 13s) time window as compared to finalized commitment, thus reducing the risk of transaction expiration (see below).

Obs: On average 5% of the transactions would be part of a fork & would potentially be dropped (as opposed to finalized commitment where 0% chance of being part of fork – at the cost of potential unstability under network congestion). This represents the trade-off between stability during network congestion and avoiding processing transactions that are actually dropped later on because of forks.

Pro tip from OMNIA: preflight & getLatestBlockhash commitment must be set to same level in order to allow RPC node to perform the retry normally, according to node’s open source code. Otherwise the default behavior of node software is “fire & forget”.
Alternatively, you can set your personalized maxRetries parameter that will be used by the RPC node when forwarding transaction to block builder.

Transaction Expiration

By default, all Solana transactions will expire if not committed to a block (referenced via blockhash used in step 2 from above transaction lifecycle) in a certain amount of time. A solid understanding of how transaction expiration works should help you diagnose the bulk of your transaction confirmation issues. 

Why do transactions expire?

There’s a very good reason for this actually – it’s to help validators avoid processing the same transaction twice.
A naive brute force approach to prevent double processing could be to check every new transaction against the blockchain’s entire transaction history. But by having transactions expire after a short amount of time, validators only need to check if a new transaction is in a relatively small set of recently processed transactions.

How does transaction expiration work?

Each transaction includes a recent blockhash which is used as a PoH clock timestamp (see above) and expires when that blockhash is no longer recent enough.
More concretely, Solana validators look up the corresponding slot number for each transaction’s blockhash that they wish to process in a block. If the validator can’t find a slot number for the blockhash or if the looked up slot number is more than 151 slots lower than the slot number of the block being processed, the transaction will be rejected.
Slots are configured to last about 400ms but often fluctuate between 400ms and 600ms, so

a given blockhash can only be used by transactions for about 60 to 90 seconds.

Transaction confirmation tips

As mentioned before, blockhashes expire after a time period of only 151 slots which can pass as quickly as one minute when slots are processed within the target time of 400ms. One minute is not a lot of time considering that a client needs to fetch a recent blockhash, wait for the user to sign, and finally hope that the broadcasted transaction reaches a leader that is willing to accept it.

Let’s go through some tips to help avoid confirmation failures due to transaction expiration!

  • Avoid reusing stale blockhashes – even if your application has fetched a very recent blockhash, be sure that you’re not reusing that blockhash in transactions for too long. The ideal scenario is that a recent blockhash is fetched right before a user signs their transaction.
  • Use healthy RPC nodes when fetching blockhashes – get your Solana endpoint from OMNIA Dashboard
  • Implement retries in your app or wallet (details below)

      Retrying transactions

      When talking about retries there are 2 main categories of actions:

      • Resigning transactions ( can only be implemented by the wallets who have access to private key)
        • When calling getLatestBlockhash RPC API to get a recent blockhash for your transaction, take note of the "lastValidBlockHeight" in the response. Then, poll the getBlockHeight RPC API with the confirmed commitment level until it returns a block height greater than the previously returned last valid block height – at this stage the blockhash used when first signing the transaction expired and requires fetching a new recent blockhash and re-signing the transaction.
        • An alternative to this would be the use of durable transactions
      • Re-broadcasting the transaction during the time window when blockhash is still valid. This can be implemented either by the application or at the RPC provider level itself.
        • While RPC nodes will attempt to rebroadcast transactions, the algorithm they employ is generic and often ill-suited for the needs of specific applications. To prepare for times of network congestion, application developers should customize their own rebroadcasting logic.
        • OMNIA RPC benefits from the reinforced transaction logic – meaning that Solana transactions are automatically re-broadcasted towards block builder during the blockhash validity time window, thus improving the stability and reducing the probability of a transaction being dropped due to network congestion or unreliable underlying UDP channel.


      • Make sure to always fetch a fresh blockhash just before user signs the transaction
      • If transaction not confirmed during blockhash validity then it requires re-signing the transaction with a fresh blockhash or use durable transactions instead
      • Implement re-broadcasting or use OMNIA RPC who does this by default – get your RPC endpoint at
      • Use RPC providers that are reliable – OMNIA RPC also leverages nodes that have stake, thus

      Written by:

      Get Started
      Contact Us Today

      Want learn about subscription plans or integrating our services into your project

      Contact Us