LAT-03
Measuring Landing Rate Without Fooling Yourself
A landing rate is a fraction, and almost every disagreement about one is a disagreement about its denominator. This entry fixes the definitions, lists the fields an attempt record has to carry, and shows the same run producing three different rates depending on how it is counted.
Fault card
- Symptom
- Two reports of the same run disagree about performance
- Mechanism
- Different denominators, silently substituted for each other
- Instrument
- Attempt record keyed by intent, with slots and outcomes
- Correction
- Publish the denominator with every rate, or do not publish the rate
A landing rate is landed transactions divided by intended transactions, over a stated window, computed from records the sender wrote itself. Every part of that sentence is load-bearing. Change the denominator to sends, or the window to whatever period looks best, and the same run will produce a number that is higher, defensible-sounding and useless.
One definition, stated
An intent is a decision to make one transaction: this amount, this venue, this signer. An attempt is one signed artefact created to fulfil an intent. A send is one submission of an artefact. Those three are not interchangeable, and a rate computed against each of them answers a different question.
The rate this desk uses is landed intents over total intents. It answers the question an operator actually has, which is what fraction of what I meant to do happened. It is also the least flattering of the available fractions, which is a reasonable sign that it is the honest one.
The alternative fractions are not wrong, they are just different measurements that must be labelled. Landed artefacts over total artefacts describes the send path's efficiency and hides rebuilds. Landed over sends describes delivery reliability and drops toward zero as resends increase, which makes it look bad for a good reason. Neither may be presented as a landing rate without saying so.
The four numbers
One rate is not enough to diagnose anything. Four numbers, always reported together, cover the whole surface, and each one answers a question the others cannot.
| Number | Definition | What it exposes |
|---|---|---|
| Intents | Decisions to transact in the window | The denominator everything else is measured against |
| Landing rate | Intents with a landed artefact, over intents | Whether the send path is working |
| Success rate | Intents with a landed artefact carrying no error, over intents | Whether the instructions and tolerances are right |
| Cost per landed swap | Total lamports spent, over successful intents | What the other three cost to achieve |
Reported together they are hard to game. Raising the landing rate by bidding more shows up immediately in cost per landed swap. Raising it by rebuilding shows up as artefacts exceeding intents, which the first number makes visible. Raising the success rate by widening slippage shows up in fills rather than here, which is why a fill-quality measure belongs beside these four for anyone trading seriously.
What an attempt record must carry
None of the four numbers can be computed after the fact from chain data alone, because the failures that matter most left nothing on chain. The record has to be written by the sender, at the moment, and it needs a specific set of fields.
| Field | Written when | Why it is needed |
|---|---|---|
| Intent id | Intent created | The join key that makes rebuilds visible |
| Signature | Artefact signed | The only handle the network understands |
| Blockhash and last valid block height | Artefact signed | Defines the deadline and therefore the expired outcome |
| Block height at first send | First send | Shows how much window was already consumed |
| Send count | Every send | Separates delivery pressure from endpoint cost |
| Endpoint identifier | Every send | Makes provider-specific problems visible |
| Landed slot | Status observed | Time to land, and the ability to look up conditions later |
| Error object | Status observed | Splits landed and failed from landed and succeeded |
| Requested and consumed units | Build and confirmation | Validates the compute margin policy |
| Fee paid | Confirmation | The numerator of cost per landed swap |
Ten fields is not a burden, and their absence is why so many runs cannot answer basic questions afterwards. The two most often missing are the endpoint identifier and the block height at first send, and they are the two that turn an unexplained variance into a diagnosis.
Time to land, in slots
Latency should be measured in the network's own clock. Time to land is the landed slot minus the slot observed at first send, and expressing it in slots removes every source of client-side timing error. Converting to seconds afterwards is fine for presentation; measuring in seconds is not.
Report it as a distribution. The median tells you how the ordinary case behaves and is stable enough to track over time. The upper percentiles tell you what the bad case looks like, and the bad case is what determines whether a strategy that depends on prompt execution is viable. An average of the two is a number that describes neither.
There is a second measurement hiding in the same fields, and it is free. The gap between the block height at first send and the last valid block height is the window an attempt had available, and comparing that against the window it actually used shows how close the send path runs to its own deadline. A path that routinely lands with a handful of blocks to spare is one bad minute away from a wave of expiries, and it will look perfectly healthy until that minute arrives.
The distribution's shape is also diagnostic. A tight cluster with a long thin tail is normal behaviour with occasional delivery misses. A distribution with two humps usually means two populations have been mixed, most often two venues or two endpoints, and separating them will produce two clean distributions and an obvious culprit.
One run, three rates
The arithmetic below is illustrative, chosen to show how the same events produce different published figures. It describes 500 intents in one window.
| Counted as | Numerator | Denominator | Rate |
|---|---|---|---|
| Landed intents over intents | 390 | 500 | 78.0 percent |
| Landed artefacts over artefacts | 410 | 620 | 66.1 percent |
| Landed artefacts over intents | 410 | 500 | 82.0 percent |
All three fractions come from one set of events. The first is the honest answer to what fraction of my intentions happened. The second describes the send path and looks worse because it counts every rebuild as a separate opportunity. The third exceeds the first because 620 artefacts were created for 500 intents, meaning 120 rebuilds occurred and 20 intents landed more than once.
That third row is the one that appears in optimistic reporting, and it is the one to challenge. A rate that can exceed the number of things you asked for is not measuring what its label claims. The tell is always the same: artefacts greater than intents, which is the duplicate signature discussed at length in the landing section of this log.
All counts above are invented for the arithmetic. The point is the relationship between the three fractions, which holds for any run where rebuilds occur. If a report does not let you compute all three, it has chosen which one you get to see.
Six ways the number lies
Each of these is a real accounting choice rather than deception, and each moves the rate in a predictable direction. Knowing the direction is enough to interrogate any figure.
- Counting resends as attempts pushes the rate down and makes a healthy path look broken. It is measuring delivery, not landing.
- Dropping expired attempts pushes the rate up, because expiries are the failures with no chain evidence and the easiest to lose.
- Counting an already-processed rejection as a failure pushes the rate down while the transaction is sitting on chain, landed.
- Starting the window after a warm-up pushes the rate up by excluding the period where configuration was still wrong.
- Mixing venues in one figure hides a venue that is failing, because a healthy majority absorbs it.
- Reporting only attempts that received a signature is survivorship: everything that failed before the send call disappears from the denominator.
None of these requires bad faith to occur. The last one in particular happens by default in any implementation that builds its report from the signature list, because a build that never produced a signature has nothing to join on. It has to be deliberately prevented, by writing the intent record before the network is touched.
Building the measurement
The measurement is a side effect of the send path rather than a reporting layer bolted on afterwards. Built in this order it costs very little; built afterwards it usually cannot be built at all, because the events that matter were never recorded.
- Write the intent before any network call. Costs one record per decision and fixes the denominator permanently. Everything else joins to this row.
- Attach the artefact, with its deadline, at signing time. Costs three fields and makes the expired outcome computable without guessing.
- Increment a send counter and record the endpoint on every submission. Costs two writes per send and turns request cost and provider faults into visible quantities.
- Poll status until landed or the deadline passes, then write the terminal outcome once. Costs the polling loop you already need, and produces the only clean close condition available.
- Fetch fee and consumed units for landed artefacts. Costs one call per landed transaction and supplies both the cost numerator and the compute margin check.
- Aggregate at window boundaries, never on demand. Costs a scheduled job and prevents the window from being chosen after the results are known, which is the most common way a rate becomes flattering.
The sixth step is a discipline rather than a technical requirement, and it is the one most worth insisting on. A window chosen before the data exists is a measurement; a window chosen afterwards is an argument. Nothing about the code changes, only who gets to pick the boundaries.
Windows and comparability
A rate without a window is not comparable to anything. Network conditions move, and a figure gathered during a quiet hour and one gathered during a busy hour are measurements of different environments, not of different senders.
The minimum honest label is the start and end of the window, the number of intents, and the venue or venues involved. With those, two figures can be compared or explicitly refused as incomparable. Without them, any comparison is a guess dressed as evidence, and the guess always favours whoever chose the window.
Slot numbers make this precise in a way timestamps do not. Recording the first and last slot of the window lets anyone reconstruct what the network was doing during it, independent of your clock and your logs. It costs two integers and is the difference between a claim and a reproducible one.
Dashboards are not evidence
A chart is a rendering of a query, and the query embodies every accounting choice described above. Two dashboards over identical data can disagree completely and both be drawn correctly, which is why the artefact worth keeping is the attempt log rather than the picture made from it.
The practical test is whether a figure can be traced back to individual signatures. If a reported landing rate cannot be expanded into the list of intents that failed, with their deadlines and their endpoints, it is a summary of something rather than a measurement of it. Anyone can produce the expansion from a proper attempt log in one query; nobody can produce it from a chart.
This also settles a recurring argument about explorers. Block explorers are excellent for confirming what a specific signature did, and they are structurally incapable of telling you what your run intended, because intentions are not on chain. Using an explorer as the source of a landing rate guarantees the survivorship error, since only the transactions that landed are visible there at all.
Reading someone else's number
The same discipline applied outward becomes a short list of questions for any tool that publishes performance figures. What is the denominator. What is the window. Are expired attempts included. Does the figure count artefacts or intents. What did it cost per landed swap. Five questions, and a report that answers all five is unusual enough to be a signal in itself.
This is the standard worth applying to a hosted Solana Volume Bot Pro or to any other engine that sends on your behalf, and it is not an adversarial standard. It is the same one this entry asks you to apply to your own logs, and a vendor who has done the work will find the questions easy.
Where a platform documents its methodology publicly, that document is worth reading against the definitions here rather than against the marketing around it. A description of how volume campaigns are measured either names denominators and windows or it does not, and that alone tells you how much weight the resulting numbers can carry.
The final check is arithmetic rather than trust. Take the reported figures, reconstruct the counts they imply, and see whether they are internally consistent. Artefacts must be at least intents. Successes cannot exceed landings. Fees must be consistent with the landed count and the documented base fee of 5,000 lamports per signature. Numbers that fail those checks are not measurements, whatever they are called.
Questions this entry keeps getting
What is a landing rate on Solana?
It is the fraction of intended transactions that were included in a block. The numerator is the count of intents that produced at least one signature with a status; the denominator is the count of intents. Both parts have to be stated, because a rate computed against sends or against resends describes something else entirely.
Should a landed but failed transaction count as a landing?
Yes, for the landing rate, because it reached a block and paid its fee. It should not count toward a success rate. Keeping both figures is what lets you tell a send-path problem from an instruction problem, and merging them into a single number destroys exactly the distinction you need.
How is time to land measured?
In slots, as the difference between the slot the transaction landed in and the slot observed at first send. Slots are the network's own clock and are unaffected by the client's wall time. Reporting this as a distribution rather than an average matters, because the tail is where the interesting behaviour is.
Why do expired transactions get left out of reports?
Usually because they never produce anything to join on. They have a signature but no status, no slot and no fee, so a report built by reading chain data simply does not see them. That is exactly why the attempt log has to be written by the sender rather than reconstructed afterwards.
Is a higher landing rate always better?
Not on its own. A rate raised by paying far more per transaction, or by rebuilding transactions until something sticks, has costs that the rate does not show. Landing rate is only meaningful alongside cost per landed swap and the count of intents, which together describe what was spent to achieve it.
How large a sample is needed before the rate means anything?
Enough that a handful of outcomes cannot move it much, and drawn from a defined window rather than assembled from convenient periods. A rate quoted from a few dozen attempts across an afternoon is an anecdote. The window is as important as the count, because network conditions change underneath the measurement.
Filed under Latency. 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.