Priority Fees: Understanding Solana's Transaction Fee Mechanics (2024)

What’s this Article About?

Solana is fast. Yet, even on the fastest blockchain available, users want optimized transaction processing for important transactions. Priority fees are a way to ensure a user’s transaction is placed at the front of the execution ordering queue. These are additional, optional fees that a user can add to their transaction.

This article briefly explores the nuances of transaction processing on Solana. It covers transactions, their lifecycle, and how transaction fees work. Then, the article explores priority fees, how to implement them programmatically, and best practices.

Transactions and Their Lifecycle

Transactions are used to invoke Solana programs and enact state changes. They are bundles of instructions (i.e., directives for a single program invocation) that tell the validator what actions to perform, on what accounts, and whether they have the necessary permissions.

The general lifecycle of a transaction on Solana is as follows:

  • The user has a clear goal for an action they want to perform. For example, Alice wants to send Bob 10 SOL
  • The user generates a transaction for their desired action. For example, Alice creates a transaction with an instruction to transfer 10 SOL from her account to Bob’s. Alice also includes a recent blockhash and signs the transaction using her private key
  • The user sends the transaction to the network. Then, they receive information on whether the transaction has been successfully added. For example, Alice sends the transaction with a confirmed commitment status. When the transaction is confirmed, she receives a transaction signature. Alice can use this transaction signature on a block explorer, such as X-ray, to see that she sent Bob 10 SOL successfully. Her account has been debited 10 SOL, whereas Bob’s was credited 10 SOL

When users send a signed transaction to the network, they use an RPC provider such as Helius. Helius’ RPCs receive the transaction and check the current leader schedule. On Solana, only specific validators are responsible for appending entries to the ledger at certain times. The leader is responsible for producing a block for its current slot and is assigned four consecutive slots. The signed transaction is sent to the current leader and the next two leaders.

The current leader validates the signed transaction and performs other preprocessing steps before scheduling the transaction for execution. Unlike other L1s like Ethereum, Solana has no global transaction queue. Most validators use the scheduler implementation provided by Solana Labs. However, validators running the Jito validator client use a pseudo-mempool (i.e., MempoolStream) to order transactions. The default scheduler is multi-threaded, with each thread maintaining a queue of transactions waiting to be executed. Transactions are ordered into blocks by combining first-in-first-out (FIFO) and priority fees. It’s important to note that this ordering is inherently non-deterministic as transactions are assigned to execution threads somewhat randomly.

When a transaction is executed, it is propagated via Turbine, and its fees are paid accordingly.

How Transaction Fees Work on Solana

Transaction fees are small fees paid to process transactions on Solana. The current leader processes transactions sent through the network to produce ledger entries. When the transaction is confirmed as a part of state, a fee is paid to support the economic design of Solana. Transaction fees fundamentally benefit Solana. They:

  • Provide compensation to validators
  • Reduce network space by introducing real-time cost for transactions
  • Provide long-term economic stability to the network via protocol-captured minimum fee

Priority Fees: Understanding Solana's Transaction Fee Mechanics (1)

Solana relies on inflationary protocol-based rewards to secure the network in the short term. The network has a scheduled global inflation rate to reward validators to achieve this. For the long term, Solana relies on transaction fees to sustain security. A fixed portion (initially set at 50%) of each transaction fee is burned, with the rest sent to the current leader. Solana burns fees to fortify the value of SOL while discouraging malicious validators from censoring transactions.

Transaction fees are calculated based on a statically set base fee per signature, and the computational resources used during the transaction measured in Compute Units (CU). This base fee can range from 50% to 1000% of the target lamports per signature. The default target per signature is currently set at 10,000. Each transaction is allocated a maximum CU budget known as the Compute Budget. Exceeding this budget leads to the runtime halting the transaction and returning an error. The maximum budget per transaction is 1.4 million CU, and the blockspace limit is 48 million CU.

What are Priority Fees?

