How to Calculate a Solana Priority Fee

Last updated:

Endpoint and plans: Solana RPC endpoint.

Terms on this page: Priority fee · Compute unit · Lamport.

At a glance

Symptom details
PropertyValue
Formulaceil(compute_unit_price × compute_unit_limit ÷ 1,000,000) lamports
Price unitMicro-lamports per compute unit (default 0)
Default limit200,000 per non-builtin instruction, 3,000 per builtin
Maximum limit1,400,000 per transaction
Base fee5,000 lamports per signature, 50% burned
Who gets the priority feeThe validator, 100%

What you see

You set a priority fee and the transaction still costs more, or less, than you expected. Or you want a number to put in SetComputeUnitPrice, and a chain-wide average tells you to pay nothing while your swaps are not landing.

Why this happens

Two instructions set the fee: SetComputeUnitLimit and SetComputeUnitPrice. The fee is their product, so it depends on the limit you requested and not on the compute you consumed. With no limit instruction, the default limit applies: 200,000 units for each non-builtin instruction. A transaction with three program instructions therefore pays for 600,000 units, even if it uses 90,000. The second surprise is contention. Fees are local to the accounts a transaction locks as writable, so a busy pool can be expensive while the rest of the block is empty, and a global average hides this. getRecentPrioritizationFees answers per account set, reporting for each recent slot the fee observed for transactions locking all of the accounts you supplied as writable. A node's cache covers up to 150 blocks, and you can pass up to 128 accounts.

Worked example: same price, different limits

One signature, at a price of 50,000 micro-lamports per compute unit
Compute unit limitPriority fee (lamports)Base fee (lamports)Total (lamports)Total (SOL)
100,0005,0005,00010,0000.00001
300,00015,0005,00020,0000.00002
600,000 (default for 3 program instructions)30,0005,00035,0000.000035
1,400,000 (maximum)70,0005,00075,0000.000075

What to do

  1. Simulate the transaction and read unitsConsumed.
  2. Set SetComputeUnitLimit to that figure plus a margin; around 10% is a common choice. A swap whose route can change needs more.
  3. List the accounts your transaction writes to, and call getRecentPrioritizationFees with them.
  4. Pick a percentile from the returned slots, not the mean: one spike distorts a mean, and long runs of zero pull it down. Use a higher percentile when landing matters more than cost.
  5. Set SetComputeUnitPrice, and put both compute budget instructions in the message before you sign.
  6. Cap what you are willing to pay, and recalculate on each attempt, because contention changes between one retry and the next.

Read recent fees for the accounts you write to

curl "$RPC_URL" -H "Content-Type: application/json" -d '{
  "jsonrpc": "2.0", "id": 1,
  "method": "getRecentPrioritizationFees",
  "params": [["<writable-account-1>", "<writable-account-2>"]]
}'
# result: [{ "slot": 123, "prioritizationFee": 50000 }, ...]
# prioritizationFee is micro-lamports per compute unit

Turn samples into a fee

const fees = result.map((r) => r.prioritizationFee).sort((a, b) => a - b);
const price = fees[Math.floor(fees.length * 0.75)];   // 75th percentile
const limit = Math.ceil(unitsConsumed * 1.1);         // 10% margin
const priorityLamports = Math.ceil((price * limit) / 1_000_000);

When this is not our problem

The fee formula and per-account contention are Solana's, and they are the same on every RPC provider. A higher fee also does not guarantee landing: it improves your position with a leader the transaction actually reached. If it never reaches one, see why a transaction never lands. To run these calls with your own key, the Solana send page lists the methods and limits by plan.

FAQ

What is a good priority fee on Solana?
There is no fixed number, because fees depend on the accounts you write to and on the moment you send. Read getRecentPrioritizationFees for those accounts and choose a percentile that matches how much landing matters.
Do I pay the priority fee if the transaction fails?
Yes, if it was processed and failed on chain. The fee is charged for processing, whatever the outcome. A transaction that was dropped before processing, or rejected in preflight, pays nothing.
Why is my priority fee higher than I calculated?
Usually the limit. If you did not set one, the default of 200,000 units per non-builtin instruction applied, and the price multiplied that figure.
Is a priority fee the same as a Jito tip?
No. A priority fee is a protocol fee paid to the validator. A Jito tip is a transfer to a tip account for Jito's auction.

Sources