Why "submitted" is not "landed"

The most common mistake in Solana development is treating a successful sendTransaction response as success. It isn't. That response only means an RPC node accepted your bytes and put them on a path. It says nothing about whether the transaction ever reached the producing leader, made it into a block, or expired in transit.

When traders say "my transaction failed," they almost always mean it never landed - it disappeared silently. That's a different problem from an on-chain failure like a slippage revert or an insufficient balance. On-chain failures at least produce a signature you can inspect. A dropped transaction leaves nothing. Understanding the difference is the first step to fixing it.

A transaction that "failed" usually never failed on-chain. It vanished somewhere between your client and the leader, and no signature was ever recorded to tell you why.

The real reasons transactions drop

Almost every "my transaction vanished" story traces back to one of four causes. Each has a concrete fix.

CauseFix
Expired blockhashA blockhash is valid ~150 slots (~60–90s). Fetch a fresh one right before signing and submit promptly
Priority fee too lowUnder load, leaders order by compute-unit price. Set a dynamic, competitive fee from current conditions instead of a flat default
Never reached the leaderForwarding through RPC hops adds delay and drop risk. Deliver directly to the current and upcoming leaders' TPUs
Dropped under congestionWhen the leader's ingest is saturated, unstaked connections lose packets first. Use stake-weighted QoS for guaranteed bandwidth

The first three are about correctness and delivery. The fourth is the one most people miss, and it has become the dominant landing factor during the busy windows where landing actually matters.

Stake-weighted QoS (SWQoS) explained

When a Solana leader is producing a block, every client on the network is trying to push transactions into the same QUIC ingress at once. There is finite capacity. Historically that capacity was a shared free-for-all: under congestion, packets were dropped more or less indiscriminately, and a well-funded bot and a hobbyist endpoint competed on equal footing for a lane that couldn't fit either of them.

Stake-weighted QoS (SWQoS) changes the allocation. Instead of one shared lane, the leader reserves ingestion bandwidth in proportion to stake. A connection that originates from - or is sponsored by - a staked validator gets a guaranteed slice of the leader's QUIC capacity, sized to that validator's stake. The more stake behind your connection, the more of the leader's attention you're entitled to when everyone is shouting at once.

The practical effect: during exactly the congested slots where landing is hardest, a stake-weighted connection sails through while unstaked traffic gets throttled or dropped. If you've ever watched your landing rate collapse the moment the network gets busy - the moment landing matters most - SWQoS is very likely the missing piece.

Get to the leader: direct TPU delivery

Bandwidth allocation only matters if your bytes actually arrive at the right door. That door is the TPU - the Transaction Processing Unit - the QUIC ingress on the current leader. A naive path sends your transaction to a generic RPC node, which forwards it onward toward whoever it thinks the leader is. Every forward is added latency and another chance to be dropped under load.

Because Solana's leader schedule is known for the whole epoch in advance, you don't have to guess. You can resolve the current leader and the next few upcoming leaders and deliver straight to their TPUs over QUIC, so whoever builds the next block already has your transaction in hand. rpc edge's transaction sender does exactly this, and pairs it with stake-weighted connections so your delivery isn't just direct, it's prioritized at ingest. We walk through the leader schedule and TPU mechanics in detail in Landing Transactions on Solana: Leader Paths and the Jito Block Engine.

Priority fees: buying your place in line

Once your transaction is in front of the leader, the leader still has to choose what to include. When it has more transactions than fit, it orders them by priority fee - the compute-unit price you attach. A higher fee raises your position in that ordering.

The keyword is dynamic. A flat priority fee is wrong in both directions: too low and you get deprioritized the instant the network gets busy, too high and you're donating lamports during quiet periods. The right approach reads current network conditions and sets a competitive-but-not-wasteful compute-unit price per transaction. And remember the fee's limits - it improves your standing only after delivery and ingest have succeeded. Pay a huge fee on a transaction that never reaches the leader and you've paid for nothing.

Jito bundles for atomicity and bidding