Due to these limitations, computationally heavy transactions could fill blockspace, delaying other transactions. Solana introduced an optional fee to allow transactions to prioritize themselves against other transactions in the leader’s queue known as a priority fee. Paying this fee effectively boosts your transaction, resulting in faster execution times. This is useful for time-sensitive or high-value transactions. The fee priority of a transaction is determined by the number of compute units it requests. The more compute units a transaction requests, the higher the fee it’ll have to pay to maintain its priority in the transaction queue. Charging more for more compute units prevents computationally heavy transaction spam.

Priority fees are the product of a transaction’s compute budget and its compute unit price measured in micro-lamports: priorityFees = computeBudget * computeUnitPrice

Compute Budget

The computeBudget specifies the maximum number of compute units a transaction can consume, the costs associated with the different operations the transaction may perform, and the operational bounds the transaction must adhere to. The following operations incur a compute cost:

  • Executing SBF instructions
  • Passing data between programs
  • Calling system calls (e.g., logging, creating a program address,CPIs)

For Cross-Program Invocations (CPIs), the called program operates within the computational budget of the calling (i.e., parent) program. If the called program uses up all of the remaining computational budget or goes beyond a set limit, it causes the entire chain of program calls to fail. This includes the execution of the initial transaction that started the process.

The current compute budget can be found here.

How to Implement Priority Fees Programmatically

A transaction’s prioritization fee is set by setting a SetComputeUnitPrice instruction and an optional SetComputeUnitLimit instruction. If a SetComputeUnitPrice instruction isn’t provided, the transaction will default to the lowest priority since no additional fee is provided. If a SetComputeUnitLimit instruction isn’t provided, the limit is calculated as the product of the number of instructions in the transaction and the default compute unit limit. The runtime uses the compute unit price and compute unit limit to calculate the prioritization fee, which is used to prioritize the given transaction.

We must add these instructions to our desired transaction to programmatically add priority fees. In Javascript, it looks like the following:

