Priority Fee & Simulation APIs
Use getRecentPrioritizationFees, simulateTransaction, and provider fee APIs to estimate compute units and priority fees before sending transactions.
Recipe
Quick-reference recipe card - copy-paste ready.
import { createSolanaRpc, getBase64EncodedWireTransaction } from "@solana/kit";
const rpc = createSolanaRpc("https://api.mainnet-beta.solana.com");
await rpc.getRecentPrioritizationFees([]).send();
await rpc.simulateTransaction(encodedTx, {
commitment: "processed",
sigVerify: false,
}).send();When to reach for this:
- Setting dynamic priority fees from recent network percentiles.
- Estimating CU consumption to set compute budget instructions.
- Preflight checking custom program errors without landing.
- Debugging transaction failures in staging.
Working Example
import { createSolanaRpc } from "@solana/kit";
const rpc = createSolanaRpc(process.env.RPC_URL!);
// Recent priority fees for relevant accounts (empty = global sample)
const fees = await rpc.getRecentPrioritizationFees([]).send();
const recent = fees.map((f) => f.prioritizationFee).filter((n) => n > 0);
recent.sort((a, b) => a - b);
const p75 = recent[Math.floor(recent.length * 0.75)] ?? 0;
console.log("suggested microLamports CU price (p75):", p75);
// Simulate signed or partially signed tx (base64 wire)
const simulation = await rpc
.simulateTransaction("BASE64_WIRE_TX", {
commitment: "processed",
sigVerify: false,
replaceRecentBlockhash: true,
})
.send();
console.log("err:", simulation.value.err);
console.log("units:", simulation.value.unitsConsumed);
console.log("logs:", simulation.value.logs?.slice(0, 5));What this demonstrates:
- Priority fee RPC samples recent landed transactions for fee guidance.
- Simulation returns
unitsConsumedand logs without committing state (except when configured). replaceRecentBlockhashhelps simulate txs with expiring blockhashes.
Deep Dive
How It Works
- Priority fees are micro-lamports per compute unit paid to validators on top of base fee.
getRecentPrioritizationFeesreturns per-slot fee observations for account lock sets.simulateTransactionruns SVM against bank snapshot at chosen commitment.- Providers may expose enhanced
priorityFeeEstimateendpoints with percentile stats.
Simulation Options
| Option | Effect |
|---|---|
sigVerify: false | Faster sim, skips signature checks |
replaceRecentBlockhash | Refreshes blockhash for stale txs |
innerInstructions | Returns CPI breakdown |
accounts | Returns post-simulation account states |
TypeScript Notes
// After simulation, set compute budget ix with headroom
const units = simulation.value.unitsConsumed ?? 200_000;
const limit = Math.ceil(units * 1.1);
const microLamports = Math.max(p75, 1_000);Gotchas
- Simulation success ≠ landing - congestion and expired blockhashes still fail on send. Fix: combine with fresh blockhash and priority fee retries.
- Underpriced priority fee - simulation passes but tx drops. Fix: target 75th-90th percentile with cap.
- sigVerify false hiding signer errors - false positives. Fix: final preflight with
sigVerify: truebefore mainnet send. - Stale prioritization sample - fees spike during NFT mints. Fix: refresh fees per send batch.
- Ignoring unitsConsumed - default 200k CU limit may be too low. Fix: set explicit limit from simulation + 10% headroom.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| Fixed priority fee | Low traffic devnet | Mainnet congestion periods |
| Jito tip APIs | Bundle landing | Simple transfers |
| Surfpool simulate | Fork-accurate DeFi | Wallet-only apps |
CLI solana confirm -v | Post-send debug | Pre-send planning |
FAQs
What units does prioritizationFee use?
Micro-lamports per compute unit for priority fee instruction - multiply by requested CU budget for total priority lamports.
How often to refresh fees?
Per transaction batch during congestion; less frequent on quiet devnet.
Does simulateTransaction cost SOL?
No on-chain spend - RPC compute only; some providers rate-limit heavy simulation.
Can I simulate without all signers?
Often yes with sigVerify: false - useful for partial signing flows.
How does this relate to compute budget program?
Simulation informs SetComputeUnitLimit and SetComputeUnitPrice instruction values.
Do provider fee APIs differ?
Helius and others wrap percentile estimates - fall back to getRecentPrioritizationFees for portability.
Why simulate with processed commitment?
Fastest feedback during iterative debugging - match send commitment for final checks.
Can simulation detect slippage failures?
Yes if program returns error on insufficient output - read logs and err field.
Does kit 7.0.0 encode wire txs?
Use getBase64EncodedWireTransaction when building txs with kit pipelines before simulate.
Where is landing policy documented?
Related
- Estimating Compute Units - CU headroom
- Setting Priority Fees - fee strategy
- Simulating Transactions - conceptual model
- RPC Providers - enhanced APIs
Stack versions: This page was written for Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0, and LiteSVM 0.6.x.