What happens when a solana program exhausts its compute budget?
A Solana program that runs out of compute budget fails immediately with a ProgramFailedToComplete error. The transaction is rolled back entirely - no state changes are applied, no tokens move, and the account modifications you attempted are discarded. The fees you paid for the transaction are still forfeited to the network.
The compute budget mechanism
Every Solana transaction starts with a fixed compute budget of 200,000 compute units (CU) by default. This budget caps the total amount of computational work the transaction's instructions can perform. When you don't explicitly set a compute unit limit, the 200,000 CU default applies.
Programs consume compute units for each operation they execute: arithmetic, memory access, cross-program invocations, account lookups, and log emissions. The Solana runtime tracks consumption in real time. The moment the running total gets to the budget, the runtime terminates the program with the error.
What the error looks like
When a program runs into the limit, you see an error message like:
Error: Instruction 0 of the transaction failed: ProgramFailedToComplete
The ProgramFailedToComplete error is distinct from other transaction failures. It does not mean the program logic threw an exception or returned a Result::Err. It means the program simply ran out of gas mid-execution - no cleanup, no partial commit.
What actually gets lost
This is the critical point: everything. Solana transactions are atomic. If any instruction in the transaction fails - including an out-of-budget failure - the entire transaction's state changes are reverted. The accounts you modified go back to their pre-transaction state. Tokens you were transferring never move.
What you do not get back: the transaction fee. The base fee and any priority fee you included are consumed by the validator that processed the block, regardless of whether the transaction succeeded or failed. The compute budget exhaustion does not refund fees.
Why this happens in practice
Programs run out of compute budget for a few common reasons:
- Processing too many accounts - Each account loaded during execution consumes compute units. A program that iterates over hundreds of accounts can exhaust the budget quickly.
- Heavy cryptography - Operations like signature verification or hashing burn compute units faster than arithmetic.
- Infinite loops or recursion - A bug that causes unbounded iteration runs into the limit every time.
- Overly optimistic compute unit estimates - Developers sometimes underestimate the cost of a program's logic, especially when using CPI (cross-program invocation) calls that themselves consume compute.
How to prevent it
You have two levers to adjust compute budget behavior.
-
Set a higher compute unit limit. When building a transaction, you can request up to 1,400,000 compute units per transaction. This is done by including an explicit
SetComputeUnitLimitinstruction before your program instructions. The default 200,000 CU is often too low for complex programs. -
Estimate and adjust. Use the
getRecentPerformanceSamplesRPC method or your local test environment to measure how many compute units your program actually consumes. Then set the limit slightly above that value. Overestimating costs you priority fees but avoids failure. -
Optimize program logic. Reduce the number of accounts loaded per instruction. Batch operations into fewer instructions. Avoid unnecessary cross-program invocations. Use
sol_logsparingly, as logging is expensive. -
Test with simulated compute budgets. During development, run your program with
--compute-unit-limitin the Solana test validator to confirm it fits within your target budget.
What to do when it happens
If your transaction fails with ProgramFailedToComplete:
- Check the compute unit consumption on a recent successful run using the transaction logs. Look for the
consumedfield in the transaction metadata. - Increase the compute unit limit in your transaction construction code. If you were using the default, bump it to 400,000 or higher.
- Verify your program does not have an unbounded loop. Run a static analysis or add iteration counters.
- Consider splitting your operation across multiple transactions if it genuinely requires more than 1,400,000 CU. That is the absolute maximum per transaction.
A note on priority fees
Raising the compute unit limit does not guarantee your transaction will have enough budget - it only sets the cap. You also need to set the priority fee high enough that the validator actually includes your transaction in a block, especially during network congestion. A transaction with a high compute limit but low priority fee may still fail because it never gets confirmed, or because it gets included but the budget runs out mid-execution. The compute unit limit and priority fee are independent settings; both matter.
Not financial advice. orymsolana.xyz publishes market data and general information about digital assets. Crypto assets are volatile and you can lose everything you put in. Nothing here is a recommendation to buy, sell or hold, and we make no price predictions.
Prices are sourced from third parties and may be delayed or wrong. Verify anything you intend to act on against a primary source.