import { Keypair, Connection, PublicKey, Transaction, SystemProgram, LAMPORTS_PER_SOL, sendAndConfirmTransaction, ComputeBudgetProgram,} from "@solana/web3.js";async function main() { // Initialize an RPC client const clusterUrl = "http://127.0.0.1:8899"; const connection = new Connection(clusterUrl, "confirmed"); // Initialize new sender and receiver keypairs const fromKeypair = Keypair.generate(); const toPubkey = new PublicKey(Keypair.generate().publicKey); // Airdrop SOL to the from_keypair const airdropAmount = 100 * LAMPORTS_PER_SOL; try { const signature = await connection.requestAirdrop( fromKeypair.publicKey, airdropAmount ); console.log("Airdrop requested. Signature:", signature); await connection.confirmTransaction({ signature, confirmation: "confirmed", }); } catch (e) { console.error("Failed to request airdrop:", e); return; } // Check if airdrop was successful const balance = await connection.getBalance(fromKeypair.publicKey); if (balance < airdropAmount) { console.error( "Airdrop was not successful. The current balance is insufficient" ); return; } // Airdrop SOL to the toPubkey const airdropAmountTo = 100 * LAMPORTS_PER_SOL; // 1 SOL in lamports try { const signature = await connection.requestAirdrop(toPubkey, airdropAmount); console.log("Airdrop requested. Signature:", signature); await connection.confirmTransaction({ signature, confirmation: "confirmed", }); } catch (e) { console.error("Failed to request airdrop:", e); return; } // Check if airdrop was successful const balanceTo = await connection.getBalance(toPubkey); if (balance < airdropAmount) { console.error( "Airdrop was not successful. The current balance is insufficient" ); return; } console.log(`Account balance: ${balance / LAMPORTS_PER_SOL} SOL`); // Create the priority fee instructions const computePriceIx = ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1, }); const computeLimitIx = ComputeBudgetProgram.setComputeUnitLimit({ units: 200_000, }); // Create the transfer instruction const transferIx = SystemProgram.transfer({ fromPubkey: fromKeypair.publicKey, toPubkey, lamports: 100_000, }); // Create the transaction with priority fees const transaction = new Transaction().add( computePriceIx, computeLimitIx, transferIx ); // Fetch the recent blockhash and sign the transaction transaction.recentBlockhash = ( await connection.getLatestBlockhash() ).blockhash; transaction.sign(fromKeypair); // Send the transaction try { const txid = await sendAndConfirmTransaction(connection, transaction, [ fromKeypair, ]); console.log("Transaction sent successfully with signature", txid); } catch (e) { console.error("Failed to send transaction:", e); }}main();

In this snippet, we:

  • Set up a test environment using Localhost
  • Create two new wallets (i.e., fromKeypair and toPubkey)
  • Airdrop both wallets 100 SOL
  • Ensure that the airdrops were successful
  • Create the priority fee instructions (i.e., computePriceIx and computeLimitIx)
  • Create a transfer instruction, sending 100, 000 lamports from fromKeypair to toPubkey
  • Create a new transaction and add all of the instructions to it
  • Attach the latest blockhash to the transaction and sign it
  • Send and confirm the transaction was sent successfully

That’s it - priority fees are just instructions added to a transaction to pay for faster execution times. Most of this snippet configures our development environment and two wallets to transfer SOL between them. What we’re interested in is creating the instructions to add priority fees and attaching them to a transaction:

// Other codeconst computePriceIx = ComputeBudgetProgram.setComputeUnitPrice({microLamports: 1,});const computeLimitIx = ComputeBudgetProgram.setComputeUnitLimit({units: 200_000,});// Other codeconst transaction = new Transaction().add(computePriceIx, computeLimitIx, transferIx);// Rest of the code

Best Practices

The order of these instructions matter as they are executed sequentially. If, for example, you have a transaction that exceeds the default computation limit (i.e., 200k CUs) before extending the computation limit, the transaction will fail. Say we have the following transaction:

  • Instruction 1 uses 100k
  • Instruction 2 uses 150k
  • Instruction 3 extends the compute limit

This transaction will fail unless instructions 2 and 3 are swapped. It is therefore recommended to add the compute limit instruction before adding other instructions to your transaction. Remember, you do not need to use the SetComputeLimit instruction if you want to add priority fees to your transaction - it is entirely optional. The placement of the SetComputePrice instruction does not matter.

Using the getRecentPrioritizationFees RPC method is recommended to get a list of recently paid priority fees. This data can be used to estimate an appropriate priority fee for transactions to ensure they are processed by the cluster and minimize the fees paid. Alternatively, Helius offers a new PriorityFeeAPI, which we'll cover in the following section.

Transactions should also request the minimum amount of compute units required for execution to minimize these fees. Note that costs are not adjusted when the number of requested compute units exceeds the total units used by a transaction.

Some wallet providers, such as Phantom, recognize that dApps can set priority transaction fees. However, they discourage doing so, citing that it often creates unnecessary complexity for end-users. Instead, they urge dApp developers to let Phantom apply priority fees on the user’s behalf. Solfare, for example, tackles the issue by automatically detecting whether Solana is under load and slightly increases fees to prioritize your transaction over others.

Helius Priority Fee API

Calculating priority fees using thegetRecentPrioritizationFeesRPC method makes intuitive sense to calculate fees on a slot basis. However, this can be tough given the ever-changing network conditions and the nature ofgetRecentPrioritizationFees'response (i.e., returning a list of values for the past 150 blocks, which is only helpful for gauging the minimum value to set for fees).

The Helius Priority Fee API introduces a new method,getPriorityFeeEstimate, that simplifies the response into a single value, considering global and local fee markets. This method uses a predefined set of percentiles to determine the estimate. These percentiles, or levels, range fromNONE(0th percentile) toUNSAFE_MAX(100th percentile, and labeled unsafe to prevent users from accidentally draining their funds). Users also have the option to specify to receive all priority levels and adjust the range used in this calculation vialookbackSlots. Thus, similar togetRecentPrioritizationFees,users can look back at a certain amount of slots in the estimate calculation.

For example, we can calculate all priority fee levels for the Jupiter v6 program with the following script:

const url = `https://mainnet.helius-rpc.com/?api-key=`;const getRecentPrioritizationFees = async () => { const response = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "getPriorityFeeEstimate", params: [{ "accountKeys": ["JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"], "options": { "includeAllPriorityFeeLevels": true, } }] }), }); const data = await response.json(); console.log("Fee: ", data);};getRecentPrioritizationFees();

