Solana priority fees in 2026: CU price, Jito tips, or both?
Solana priority fees in 2026 — when to use compute unit pricing, when Jito tips, when both. A practical recipe with the numbers that matter.
For roughly two years, "Solana transaction landed or it didn't" was the entire fee conversation. That stopped in 2024 when local fee markets, Jito tips, and stake-weighted QoS turned transaction landing into an auction with three different bidding mechanisms. By 2026 the landscape has settled enough to write down what actually works.
There are three knobs. You combine them based on what kind of transaction you're sending.
The three knobs
1. Base fee. 5,000 lamports per signature. Not optional, not negotiable. Negligible.
2. Compute unit price. A bid (in micro-lamports per CU) for inclusion in the next block. Set via the ComputeBudgetProgram.setComputeUnitPrice instruction. Validators sort the mempool by this price within each write-locked account. This is your local-fee-market bid.
3. Jito tip. A transfer to a Jito tip account inside a bundle. The Jito-Solana validator client (currently ~88% of stake) sorts bundles by tip when building blocks. Tips have to clear a minimum (~1000 lamports) to be considered.
The decision tree
Regular consumer transaction (user sending tokens, approving a swap, claiming an airdrop):
- Set CU price based on current network conditions.
- Don't bother with Jito tips — overhead doesn't pay off.
- Use Helius' or Triton's priority fee API to estimate.
Latency-critical transaction (arbitrage, liquidation, winning a launchpad mint):
- Submit through a Jito Block Engine endpoint as a bundle.
- Pay both: CU price for non-Jito validators, Jito tip for Jito validators.
- Skip the public mempool entirely — you don't want frontrunners.
High-volume batched transactions (oracle pushes, protocol cranks, recurring jobs):
- Bundle 5 transactions into a Jito bundle, one tip pays for all five.
- Modest CU price as a fallback for non-Jito blocks.
- Submit via stake-weighted QoS if you have validator relationships.
Setting CU price properly
The recipe most apps get wrong: setting a single fixed CU price for every transaction. The price you need varies by 100x across network conditions and by the specific accounts you're writing to. Always query a live estimator:
// Helius priority fee estimator
const res = await fetch("https://mainnet.helius-rpc.com/?api-key=...", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
jsonrpc: "2.0",
id: 1,
method: "getPriorityFeeEstimate",
params: [{
transaction: bs58.encode(tx.serialize()),
options: { priorityLevel: "High", recommended: true },
}],
}),
})
const { result: { priorityFeeEstimate } } = await res.json()
// Then attach the compute budget instructions
import { ComputeBudgetProgram } from "@solana/web3.js"
const ixs = [
ComputeBudgetProgram.setComputeUnitLimit({ units: 200_000 }),
ComputeBudgetProgram.setComputeUnitPrice({ microLamports: Math.ceil(priorityFeeEstimate) }),
...yourInstructions,
]Two important details:
- Set the CU limit explicitly. The default is 200k × instruction count, almost always too high. Simulate, take actual usage + 10% buffer, set the limit. You're paying for allocated CUs whether you use them or not.
- Re-estimate per transaction. Network conditions shift in seconds. A fee that worked at 14:00 may be 10x too low at 14:02 during a spike.
Jito tip floor and the bundle approach
For latency-critical work, the model flips. You're not bidding for inclusion — you're bidding for ordering and atomicity. Jito bundles let you guarantee a sequence of transactions land in order within one block, or none of them do. The tip is your bid for that atomicity:
import { SystemProgram } from "@solana/web3.js"
const JITO_TIP_ACCOUNTS = [
"96gYZGLnJYVFmbjzopPSU6QiEV5fGqZNyN9nmNhvrZU5",
"HFqU5x63VTqvQss8hp11i4wVV8bD44PvwucfZ2bU7gRe",
// ...8 total, pick randomly per tx for load balancing
]
const tipIx = SystemProgram.transfer({
fromPubkey: payer.publicKey,
toPubkey: new PublicKey(JITO_TIP_ACCOUNTS[Math.floor(Math.random() * 8)]),
lamports: 100_000, // 0.0001 SOL — adjust based on current floor
})
// Tip is just another instruction. Bundle: [yourTx1, yourTx2, tipTx]
// Submit via sendBundle to a Block Engine endpoint:
// https://mainnet.block-engine.jito.wtf/api/v1/bundlesTip floor varies — the Jito tip stream usually publishes p50, p75, p95 percentiles. For most non-MEV work, p75 is enough. For competitive arb, p99.
Common mistakes
- Static CU price. If you wrote "10_000 micro-lamports" into a constant six months ago, you're either paying way too much or your transactions silently fail during congestion.
- Tipping Jito without bundling. A standalone transaction with a transfer to a Jito tip account doesn't confer any priority unless it's submitted as a bundle to a Block Engine endpoint.
- Not setting CU limit. You're paying for 1.4M CUs (the per-tx max) when you only need 200k. The CU price you set is multiplied by allocated, not used.
- Trusting a single RPC's fee estimate as gospel. Different providers see different mempools. Take the max of two providers if you really need to land.
References
The short version: CU price for normal traffic, Jito bundles when you need atomicity or ordering, both when you're fighting for a scarce slot. Whichever you pick, query the live estimate per transaction.