Skip to content
The Sniper Bot Index

Priority fees and Jito bundles: what your fee actually buys

Solana charges a flat base fee per signature and an optional priority fee priced in micro-lamports per compute unit. Bundles are a separate mechanism entirely: they buy atomic, ordered execution rather than a place in a queue. Confusing the two is how operators end up spending on tips that were never going to help.

A priority fee is a price you set in micro-lamports per compute unit, multiplied by the compute unit limit you declare, paid on top of the flat base fee per signature. It ranks you against other transactions writing to the same accounts. A Jito bundle is not a fee at all: it is a request for several transactions to execute in order, in the same block, or not at all, and it is paid for with a tip that only settles if the bundle lands.

The two fees you actually pay

Every Solana transaction pays a base fee determined by its signature count, currently 5,000 lamports per signature. One lamport is one billionth of a SOL, so a single-signature transaction pays 0.000005 SOL regardless of what it does. This fee is not an auction and cannot be bid up or down.

On top of that sits the optional priority fee, added by including compute budget instructions in the transaction. Two instructions matter: one sets the compute unit limit the transaction is requesting, the other sets the price per compute unit in micro-lamports. Their product is the priority fee.

The rules for how much of a fee is burned versus paid to the block producer have been changed by governance more than once, so treat any fixed split you read as version-dependent and check current protocol documentation before building economics on it. What has stayed stable is the shape: a flat component tied to signatures, and a variable component you control through compute pricing.

Compute units and the fee arithmetic

Compute units meter on-chain work. Each instruction consumes them, a transaction declares a ceiling, and exceeding that ceiling aborts everything in the transaction. Without an explicit limit the runtime applies a default allocation per instruction, and a transaction can request up to 1.4 million compute units in total.

The formula is straightforward:

priority fee in lamports = compute unit limit × compute unit price in micro-lamports / 1,000,000

A worked example, using illustrative settings rather than current market rates. Take a swap that a simulation shows consuming about 82,000 compute units. You declare a limit of 90,000 for headroom.

Illustrative fee arithmetic for one single-signature swap
ScenarioCU limit declaredCU price (micro-lamports)Priority feeBase feeTotal in SOL
Quiet market90,00020,0001,800 lamports5,000 lamports0.0000068
Busy market90,000200,00018,000 lamports5,000 lamports0.000023
Contested entry90,0001,000,00090,000 lamports5,000 lamports0.000095
Lazy limit, same price1,400,0001,000,0001,400,000 lamports5,000 lamports0.001405

The final row is the point of the table. Declaring the maximum limit because it is easier than measuring costs roughly fifteen times the priority fee of a correctly sized transaction at the same price, because you are charged against the limit you requested rather than the units you consumed. On a handful of trades this is noise. On a system doing hundreds of transactions a day it is one of the largest avoidable line items in the whole cost stack, as the cost breakdown shows when the same mistake is carried across a full run.

Local fee markets, not a global auction

The most valuable thing to understand about Solana fees is that they are local. Transactions are scheduled in parallel unless they contend for write access to the same accounts. Two swaps on two unrelated pools do not compete with each other at all, no matter how busy the chain is overall.

Consequences worth internalising:

  • Chain-wide congestion is not automatically your problem. If nobody else is writing to your pool, a modest fee is sufficient even during a network-wide surge.
  • A single hot account can be brutally contested while the rest of the chain is calm. This is exactly the situation at a popular launch, and it is why generic fee advice fails.
  • Fee estimates should be account-scoped. The RPC method that returns recent prioritisation fees accepts the accounts your transaction will write to, and that scoped answer is the only one worth acting on.
  • Overpaying on a quiet market is a straight donation. There is no queue to jump when the queue is empty.

A reasonable fee policy therefore reads recent prioritisation fees for the specific writable accounts involved, takes a high percentile of that distribution rather than the mean, applies a multiplier scaled to how much the trade matters, and caps the result as an absolute fraction of the trade's notional value. That last clause is what stops a runaway fee loop from spending more on inclusion than the position is worth.

Locality is also why routing breadth changes the fee question rather than simplifying it. A multi-DEX Solana volume bot writing to pools on several venues is standing in a separate local fee market on each one, so a single global fee setting will overpay on the quiet venue and miss inclusion on the contested one. Per-venue scoping is the only version of the policy that survives contact with that.

Setting the compute unit limit correctly

The correct procedure is boring and it is skipped constantly.

  1. Simulate the transaction against current state and read the compute units consumed from the simulation result.
  2. Add a margin, commonly in the range of ten to twenty per cent, to absorb variation in account state and route length.
  3. Set the limit explicitly to that figure rather than accepting the default or requesting the maximum.
  4. Re-measure whenever the route changes, the venue upgrades its program, or the transaction starts creating token accounts it did not create before.

Getting this wrong in either direction is costly. Too low and the transaction aborts mid-execution, paying fees for nothing. Too high and every transaction overpays its priority fee by the ratio of the declared limit to the real consumption. Because the margin also affects how a scheduler treats your transaction's expected weight, a tightly measured limit is one of the few optimisations that improves both cost and inclusion behaviour at once.

Bundles: what atomicity buys

A bundle is an ordered list of transactions submitted to a block engine with the guarantee that they execute sequentially inside the same block or not at all. Current implementations accept up to five transactions per bundle. It is a fundamentally different product from a priority fee, and it solves a different problem.

Priority fees answer "how do I get included sooner among transactions touching this account". Bundles answer "how do I ensure these operations happen together, in this order, with nothing wedged between them". The strategies that genuinely need the second guarantee are narrower than the marketing suggests:

  • Multi-leg arbitrage where a partial execution leaves an unintended directional position. This is the canonical case.
  • Operations that must not be interleaved, such as creating an account and immediately using it under contention.
  • Sequences that exceed the single-transaction size limit but must still behave as one unit.