This endpoint is in active development. For more information, visit theHelius documentation.

Conclusion

Navigating the world of Solana transactions reveals a sophisticated system that balances network efficiency with economic incentives. Understanding how transactions work, in addition to their fees and priority fees, enables developers and users to make more informed decisions to optimize their interactions on Solana. The ability to implement priority fees programmatically opens up new avenues for high-value and time-sensitive transactions. This allows for greater flexibility and efficiency in operations on Solana.

If you’ve read this far, thank you, anon! Be sure to enter your email address below so you’ll never miss an update about what’s new on Solana. Ready to dive deeper? Join our Discord to start building the future on the most performant blockchain, today.

Additional Resources / Further Reading

Priority Fees: Understanding Solana's Transaction Fee Mechanics (2024)

FAQs

What is the priority fee for Solana? ›

What are Solana Priority Fees? Solana priority fees are additional fees users can pay to increase the likelihood of their transactions being processed more quickly by the network.

What is the transaction fee mechanism of Solana? ›

Solana's fee system consists of two components: the base fee and the priority fee. Broadly, each fee component ideally serves the following purpose: Base fees: right to utilize the network's resources. Priority fees: determine the order in a leader's transaction queue.

What is the average Solana transaction fee answer? ›

Solana offers some of the cheapest transaction fees in the cryptocurrency market, typically costing between $0.003 and $0.030.

What is the priority fee for a transaction? ›

The fee priority of a transaction is determined by the number of compute units it requests. The more compute units a transaction requests, the higher the fee it'll have to pay to maintain its priority in the transaction queue. Charging more for more compute units prevents computationally heavy transaction spam.

What is the priority fee in Sol? ›

The priority fee adjusts the compute unit price to influence the transaction processing speed. Transaction instructions: Two main instructions are created: A transfer instruction to move SOL from the sender's account to a specified recipient (in this case, it transfers to the same account for demonstration).

What is a priority fee? ›

Priority Fee means the fee in addition to the Document Fee that Property Managers charge customers for preparing Documents for delivery in a shorter time period than the maximum allowed under the Act; Sample 1.

How to calculate Solana transaction fee? ›

The total fee for a transaction is calculated by multiplying the number of compute units required for the transaction by the current compute unit price, along with any applicable base fees. Compute Unit Limit: This refers to the maximum number of compute units that a single transaction can consume.

How much is Solana transaction fee live? ›

Solana can process as many as 50,000 transactions per second (TPS), and its average cost per transaction is $0.00025.

How much is priority fee? ›

Optional Premium Services Outside the UK
Application CategoryApplication Fee
Priority Visa service – Settlement£500
Priority Visa service – Non-Settlement£500
Super Priority Visa service£1,000
4 more rows
Jul 9, 2024

How do I avoid paying a transaction fee? ›

How to Avoid International Transaction Fees
  1. Open a Credit Card Without a Foreign Transaction Fee. ...
  2. Open a Bank Account Without a Foreign Transaction Fee. ...
  3. Exchange Currency Before Traveling. ...
  4. Avoid Foreign ATMs. ...
  5. Ask Your Bank About Foreign Partners.

What is the maximum priority fee? ›

