# TPU landing: engine-side configuration and leader schedule

> How mod_solana_tpu discovers the leader schedule, what each reported config key means, and how per-leader land success and p50 latency are read in the console.

The **TPU landing** screen submits raw transactions straight to a validator's
TPU port over QUIC (ALPN `solana-tpu`, ephemeral ed25519 client identity)
instead of going through an RPC `sendTransaction`. The screen is a **read-only
view**. Every value it shows is reported by the engine module
`mod_solana_tpu`, which is configured where the engine is deployed — not from
this console.

This page explains what the module owns, what each reported key means, and how
to read the per-leader numbers.

## What mod_solana_tpu owns

`mod_solana_tpu` is the engine-side component of TPU landing. It owns:

- The **RPC connection** used for discovery (`rpc_url`), and its health, probe
  latency and slot lag.
- The **leader schedule**: which validator identity owns which slot, refreshed
  on an interval.
- The **QUIC connections** to each leader's TPU endpoint, including ALPN
  negotiation and the client certificate presented on the handshake.
- The **fan-out decision**: how many upcoming leaders each transaction is sent
  to.
- The **land accounting**: landed / failed counts and latency per leader, which
  the console renders per slot and in the completed-leader table.

The console reads all of this through a single procedure, `tpu.schedule`. There
are no write controls on this screen, and the **Landing config** card is
deliberately rendered as read-only rows: a toggle here would not change engine
behaviour. To change any key below, change the engine's `mod_solana_tpu`
configuration and redeploy or reload the module. The console will then report
the new effective value.

## Configuration keys

The config block returned by `tpu.schedule` (`tpu.config`) is the module's
**effective** configuration, not a copy of your config file. Keys that are not
configured come back empty and render as `—`.

| Key               | Console row / tile      | What it controls                                                                                   |
| ----------------- | ----------------------- | -------------------------------------------------------------------------------------------------- |
| `rpc_url`         | `rpc_url health`, Landing config | The RPC endpoint the module calls to discover the leader schedule and track the current slot. |
| `slot_refresh_ms` | `slot_refresh_ms`       | How often the module re-reads slot / schedule state from `rpc_url`, in milliseconds.               |
| `fanout_leaders`  | `fanout_leaders`        | How many of the next leaders each transaction is fanned out to.                                    |
| `alpn`            | Landing config          | The ALPN protocol negotiated on the QUIC handshake with the validator's TPU port (`solana-tpu`).    |
| client cert       | `client cert`           | The certificate presented per QUIC connection to a leader.                                          |

`Target leaders` is reported as `auto-discover`: the module resolves leaders
from the schedule rather than from a static host list. There is no
console-side way to pin a manual host on this screen.

`tpu.schedule` reports effective values only — it does not report the accepted
range for any key. Consult the `mod_solana_tpu` configuration reference for the
engine build you run before changing `slot_refresh_ms` or `fanout_leaders`.

## What the client certificate is for

The `client cert` tile shows the certificate the module presents on each QUIC
connection, and is labelled **per-connection**. It is distinct from the
ephemeral ed25519 identity in the page subtitle:

- The **ephemeral ed25519 identity** is the keypair the module generates for the
  QUIC/TLS session. It identifies the *connection*, not your account, and is
  not the fee payer or signer of any transaction.
- The **client cert** is what the module actually presents on the handshake and
  is configured engine-side. When the tile reads `—`, the sub-label is `not
  configured` and no certificate is being presented.

Neither value authorises anything on behalf of your FirstByte workspace, and
neither signs transactions. Transaction signing happens before the raw
transaction reaches this module.

## How the leader schedule is discovered and refreshed

The **Leader schedule** card is built from `tpu.leaders`, discovered from
`getLeaderSchedule` on `rpc_url`. Each card in the timeline is one leader slot
and carries four slots per leader, per the standard rotation.

Each leader entry reports:

| Field     | Meaning                                                |
| --------- | ------------------------------------------------------ |
| `slot`    | The slot number this leader owns.                      |
| `name`    | The validator's display name.                          |
| `pubkey`  | The validator identity pubkey.                          |
| `quic`    | The TPU QUIC endpoint the module connects to.           |
| `region`  | The region reported for the validator.                  |
| `state`   | `current`, `next`, or `upcoming`.                       |
| `land`    | Land success percentage, or `null`.                     |
| `fail`    | Failed lands, or `null`.                                |
| `latency` | p50 latency in milliseconds, or `null`.                 |

