getPriorityFeeEstimate Solana Developer Guide
Set an accurate Solana priority fee: size the compute unit limit from a simulation, then price it with getPriorityFeeEstimate before you sign and send.
Reference documentation: getPriorityFeeEstimate
A Solana priority fee is the price you offer for each requested compute unit. The final fee depends on both the compute-unit price and the compute-unit limit, so choose them together.
This guide uses the transaction you actually plan to send. You will simulate it, build the unsigned transaction, ask FluxRPC for a fee estimate, then add that price before signing and sending. You need a FluxRPC API key for the estimate. When you are signed in, these examples use the API key you select. When you are signed out, they keep a safe placeholder.
Build the priority fee in three steps
Use the steps in order. Open any step to see its explanation and code. The page URL records the open step, so a reload or shared link returns to the same place.
Step 1: Set the compute unit limit
Why the Limit Comes First
Solana priority fees are based on the requested compute-unit limit, not the compute units the transaction eventually consumes. An unnecessarily high limit can therefore make the same micro-lamport price cost more than it needs to.
For production transactions, simulate the instruction set you intend to send, record the consumed compute units, then add a small safety margin. Solana currently recommends about 10%. The network caps a transaction at 1,400,000 compute units.
Turn the Simulation Result into a Limit
The examples below assume the simulated-unit value came from your existing transaction simulation. Keep the limit calculation next to the transaction-building code so the requested budget is obvious.
from math import ceil
from solders.compute_budget import set_compute_unit_limit
COMPUTE_UNIT_SAFETY_MULTIPLIER = 1.1
MAX_COMPUTE_UNIT_LIMIT = 1_400_000
compute_unit_limit = min(
MAX_COMPUTE_UNIT_LIMIT,
ceil(simulated_units * COMPUTE_UNIT_SAFETY_MULTIPLIER),
)
compute_unit_limit_instruction = set_compute_unit_limit(compute_unit_limit)
SetComputeUnitLimit does not add a priority fee by itself. It only declares the maximum compute budget for the transaction. The fee price is added after FluxRPC estimates it in Step 3.
Keep the Instruction for the Draft Transaction
Do not send this instruction on its own. In Step 2, it becomes the first instruction in the unsigned transaction you serialize for fee estimation.
Step 2: Build the transaction for estimation
Build the Same Transaction You Intend to Send
Build the transaction you intend to send, but stop before signing or broadcasting. The priority price changes the transaction message. If you sign now, you will have to discard that signature in Step 3.
The draft should already contain the compute-unit limit from Step 1 and the real application instructions. The example below uses a SOL transfer so the transaction shape stays easy to inspect.
Assemble an Unsigned Draft
import asyncio
import base64
from solana.rpc.async_api import AsyncClient
from solders.compute_budget import set_compute_unit_limit
from solders.message import MessageV0
from solders.null_signer import NullSigner
from solders.pubkey import Pubkey
from solders.system_program import TransferParams, transfer
from solders.transaction import VersionedTransaction
async def main() -> None:
async with AsyncClient("https://eu.fluxrpc.com?key=<Your-API-Key>") as connection:
payer = Pubkey.from_string("YOUR_PAYER_ADDRESS")
recipient = Pubkey.from_string("YOUR_RECIPIENT_ADDRESS")
compute_unit_limit = 200_000 # Replace with the Step 1 result.
compute_unit_limit_instruction = set_compute_unit_limit(compute_unit_limit)
transfer_instruction = transfer(
TransferParams(
from_pubkey=payer,
to_pubkey=recipient,
lamports=1_000_000,
)
)
latest_blockhash = (await connection.get_latest_blockhash()).value
draft_message = MessageV0.try_compile(
payer=payer,
instructions=[compute_unit_limit_instruction, transfer_instruction],
address_lookup_table_accounts=[],
recent_blockhash=latest_blockhash.blockhash,
)
# NullSigner writes the required all-zero placeholder signature without
# signing the draft message.
draft_transaction = VersionedTransaction(draft_message, [NullSigner(payer)])
serialized_transaction = base64.b64encode(bytes(draft_transaction)).decode("ascii")
print(serialized_transaction)
if __name__ == "__main__":
asyncio.run(main())
The 200_000 value is only a visible placeholder for the Step 1 output. Do not copy it as a general recommendation; use the limit derived from the transaction you are actually building.
Why Serialize Before Signing
getPriorityFeeEstimate can inspect a Base64-encoded transaction and estimate a price from its context. The zeroed signature slot is enough for estimation. Add the real signature only after the fee-price instruction is part of the final message. Python's NullSigner, web3.js's unsigned serialization, and solana-go's transaction encoder all preserve the same placeholder-signature shape.
If you change writable accounts or application instructions after this point, regenerate the draft and request a fresh estimate so the estimator sees the new transaction shape.
For a complete wallet connection and signing example, see the existing sendTransaction guide.
Step 3: Estimate the priority fee and send
Ask FluxRPC for the Priority Fee
The draft from Step 2 now contains the transaction accounts, application instructions, recent blockhash, and compute-unit limit. Send that Base64 transaction to getPriorityFeeEstimate.
The examples below ask FluxRPC for its recommended estimate. The docs page automatically replaces {{RPC_URL}} with the FluxRPC endpoint for your selected API key when you are signed in.
from math import ceil
import requests
def get_recommended_priority_fee(serialized_transaction: str) -> int:
response = requests.post(
"https://eu.fluxrpc.com?key=<Your-API-Key>",
json={
"jsonrpc": "2.0",
"id": 1,
"method": "getPriorityFeeEstimate",
"params": [
{
"transaction": serialized_transaction,
"options": {
"transactionEncoding": "Base64",
"recommended": True,
},
}
],
},
timeout=10,
)
response.raise_for_status()
payload = response.json()
if payload.get("error"):
raise RuntimeError(payload["error"]["message"])
return ceil(payload["result"]["priorityFeeEstimate"])
The returned priorityFeeEstimate is the compute-unit price in micro-lamports per CU. If you need a specific aggressiveness level or the full set of fee levels instead, the RPC reference documents priorityLevel, includeAllPriorityFeeLevels, Jito estimates, lookback controls, and the other available options.
Add the Price to the Final Transaction
Rebuild the final transaction from the same instructions, this time inserting SetComputeUnitPrice after the compute-unit limit. Then sign the new message, not the unsigned draft from Step 2.
from solders.compute_budget import set_compute_unit_price
from solders.message import MessageV0
priority_fee_micro_lamports = get_recommended_priority_fee(serialized_transaction)
compute_unit_price_instruction = set_compute_unit_price(priority_fee_micro_lamports)
final_message = MessageV0.try_compile(
payer=payer,
instructions=[
compute_unit_limit_instruction,
compute_unit_price_instruction,
transfer_instruction,
],
address_lookup_table_accounts=[],
recent_blockhash=latest_blockhash.blockhash,
)
At this point the transaction contains both halves of the priority-fee calculation: the requested compute-unit limit and the estimated price per compute unit.
Sign and Send
Use the signer flow you normally use for a Solana transaction. The browser example hands the final message to a wallet. The Python and Go examples load a key from an environment variable to make the server-side signing boundary explicit. Do not hard-code private keys in application source.
import os
from solders.keypair import Keypair
from solders.transaction import VersionedTransaction
async def sign_and_send(connection, final_message, payer, latest_blockhash) -> None:
payer_keypair = Keypair.from_base58_string(os.environ["PAYER_PRIVATE_KEY"])
if payer_keypair.pubkey() != payer:
raise ValueError("PAYER_PRIVATE_KEY does not match the transaction payer")
final_transaction = VersionedTransaction(final_message, [payer_keypair])
send_result = await connection.send_transaction(final_transaction)
await connection.confirm_transaction(
send_result.value,
commitment="confirmed",
last_valid_block_height=latest_blockhash.last_valid_block_height,
)
print("Transaction signature:", send_result.value)
The Go client's SendTransaction call returns after submission. If your service must block until confirmation, follow it with GetSignatureStatuses polling or the SDK's WebSocket-backed sendAndConfirmTransaction helper.
If the recent blockhash expires while your application is waiting for user approval, fetch a fresh blockhash and rebuild the final transaction before asking the wallet to sign it.
For the full wallet-discovery and browser-signing setup, continue with the existing sendTransaction guide. For every estimator option and the live Try It form, use the getPriorityFeeEstimate RPC reference.
Why this order matters
getPriorityFeeEstimate should inspect the same accounts, instructions, and compute-unit limit that you plan to submit. Build that unsigned shape first, estimate the price from it, then rebuild the final transaction with SetComputeUnitPrice before signing.
This keeps estimation separate from signing and broadcasting. It also avoids paying for an unnecessarily high compute-unit limit, because Solana calculates the priority fee from the requested limit rather than the compute units the transaction actually consumes.