Max Priority Fee: Determined by the user and is optional. Priority Fee is also known as Miner Tip as it is paid directly to block producers. Max Fee Per Gas: Maximum amount the user is willing to pay to get their transaction included in a block.

How to set priority fees on Solana? ›

The total compute budget or Prioritization Fee for a single TX can be changed by adding instructions from the ComputeBudgetProgram. ComputeBudgetProgram. setComputeUnitPrice({ microLamports: number }) will add a Prioritization Fee above the Base Fee (5,000 Lamports).

How much is the Solana processing fee? ›

Currently, the base Solana transaction fee is set at a static value of 5k lamports per signature. On top of this base fee, any additional prioritization fees can be added.

What are the fixed fees for Solana? ›

Base Fees. Solana transactions have a fixed base fee of 0.000005 SOL (5,000 lamports) per signature that must be paid upfront.

What is the fee market in Solana? ›

Solana's fee model creates a local fee market, where each contract has its own gas fee. This is similar to paying different amounts for groceries in different neighborhoods.

Top Articles
What is a ‘bad’ credit score?
What is an ERC as NFT standard?
Calvert Er Wait Time
UPS Paketshop: Filialen & Standorte
craigslist: kenosha-racine jobs, apartments, for sale, services, community, and events
Driving Directions To Fedex
Roblox Developers’ Journal
Lycoming County Docket Sheets
Western Razor David Angelo Net Worth
Fcs Teamehub
Lantana Blocc Compton Crips
Milk And Mocha GIFs | GIFDB.com
Tripadvisor Near Me
What Was D-Day Weegy
U/Apprenhensive_You8924
Missing 2023 Showtimes Near Landmark Cinemas Peoria
Lancasterfire Live Incidents
Vistatech Quadcopter Drone With Camera Reviews
Schedule 360 Albertsons
Craigslist List Albuquerque: Your Ultimate Guide to Buying, Selling, and Finding Everything - First Republic Craigslist
How To Level Up Roc Rlcraft
Daytonaskipthegames
Ice Dodo Unblocked 76
12 Facts About John J. McCloy: The 20th Century’s Most Powerful American?
University Of Michigan Paging System
R/Airforcerecruits
Craigslist Efficiency For Rent Hialeah
Funky Town Gore Cartel Video
Top Songs On Octane 2022
Basil Martusevich
Donald Trump Assassination Gold Coin JD Vance USA Flag President FIGHT CIA FBI • $11.73
Bernie Platt, former Cherry Hill mayor and funeral home magnate, has died at 90
Mega Millions Lottery - Winning Numbers & Results
Newsday Brains Only
Green Bay Crime Reports Police Fire And Rescue
Edward Walk In Clinic Plainfield Il
Panchitos Harlingen Tx
Scanning the Airwaves
Nearest Ups Office To Me
Keir Starmer looks to Italy on how to stop migrant boats
Wasmo Link Telegram
Stranahan Theater Dress Code
Wordle Feb 27 Mashable
Best Suv In 2010
John Wick: Kapitel 4 (2023)
Wpne Tv Schedule
Wood River, IL Homes for Sale & Real Estate
Christie Ileto Wedding
Coleman Funeral Home Olive Branch Ms Obituaries
Mawal Gameroom Download
WHAT WE CAN DO | Arizona Tile
Ok-Selection9999
Latest Posts
Article information

Author: Otha Schamberger

Last Updated:

Views: 6546

Rating: 4.4 / 5 (55 voted)

Reviews: 86% of readers found this page helpful

Author information

Name: Otha Schamberger

Birthday: 1999-08-15

Address: Suite 490 606 Hammes Ferry, Carterhaven, IL 62290

Phone: +8557035444877

Job: Forward IT Agent

Hobby: Fishing, Flying, Jewelry making, Digital arts, Sand art, Parkour, tabletop games

Introduction: My name is Otha Schamberger, I am a vast, good, healthy, cheerful, energetic, gorgeous, magnificent person who loves writing and wants to share my knowledge and understanding with you.