LND-01
Solana Transaction Landing, Checkpoint by Checkpoint
A send either reaches a block or it does not, and almost every argument about bot performance is really an argument about that one bit. This entry sets out the checkpoints between a signed message and a slot, and which instrument reports each of them.
Fault card
- Symptom
- Sends disappear with no error and no signature status
- Mechanism
- The transaction never reached a leader that produced a block
- Instrument
- getSignatureStatuses, getTransaction, block height at send time
- Correction
- Separate the five checkpoints before changing any setting
On Solana, a transaction lands when a leader includes it in a block. Everything before that point is delivery, and everything after it is execution and voting. Landing is a single bit that the network reports through the signature, and most disagreements about execution quality resolve into a disagreement about how that bit is being counted.
What landing actually means
The word gets used loosely, so it is worth pinning down. A transaction that has landed was packed into a block by the leader for some slot and executed by the runtime. That is the whole claim. It does not say the swap filled, it does not say the account was created, and it does not say the block containing it will survive. It says the network saw the bytes and ran them.
This matters because the two most common ways of describing a run are counting swaps that produced the balance change you wanted, and counting sends that were accepted by an RPC endpoint. Neither is landing. The first undercounts, because failed instructions landed and were paid for. The second overcounts, because acceptance by an endpoint is only a promise to try.
Keeping landing as its own number is what makes the rest of the diagnosis possible. If landing is high and success is low, the problem is in your instructions or your slippage tolerance. If landing is low, the problem is in the send path and no amount of instruction tuning will move it. The two failure families have almost no overlap, and mixing them is why operators change the wrong setting.
The five checkpoints
Between a signed message and a slot there are five places the transaction can stop. Each has a different owner, a different symptom and a different fix. Working through them in order is faster than guessing, because the first three produce no on-chain evidence at all and the last two produce a great deal.
| Checkpoint | Who decides | Typical stop reason | Evidence left behind |
|---|---|---|---|
| 1. Build validity | Your client | Message too large, missing signer, unresolved account | Local exception, no signature broadcast |
| 2. RPC admission | The endpoint you send to | Preflight simulation failed, blockhash unknown to that node, rate limit | An RPC error response |
| 3. Delivery to a leader | The endpoint and the network | Packet dropped, connection capacity exhausted, leader already past | Nothing at all |
| 4. Scheduling at the leader | The current leader | Not enough block space at your fee level, account write-lock ceiling reached | Nothing at all |
| 5. Inclusion and execution | The runtime | Instruction returned an error | A signature with an error object, fee charged |
Checkpoints three and four are the uncomfortable ones. They leave nothing behind, which is why operators describe them as sends that vanished. Nothing vanished; the transaction was simply never given to a block producer in time, or was given to one that had better-paying candidates. The absence of evidence is itself the diagnostic signal, and it is the reason a run needs its own attempt log.
Checkpoint one is worth a separate mention because it is entirely under your control. A legacy transaction must serialise within the 1,232-byte packet the network accepts, a figure that comes from the 1,280-byte IPv6 minimum transmission unit minus header overhead. Versioned transactions with address lookup tables exist precisely to buy account slots back inside that ceiling, and a builder that has never hit it will hit it the first time a route grows an extra hop.
Landed, succeeded, confirmed
Three words that get used interchangeably describe three independent facts. A transaction can be any combination of them, and the combinations that look strange are the ones worth understanding.
| State | Question it answers | Where it comes from | Fee charged |
|---|---|---|---|
| Landed | Was it included in a block? | Presence of the signature in a slot | Yes |
| Succeeded | Did every instruction return without error? | The err field on the transaction status | Yes, either way |
| Confirmed | How much of the cluster has voted on that block? | Commitment level: processed, confirmed, finalized | Not related |
Landed and failed is the most common surprising combination. A swap that hit its slippage guard was included, executed, reverted its own effects, and charged the base fee of 5,000 lamports per signature plus whatever priority fee it carried. From the network's point of view this is a completely normal transaction. From a cost report's point of view it is money spent for no position change, and it must be counted as such.
Not landed and no error is the second. The client sent, the endpoint accepted, and no signature status ever appeared. There is no exception to catch because nothing went wrong locally. The only correct handling is to treat the attempt as closed once the blockhash cannot be accepted any more, and to record it as an attempt that produced no landing rather than as a mystery.
Commitment sits on a different axis. The three levels published by the cluster are processed, confirmed and finalized, and they answer how much voting has happened on the block, not whether your instructions worked. Reading balances at processed is fast and occasionally wrong; reading accounting at finalized is slow and stable. Choosing one level for the interface and a stricter one for the ledger is a legitimate design, as long as the two are labelled.
The instruments that report each state
Every claim above maps to a specific call. The reason to name them is that an operator with a disputed landing rate usually cannot say which call produced the number, and a number without a source cannot be argued with. The Solana signature status method and the transaction fetch are the two that matter most.
getSignatureStatusesanswers landed and succeeded together: a null status means no landing yet, a status with a null error means landed and succeeded, and a status with an error object means landed and failed. Statuses age out of the recent cache, so a late poll needs the history search flag.getTransactionanswers the same questions with the slot, the fee actually charged and the compute units consumed. It is the call to use when closing out a run rather than when tracking it live.getLatestBlockhashreturns both the blockhash and the last block height at which it will still be accepted, which is what defines the deadline for the attempt.getBlockHeightis the clock that deadline is measured against. Wall time is a poor proxy because skipped slots make the mapping between seconds and blocks variable.getSlotLeadersexposes which validators are scheduled to produce upcoming slots, which is context for delivery rather than a diagnostic on its own.
None of these instruments requires special access. Any endpoint that serves standard JSON-RPC will answer all of them, and a run that logs the four numbers those calls produce for every attempt can reconstruct its own landing history without trusting anyone's dashboard. That reconstruction is the entire method this desk uses.
A worked landing budget
Numbers make the distinctions concrete, so here is an illustrative example built only from the documented base fee. The volumes are chosen for arithmetic, not observed anywhere. Suppose a run makes 500 send attempts against a single signer, and the attempt log at the end shows 420 signatures with a status and 80 with none.
| Bucket | Count | Base fee charged | What it tells you |
|---|---|---|---|
| Never landed | 80 | 0 lamports | Send path problem: delivery, expiry or scheduling |
| Landed, instruction failed | 60 | 300,000 lamports | Instruction problem: slippage, balance, account state |
| Landed, succeeded | 360 | 1,800,000 lamports | The only bucket that changed a position |
| Total attempts | 500 | 2,100,000 lamports | 0.0021 SOL in base fees before priority fees |
Two ratios come out of that table and they are not the same. Landing rate is 420 of 500, or 84 percent. Success rate is 360 of 500, or 72 percent. A report that quotes only one of them is hiding the other, and the two demand opposite corrections: the 80 missing sends are answered by the send path, the 60 reverted ones by the instruction and its tolerances.
The base fee in this example is a protocol constant of 5,000 lamports per signature. The counts are invented for the arithmetic. Any figure that claims to be a typical landing rate without naming the run, the endpoint and the window is not a measurement.
Reading one failed send
Before touching aggregates, it is worth being able to read a single attempt end to end. The sequence below takes about a minute per transaction and settles most arguments, because it produces a checkpoint number rather than an opinion.
- Confirm the client produced a signature. If signing threw, the attempt stopped at checkpoint one and the network was never involved. Nothing about fees or endpoints is relevant.
- Check the response from the send call. An RPC error means checkpoint two. Preflight failures name the offending instruction, and that message is the most useful single string in the whole path.
- Record the block height at send time and the last valid block height. The gap between them is the entire budget the attempt has. If the gap was already small when you sent, delivery had almost no room.
- Poll the signature status until the last valid block height passes. A status that appears is checkpoint five, with or without an error. No status by the deadline means checkpoint three or four.
- If a status appeared with an error, read the instruction index. That index points at exactly which instruction returned the error, which converts a vague failed swap into a specific program error code.
- Write the result into the attempt log with the slot. The slot is what lets you go back later and ask what the network was doing at that moment rather than what it is doing now.
Doing this for ten failures usually reveals that they are not one problem. A run with a poor landing rate typically has two or three distinct causes with quite different fixes, and the aggregate rate averages them into a single unhelpful number. Splitting first and tuning second is the order that saves the most time.
What to change, in order
Corrections have costs, and a tuning list that does not state them is a wish list. Each item below names what it buys and what it charges, so the trade is visible before it is made.
| Correction | Helps with | What it costs |
|---|---|---|
| Fetch the blockhash immediately before signing | Expiry during a slow build | An extra round trip on every attempt |
| Resend the same signed bytes on a schedule | Delivery drops at checkpoint three | More requests against your endpoint quota |
| Attach a priority fee | Scheduling pressure at checkpoint four | Real lamports on every landed attempt, including failed ones |
| Set an explicit compute unit limit | Wasted fee on an over-requested budget | A simulation call, and a rebuild if the route changes |
| Skip preflight | One round trip of latency | Losing the error message, and paying fees for transactions that would have been rejected |
| Widen slippage tolerance | Instruction failures, not landing | Worse fills, and no effect whatsoever on checkpoints three and four |
The last row is there because it is the most common misapplied fix. Widening slippage changes what happens after inclusion. If the transaction is not being included, the tolerance is irrelevant and the only thing a wider guard achieves is a worse price on the attempts that were already landing.
Order matters as much as content. Expiry is checked first because it is free to fix and invalidates every other measurement. Delivery second, because resending costs nothing but requests. Fees third, because that is where money starts moving. An operator who reaches for the fee lever first has usually paid for a problem that was never a scheduling problem.
When the send path stops being yours
There is a point at which building this instrumentation stops being the cheapest option. If the send path is not the thing you are trying to learn, a hosted runner moves the whole checkpoint list behind an interface, and the question changes from how do I fix delivery to how do I verify what I am being told. That is a different and much shorter list of questions.
The useful comparison when picking one is not the feature grid, it is the reporting. A tool that hands back signatures and slots can be audited against the same instruments described above; a tool that hands back a success percentage cannot be audited at all. That distinction is worth more than any headline number when reading a roundup of the best Solana volume bot options, because it is the only property you can independently check.
The same applies to running one. Whether the engine is yours or a hosted Solana volume bot, the operator's job after the first hour is the same: keep an attempt log, split landing from success, and treat any number without a source as decoration. The checkpoints do not care who wrote the sender.
What none of this settles is whether the run is worth making. Landing is a delivery property, not a strategy. This log takes the strategy as given and asks only whether the transactions that were supposed to happen actually happened, at what cost, and which of the five checkpoints stopped the ones that did not.
Questions this entry keeps getting
What does it mean for a Solana transaction to land?
It means the transaction was included in a block produced by a leader and therefore executed by the runtime. Landing says nothing about whether the instructions succeeded. A swap that reverts on a slippage check has landed, has consumed compute, and has paid its fee. A swap that expired before any leader packed it has not landed and has paid nothing.
Is a landed transaction the same as a confirmed transaction?
No. Landing is inclusion in a block. Confirmation is a statement about how much of the cluster has voted on the block that contains it. A transaction can be visible at the processed commitment level and still belong to a block that never becomes part of the canonical chain, which is why accounting should read outcomes at a stricter level than a user interface does.
Do failed transactions cost anything on Solana?
Yes, if they landed. The base fee of 5,000 lamports per signature is charged when a transaction is included in a block, whether or not its instructions succeeded, and any priority fee attached to it is charged as well. Transactions rejected during preflight simulation never reach a block and cost nothing beyond the request itself.
Why do some sends produce no error at all?
Because a send that is accepted by an RPC node and then dropped somewhere between that node and a block-producing leader has no error to report. The client got an acknowledgement of submission, not of inclusion. This is the class of failure that has to be detected by polling the signature rather than by catching an exception.
Does a higher priority fee guarantee landing?
No. A priority fee improves your position in the ordering a leader applies when it has more candidate transactions than block space, which is a real advantage during contention. It does nothing about an expired blockhash, a transaction that never reached the leader, a write-lock ceiling on a hot account, or an instruction that would fail anyway.
How long should a client wait before deciding a send is lost?
Until the blockhash it references can no longer be accepted, which is a block-height condition rather than a clock condition. If the last valid block height returned with the blockhash has passed and the signature still has no status, the transaction cannot land and the attempt is closed. Waiting longer produces no new information.
Filed under Landing. Arithmetic on this page is either a documented protocol constant or an illustrative example built from numbers you supply. If a figure here is wrong or has moved, send the desk a correction and the entry gets amended rather than quietly rewritten.