For a plain buy into a new pool, atomicity buys very little. There is no second leg to protect and no ordering constraint beyond being early. What a bundle can offer such a trade is a different inclusion path, which may or may not be faster on any given day, and which comes with its own dependency on a third-party block engine being reachable and healthy.

One nuance that surprises people: the public transaction-forwarding services attached to bundle infrastructure have changed substantially over time, including the withdrawal of a public pending-transaction stream. Any strategy whose profitability depends on privileged visibility into other people's unlanded transactions is depending on a commercial arrangement that can be, and has been, withdrawn.

Tips, and when a tip is wasted

A tip is a transfer to a designated tip account, included inside the bundle itself, that competes for the block engine's attention against other bundles. Because the tip instruction lives in the bundle, it settles only if the bundle lands. That property is genuinely useful: an unsuccessful bid costs nothing beyond the opportunity.

Three ways operators waste tips anyway:

Tipping when the bottleneck is detection

If your data path tells you about a market three hundred milliseconds after everyone else, no bid changes the outcome. You are competing for a block that has already been decided. Fix the detection path first; the diagnosis is in the landing-rate measurement recipe, which will show a healthy landing rate alongside consistently poor entry prices.

Tipping and paying a large priority fee for the same transaction

These are two different inclusion mechanisms. Running both at full aggression on a routine trade is paying twice for a race you are not in. Choose the mechanism that matches the constraint, and keep the other at a baseline.

Sending the tip outside the bundle

A standalone transfer to a tip account is an ordinary transaction. If it lands, the money is gone, whether or not the trade it was meant to accompany landed. Tips belong inside the bundle they are bidding for, and any tooling that does otherwise should be examined closely.

Decision table by trade urgency

Fee policy should be a function of urgency, not a global setting. This table is a starting posture, not a recommendation of specific values, because the correct number always depends on what the contended accounts are doing right now.

Fee and inclusion posture by trade urgency
SituationCU price postureCU limit postureBundle and tipRetry postureCost of failure
Routine rebalance, no deadlineBaseline percentile of recent fees for the accountMeasured limit plus small marginNeitherSlow cadence, long windowNegligible: retry later
Normal swap in a liquid marketMedian to upper percentile, scoped to the poolMeasured limit plus marginNeitherSteady cadence until expirySmall: price drift
Contested entry at a launchHigh percentile, capped as a fraction of notionalMeasured tightly; margin costs real money hereBundle only if there is a second leg to protectShort cadence, hard stop on price checkHigh: the whole trade thesis
Multi-leg arbitrageSecondary concernMeasured per leg, watch the size limitBundle is the requirement, tip is the bidRebuild rather than retry stale legsSevere: an unintended position
Exit under stressAggressive; inclusion beats optimisationGenerous margin, since route may be longerNeither, unless the exit is multi-legPersistent, with widened slippage toleranceSevere and asymmetric: not exiting

The exit row is deliberately the opposite of the entry row. Entries are optional and can be skipped at no cost beyond regret; exits are not. A fee policy that treats both identically is optimising the cheap decision and under-resourcing the expensive one.

Writing the fee policy down

Most fee problems are not pricing problems, they are the absence of a written rule. Whatever the numbers are, the policy should be explicit enough that someone else could read it and reproduce your behaviour. A workable one has six clauses.

  1. Scope. Estimate against the specific writable accounts the transaction touches, never against a chain-wide average. The account-scoped estimate is the only one that describes your competition.
  2. Statistic. Choose a percentile of the recent distribution and write it down. Means are dragged around by single outliers, and the outlier is often somebody else's mistake.
  3. Multiplier by urgency. One multiplier per row of the urgency table above. This is the only place discretionary aggression is allowed to enter.
  4. Absolute cap. A hard ceiling expressed as a fraction of the trade's notional value, applied after every other clause. Without this, a fee estimator reading a contested market can spend a meaningful share of a small position on inclusion alone.
  5. Floor. A minimum that keeps routine transactions moving during broad activity spikes, so that low-priority work does not silently stall for a minute at a time.
  6. Escalation on retry. Decide in advance whether a rebuild raises the price, and by how much. Escalating without a ceiling is how a retry loop turns a missed entry into an expensive one.

Two review habits keep the policy honest. First, reconcile intended fees against fees actually paid, parsed from the confirmed transactions rather than from your own logs, because the gap between the two exposes limit-sizing errors immediately. Second, keep a record of trades that were skipped because they hit the cap. If that list is empty over a long period, the cap is too loose to be doing anything; if it is full of trades you wish you had made, the cap is too tight. The cap is doing its job when the list is short and unregretted.

What fee spending cannot buy

  • It cannot beat an expired blockhash. Once the validity window closes, no fee resurrects the transaction. It must be rebuilt.
  • It cannot fix a saturated ingress path. If the transaction never reaches the current leader, its fee was never evaluated.
  • It cannot help on an uncontended account. Fees rank you against competitors for the same write locks. With no competitors, the ranking is a formality.
  • It cannot guarantee a position inside the block. You influence selection, not the leader's internal ordering.
  • It cannot compensate for stale pricing. Landing quickly at a price computed from a quote several seconds old is an efficient way to buy the top.
  • It cannot make a bad trade good. The most expensive fee is the one paid to enter a position that should not have been entered.

The productive way to hold all of this is as a hierarchy. Detection quality sets the ceiling on what you can achieve. Landing behaviour determines whether your intentions become transactions. Fee policy is a fine adjustment applied inside those constraints, and it is the last thing to tune, not the first. Operators who invert that order spend measurably more for outcomes that do not move.