Direct TPU delivery is the right tool for a single transaction you just want to land. Some strategies need more: atomicity and ordering. That's the Jito Block Engine.

A Jito bundle is a set of transactions that execute all-or-nothing, in the exact order you specify. You attach a tip to a Jito tip account, and the Block Engine runs an auction - the highest-tipping bundles win inclusion and ordering. This is the mechanism behind competitive MEV on Solana: you're not just sending, you're bidding for the right to be included exactly how you want. Reach for it when you need atomic multi-transaction execution, guaranteed ordering, or you want to bid for inclusion. For a plain single transaction, direct delivery is simpler and cheaper.

send.ts
// fresh blockhash, direct to leaders, you own the retries
const tx = await buildTx({ blockhash: latest.blockhash }); // refreshed right before signing
 
const sig = await rpcedge.sendTransaction(tx, {
  route: "tpu",            // direct to current + upcoming leaders' TPUs
  leaders: 3,              // fan out to the next few producers
  swqos: true,             // stake-weighted ingest bandwidth under congestion
  skipPreflight: true,     // you already simulated; don't pay for it again
  maxRetries: 0,           // you control retries; see below
});

Retries done right

Blindly retrying is how you pay twice or land a stale action. Set maxRetries: 0 on the RPC and own the retry loop yourself: resubmit the same signed transaction to fresh leaders within the blockhash window, stop the moment it lands or the blockhash expires, and never silently re-send something your strategy no longer wants. A retry is a delivery decision, not a default. This is also why polling for confirmation is the wrong tool - you want to be pushed the moment your transaction lands, not poll and wait, which we cover in Why RPC Polling Can't Keep Up With HFT on Solana.

Land transactions like you mean it.

rpc edge's transaction sender delivers to current and upcoming leaders' TPUs with stake-weighted QoS and the Jito Block Engine - co-located, tuned for landing rate.

View plans & pricing →

The takeaway

When a Solana transaction "fails," ask first whether it landed at all - usually it didn't. Fix the four delivery failures in order: refresh the blockhash, fee dynamically, deliver straight to the leaders' TPUs, and lean on stake-weighted QoS so your packets are accepted when the network is saturated. Reach for Jito bundles when you need atomicity, ordering, or to bid. Own your retries. And put the whole path next to the cluster - rpc edge runs its RPC and transaction sender beside Solana stake clusters and the Jito Block Engine, because every part of landing is a delivery race, and delivery races are won by proximity. That's the difference between hoping a transaction lands and engineering it to.

Frequently asked questions

Why did my Solana transaction fail?
Most of the time it didn't fail on-chain, it never landed. The usual culprits are an expired blockhash, a priority fee too low for current congestion, a transaction that never reached the current leader, or one dropped while the network was saturated. The fix is delivery: fresh blockhash, dynamic fee, and a direct path to the leader.
What is stake-weighted QoS?
Stake-weighted Quality of Service (SWQoS) lets validators allocate transaction-ingestion bandwidth in proportion to stake. Connections backed by staked validators get a guaranteed share of the leader's QUIC capacity, so during congestion their transactions are far more likely to be accepted than unstaked connections fighting over the shared lane.
How do priority fees affect landing?
A priority fee is the compute-unit price you attach. When a leader has more transactions than it can fit, it orders them by priority fee, so a competitive fee raises your place in line. It improves your odds once your transaction is in front of the leader, but it does not get it there and it does not guarantee inclusion.
What is an expired blockhash?
Every Solana transaction references a recent blockhash that is valid for about 150 slots, roughly 60 to 90 seconds. If your transaction is not processed within that window the blockhash expires and the transaction is rejected as invalid. Always fetch a fresh blockhash and submit promptly.
Do Jito bundles improve landing rate?
They can, when you need atomic all-or-nothing execution, guaranteed ordering, or you want to bid for inclusion via a tip. The Block Engine runs an auction and the highest-tipping bundles win. For a single transaction you just want to land fast, direct TPU delivery with a sensible priority fee is usually simpler and cheaper.