The `state` field drives the timeline styling: `current` renders as a live pip,
`next` as a warning tone, `upcoming` as inactive.

Refresh behaviour comes from two places:

- **The module** re-reads schedule state on its own `slot_refresh_ms` interval.
  `tpu.rpc.lastRefresh` shows when that last happened, under the
  `slot_refresh_ms` tile.
- **The console** `Refresh schedule` button re-runs the `tpu.schedule` query. It
  pulls the module's current reported state; it does not shorten the module's
  refresh interval.

So a `lastRefresh` that stays old after you press `Refresh schedule` means the
module is not refreshing, not that the console failed to fetch.

### Fan-out

The first `fanout_leaders` entries in the timeline are marked `fan-out` and
highlighted. These are the leaders the module sends each transaction to. The
card header states this directly: *fanout to first N leaders*. If
`fanout_leaders` is unset, the tile reads `not configured` and no leaders are
highlighted.

## How land success, failed lands and p50 latency are measured

Land accounting is per leader, and the module reports it in two places.

**Per upcoming/current leader** (`tpu.leaders[]`), shown in the selected-leader
detail card:

- **Land success** — `land`, a percentage, rendered with a meter row.
- **Failed lands** — `fail`, a count.
- **p50 latency** — `latency`, the median in milliseconds, so a single slow
  submission does not move it.

**Per completed leader** (`tpu.recent[]`), shown in *Recently completed
leaders*, which reports `landed`, `fail`, `land` and `latency` side by side for
the last rotations. This is the table to use when you want the raw counts
behind a percentage: `land` is the share of that leader's submission attempts
that landed, and `landed` plus `fail` are the attempt counts it was derived
from.

All four numbers are nullable. A leader with no submission attempts yet reports
`null`, and the console renders `—` rather than `0`. A `—` on a `current`
leader is normal in the first moments of its slot window; a `—` on a leader
your fan-out has been targeting for a while is not.

### How the console colours these numbers

The timeline and detail card colour `land` on fixed bands, so the colour tells
you which bucket a leader is in without reading the number:

| `land` value | Colour      |
| ------------ | ----------- |
| above 94%    | success     |
| above 89%    | warning     |
| 89% or below | destructive |
| `null`       | muted, `—`  |

These are display bands in the console only. They are not thresholds that
`mod_solana_tpu` acts on, and they do not cause the module to stop using a
leader.

## Reading a bad leader vs a stale schedule vs an unhealthy RPC

Three different failures look similar at a glance — low land success. Use the
top strip to separate them before you touch anything.

**An unhealthy RPC.** The `rpc_url health` tile reads anything other than
`healthy`, or `slot lag` is elevated. Discovery is the problem, not landing.
The module cannot learn who the next leaders are, so fan-out targets the wrong
validators and lands fail broadly — across *all* leaders, not a specific one.
If `latency not probed` is shown, the module has no probe result for the RPC
at all. Fix `rpc_url` first; per-leader numbers are not trustworthy until
health is `healthy`.

**A stale schedule.** The RPC is `healthy`, but `refreshed <lastRefresh>` under
the `slot_refresh_ms` tile is old relative to `slot_refresh_ms`. The module has
a schedule, but it is out of date, so the leader marked `current` in the
timeline may no longer be the leader. Symptom shape: failures cluster on the
`current` and `next` cards while completed leaders in the table look fine.
Check that the module's refresh loop is running and that `slot_refresh_ms` is
set — a `—` there means it is not configured.

**A bad leader.** RPC is `healthy`, `lastRefresh` is recent, and the failure is
isolated to one or two validators: a low `land` and a high `fail` on specific
cards, with neighbouring leaders in the green. Confirm it in *Recently
completed leaders* — a genuinely bad leader shows repeated low `land%` across
rotations, while a one-off shows a single bad row. A raised `p50` on that one
leader alongside normal `p50` elsewhere points at the path to its `quic`
endpoint rather than at your submission pipeline.

**Nothing at all.** If the timeline shows *No leader schedule* and the table
shows *No landings yet*, TPU landing is not yet active for this workspace and
there is nothing to diagnose — the module has reported no schedule and no
completed rotations.

## Submitting to a specific leader

This screen does not submit transactions. To send a raw transaction to one
chosen leader rather than to the fan-out set, use the **Submit** screen; copy
the `Validator identity (pubkey)` or `TPU QUIC endpoint` from the selected
leader's detail card to identify the target.
