All articles
MEV·May 3, 2026·7 min read

Priority Fee Spam Wars: Modeling Solana Landing Rates for Bots

A data-driven model of Solana priority fee landing rate under congestion — logistic bid curves, QUIC SWQoS, and a bidding policy that beats paying blindly more.

Solana doesn't have a mempool, but it has something functionally worse for a searcher trying to land a transaction during a hot mint: a leader that accepts every packet thrown at it, drops the ones it can't process, and gives you no receipt for the ones it discarded. When a new pool goes live and 40,000 bots all want the same first swap, your transaction is competing not against a fee auction with clean ordering, but against a UDP firehose where the validator's scheduler picks winners partly on priority fee, partly on when your packet physically arrived, and partly on whether QUIC decided to throttle your connection. Landing rate — the fraction of your submitted transactions that actually get included — is the number that decides whether your bot is profitable, and most builders model it with a single knob: pay more.

That knob is real but badly calibrated. Below is how to actually model landing probability under congestion and turn it into a bidding policy that doesn't set your compute-unit price to the moon on every transaction.

What actually determines landing

The current leader runs an Agave scheduler (post-1.18 the central scheduler, not the old thread-per-connection model) that orders transactions within a block by priority — priority = compute_unit_price × compute_units_requested / 1e6, expressed in micro-lamports. Two things matter here that people constantly get wrong:

  • Your effective bid is price times CU requested, not price alone. A transaction requesting 200k CU at 10,000 micro-lamports outranks one requesting 50k CU at 30,000. If you inflate your CU limit to pad your rank, you also inflate the fee you pay when you land. There's no free rank.
  • QUIC stake-weighted quality of service (SWQoS) gates whether your packet even reaches the scheduler. Connections from staked validators get reserved bandwidth; an unstaked RPC connection competes for the leftover ~20% of ingress capacity, and during congestion that capacity is saturated. This is why two bots with identical fees see wildly different landing rates — one is sending through a staked-connection RPC and the other isn't.

So the honest model has at least three inputs, not one: your priority bid relative to the current per-block clearing price, your packet's arrival path (staked vs. not, geographic RTT to the leader), and the raw contention level. Modeling only the first is why "I paid 500,000 micro-lamports and still missed" happens.

A landing-rate model you can fit

Treat landing as a logistic function of your bid percentile against the observed fee distribution for that leader slot. Pull recent priority fees with getRecentPrioritizationFees, but don't trust the raw mean — it's polluted by the long tail of desperate overbids. Build a percentile curve from the last 150 slots and estimate where the block is clearing.

import numpy as np

def landing_prob(my_price, cu, recent_fees, path_factor):
    # recent_fees: list of prioritizationFee values (micro-lamports) from RPC
    my_bid = my_price * cu / 1e6
    fees = np.array(recent_fees)
    fees = fees[fees > 0]                      # ignore zero-fee noise
    pctile = (fees < my_bid).mean()            # where my bid sits
    # logistic: steepness k tuned from historical land/miss data
    k = 8.0
    base = 1 / (1 + np.exp(-k * (pctile - 0.5)))
    return min(base * path_factor, 0.98)       # path_factor in (0,1]

path_factor is the multiplier you back out from your own telemetry: if you land 70% of transactions that your model says should land at 95%, your path is costing you a 0.74 factor and no amount of extra fee fixes it — you fix it by sending through a staked connection or a colocated sender. The logistic steepness k is the interesting parameter. In quiet conditions the curve is nearly a step function (paying one micro-lamport over the clearing price lands you), so k is high. During a spam war k flattens because arrival-time jitter and QUIC drops dominate over fee ordering, and the same fee percentile lands far less reliably. Fit k per-congestion-regime from logged outcomes; a single global k will lie to you exactly when it matters.

The spam-war dynamic

Here's the part builders underprice. During a contested launch, the fee distribution isn't exogenous — you and your competitors are jointly writing it in real time. If everyone reads getRecentPrioritizationFees and bids the 90th percentile, the 90th percentile ratchets upward every slot until fees are 100x the value of the trade for anyone but the first lander. This is a classic all-pay-ish auction where losers still burn base fee and compute, and the Nash outcome is overpay for almost everyone.

The move that beats naive percentile-chasing is volume-and-variance instead of price. Sending three transactions at the 75th percentile through independent staked senders often lands more reliably than one transaction at the 99th, because you're buying independent draws against arrival-time jitter rather than paying a premium the scheduler barely rewards once k has flattened. Getting those independent paths — colocated senders, streaming the leader's state directly, cutting propagation delay — is an infrastructure problem, and it's the same class of edge you get from the low-latency data and sender setup we build in our Solana infrastructure and data work. If you want the mempool-equivalent visibility to know when the war is starting before your competitors' fees spike, streaming account writes with Yellowstone gRPC Geyser gives you the leading signal that the RPC fee endpoint reports two slots too late.

Where Jito changes the math

Bundles route around the fee-spam problem entirely by paying a tip into an off-chain auction with deterministic inclusion and ordering — if your bundle wins, it lands as a unit, atomically. The tradeoff: you're now bidding in a sealed second-price-ish auction against other searchers, and the tip floor moves just as violently during a mint. The right hybrid is to run both channels and let the model arbitrate: if the Jito tip percentile needed to clear is cheaper than the priority-fee percentile for equivalent landing probability, bundle it; otherwise spray priority-fee transactions. Cutting the latency on the Jito side — landing your bundle submission before the auction's effective cutoff — is exactly the ShredStream searcher latency edge that separates bundles that clear from bundles that arrive a beat late. For strategies where the on-chain state you're racing is a DLMM position, the interaction between fee bidding and execution timing gets subtler, which we get into in the JIT liquidity on Meteora DLMM writeup.

A bidding policy, concretely

Put together, the policy your bot should run each slot:

  1. Estimate the clearing bid from a 150-slot percentile curve, not the raw mean.
  2. Compute expected value: EV = P(land) × profit − P(land) × fee − P(miss) × wasted_base_fee. If EV goes negative, don't send — the single most valuable thing this model does is tell you which mints to skip.
  3. Choose channel (Jito bundle vs. priority spray) by comparing clearing costs for equal landing probability.
  4. Prefer multiple independent draws at a moderate percentile over one draw at an extreme percentile once your fitted k has flattened below roughly 3.
  5. Continuously re-estimate path_factor from your own land/miss logs; treat a low factor as an infra bug, not a fee problem.

The failure mode I see most often is a bot that lands fine in backtest and bleeds in production because the backtest assumed fee percentile fully determined inclusion. It doesn't. Arrival path and contention regime move the curve, and a model that ignores them will keep telling you to pay more when the actual fix is a better sender. Half of "priority fee tuning" is really latency and connection engineering wearing a fee-shaped mask — the same reasoning underpins how we approach EVM MEV bots and cross-venue EVM arbitrage, where inclusion economics differ but the discipline of modeling probability before bidding is identical.

If you're building a bot that has to survive contested Solana launches instead of just paying into the spam spiral, our Solana MEV and arbitrage bot development is where we turn this kind of landing-rate model into a sender that actually clears.

Need a bot like this built?

We design, build and run trading bots on Solana, Hyperliquid and Polymarket.

Start a project
#Solana#priority fees#MEV#landing rate#searcher infra