Setting Priority Fees
Set dynamic priority fees using recent network percentiles and SetComputeUnitPrice so transactions compete during congestion.
Recipe
Quick-reference recipe card - copy-paste ready.
const fees = await rpc.getRecentPrioritizationFees([]).send();
fees.sort((a, b) => a.prioritizationFee - b.prioritizationFee);
const p75 = fees[Math.floor(fees.length * 0.75)]?.prioritizationFee ?? 1000;
// microLamports per CU in compute budget instruction
const microLamports = Math.min(p75 * 1.2, MAX_CAP);When to reach for this:
- Mainnet launches and mints with contention.
- Relayer services batching user transactions.
- Wallets auto-tuning send success rate.
- Replacing static zero priority fee defaults.
Working Example
import { createSolanaRpc } from "@solana/kit";
const rpc = createSolanaRpc(process.env.RPC_URL!);
const MAX_MICRO_LAMPORTS = 500_000;
async function suggestPriorityFee(lockedAccounts: string[] = []) {
const fees = await rpc
.getRecentPrioritizationFees(
lockedAccounts.map((a) => ({ account: a }))
)
.send();
const samples = fees
.map((f) => f.prioritizationFee)
.filter((n) => n > 0)
.sort((a, b) => a - b);
if (samples.length === 0) return 1_000;
const p75 = samples[Math.floor(samples.length * 0.75)];
return Math.min(Math.ceil(p75 * 1.2), MAX_MICRO_LAMPORTS);
}
const microLamports = await suggestPriorityFee();
console.log("compute unit price:", microLamports);What this demonstrates:
getRecentPrioritizationFeessamples landed transaction fees.- 75th-90th percentile targeting balances cost vs success.
- Hard cap prevents runaway fees during fee spikes.
Deep Dive
How It Works
- Priority fee =
microLamports * compute_units_requested(capped by limit instruction). - Validators order transactions partly by total priority fee bid.
- Base signature fee (5000 lamports) remains separate from priority component.
- Provider APIs may return
priorityFeeEstimatewith percentile stats.
Strategy Tiers
| Profile | Percentile | Use case |
|---|---|---|
| Economy | p50 | Low urgency |
| Standard | p75 | Most UX |
| Aggressive | p90 | Mints, arb |
| Capped | min(p90, cap) | Cost guardrails |
TypeScript Notes
// Total priority lamports ≈ (microLamports * computeUnitLimit) / 1_000_000
// Add base fee separately in UX estimatesGotchas
- Zero fee during hype mint - near-zero landing rate. Fix: dynamic percentile with floor.
- Uncapped p99 - users pay extreme fees. Fix:
MAX_MICRO_LAMPORTSper product policy. - Stale fee sample - market moved since fetch. Fix: refresh per send batch.
- High limit + high price - multiplies total priority lamports. Fix: right-size CU limit first.
- Devnet fee tuning meaningless - congestion unlike mainnet. Fix: test policy on mainnet small txs.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| Fixed fee | Quiet devnet | Congested mainnet |
| Jito tip | Bundle landing | Simple transfers |
| Private validator deals | Institutional | Consumer wallets |
| User-selected sliders | Transparent UX | Fully automated bots |
FAQs
What are microLamports?
1e-6 lamports; price is per compute unit requested in the budget instruction.
How do users see priority fee?
Show estimated priority SOL = microLamports * CU limit / 1e9 plus base fee.
Should fees differ per instruction type?
Yes - maintain fee profiles per transaction template from simulations.
Do failed txs pay priority?
If included in block but failed program, priority fee still charged; dropped txs pay nothing.
Helius fee API?
Optional enhancement over raw getRecentPrioritizationFees - abstract behind interface.
Priority fee on devnet?
Usually unnecessary - focus testing on mainnet small amounts.
Relation to Jito tip?
Separate payment paths - some apps use both for competitive landing.
How often to refresh?
Per user send action during congestion; less frequent off-peak.
Can I refund priority fees?
No on-chain refund if tx lands failed - design caps and simulation carefully.
Where is CU limit set?
See Estimating Compute Units - set limit before price.
Related
- Priority Fee & Simulation APIs - RPC data
- Priority Fees - conceptual model
- Jito Bundles - bundle tips
- Why Transactions Fail to Land - underpriced drops
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.