Why AF_XDP¶
Docs-site note (2026-06-25): A "why we chose it" page — the datapath tradeoff only; the throughput numbers and full datapath design live in the Performance overview.
The decision¶
A Solana validator drinks from a firehose. During its leader window and continuously as it follows the chain, it ingests a torrent of small UDP packets — shreds (the ~1228-byte pieces a block is split into) plus QUIC traffic for transactions and votes. How those packets get from the wire into the validator's memory is a load-bearing performance decision.
Vexor uses a zero-copy AF_XDP datapath. The packet ingest is DONE and live on testnet (deployed
with VEX_ENABLE_AFXDP=1), feeding the shred-ingest and native-QUIC paths, with a fallback to standard
kernel sockets when the environment doesn't support AF_XDP.
This page explains why AF_XDP and not the two obvious alternatives: plain kernel UDP sockets (simple, slow) or a full userspace NIC stack like DPDK (fast, operationally heavy). AF_XDP is the kernel-bypass-lite middle: it delivers packets zero-copy into userspace while keeping the in-kernel NIC driver.
The three options¶
| Approach | What it is | Tradeoff |
|---|---|---|
| Plain kernel UDP sockets | The normal BSD socket path. Each packet is an sk_buff, a syscall, and at least one copy into userspace. |
Simplest and most portable, but per-packet syscall + copy overhead does not keep up with the shred firehose at scale. |
| AF_XDP (chosen) | A memory-mapped socket (UMEM rings) that an in-kernel XDP/eBPF hook redirects packets into — zero-copy, no per-packet syscall, but the kernel driver stays in place. | Near-userspace throughput and latency while keeping kernel device management, ethtool, and normal operations. Needs a NIC/driver and kernel that support it. |
| Full userspace NIC (DPDK / kernel-bypass) | The application takes over the network device entirely; the kernel no longer sees it. | Maximum performance, but you lose the kernel's networking entirely — dedicated NICs, hugepage plumbing, no tcpdump, much heavier operational and porting cost. |
AF_XDP captures most of the kernel-bypass win — eliminating the per-packet syscall and the copy on the hot ingest path — without the operational weight of owning the device. For a validator that has to run on a range of operator hardware, keeping the in-kernel driver is a meaningful practical advantage.
Why we landed on AF_XDP¶
- Zero-copy on the hot path. Packets land in a shared memory-mapped region (UMEM) that both the kernel and the validator see; the shred-ingest path reads them in place instead of copying every ~1228-byte packet through a syscall boundary. That removes the dominant per-packet cost at firehose volume.
- Keeps the kernel driver. Unlike full userspace bypass, AF_XDP leaves the NIC under kernel control, so standard device management, multi-queue steering, and operational tooling still work. The porting and ops burden is far lower than DPDK.
- It is the same choice the other fast client made. Firedancer's default high-performance datapath is
XDP with
xdp_zero_copy = true— which is AF_XDP zero-copy. AF_XDP (the userspace delivery socket) and the XDP/eBPF program (the in-kernel redirect that feeds it) are two halves of one mechanism, not competing choices. Vexor and Firedancer are doing the same thing here. - Graceful fallback. Not every operator environment has a NIC/driver/kernel combination that supports AF_XDP (especially zero-copy mode). When it isn't available, Vexor falls back to standard kernel UDP sockets — slower, but correct and portable. AF_XDP is an opt-in performance lever, not a hard requirement to run.
Honest caveats¶
- NIC, driver, and kernel support matters. AF_XDP needs driver support, and zero-copy mode in particular depends on the specific NIC/driver/kernel. On unsupported combinations you get copy-mode (still faster than plain sockets, but not zero-copy) or the socket fallback. The deployment enables AF_XDP explicitly; whether a given deployment runs full zero-copy mode versus copy mode depends on the NIC/driver/kernel combination, and the AF_XDP build and flag plumbing is in place either way.
- This page is the "why," not the "how." Throughput and latency figures, the UMEM ring layout, queue steering, and how the datapath feeds the tiles are owned by the Performance overview. No specific Vexor packet-rate numbers are claimed here.
tcpdumpblind spot. As with any XDP-socket datapath, traffic arriving on an AF_XDP socket is not visible totcpdump— a known operational quirk of the approach, not a Vexor-specific limitation.
See also¶
- Network Stack & Performance overview — the datapath in depth, with numbers.
- Why a Tile Architecture — why ingest runs on its own cores, off the consensus path.