I built a C++20 packet I/O library and benchmarked AF_XDP against DPDK and raw Verbs on real hardware: ConnectX-4 Lx, Intel XXV710-DA2, and Intel I225-V. Each configuration ran for 24 hours in a port-to-port loopback, measuring RTT with HdrHistogram — median through P99.999, plus max.
Spoiler: DPDK outperforms AF_XDP on every latency metric across all NICs.
One point that I think is underappreciated: a commonly marketed advantage of AF_XDP is that it doesn't unbind the NIC driver, so the interface stays visible to "ip link" and ethtool. That's true for Intel NICs, where DPDK requires binding to vfio-pci. But it's not true for mlx5 (ConnectX-4/5/6/7), which is a bifurcated driver — the NIC stays fully visible to the kernel while DPDK runs. On Mellanox hardware, the main practical argument for AF_XDP largely disappears.
On implementation effort: even with libbpf and libxdp, custom AF_XDP has high code complexity and plenty of driver-specific quirks. Its four lock-free SPSC rings (fill/RX/TX/completion) are counterintuitive and fairly difficult to comprehend. Without the helper libraries I'd call it a serious long-term project. For most use cases I'd recommend DPDK's AF_XDP PMD instead of a from-scratch implementation — in my results, my custom implementation performed only marginally better than DPDK’s AF_XDP PMD.
Most public AF_XDP examples I found lack rigorous benchmarking on real hardware; that's the gap this project aims to fill. Everything is open source: the library, the full results tables, histograms, and per-driver known-issues notes.
Next up in the same repo: Solarflare ef_vi vs DPDK on an X2522-PLUS — the DPDK layer is done, the ef_vi backend is in progress.
Let me know if you guys have feedback on the code, benchmark methodology and/or anything. I’m also happy to answer any questions.
CoreCppEngineer•1h ago
Spoiler: DPDK outperforms AF_XDP on every latency metric across all NICs. One point that I think is underappreciated: a commonly marketed advantage of AF_XDP is that it doesn't unbind the NIC driver, so the interface stays visible to "ip link" and ethtool. That's true for Intel NICs, where DPDK requires binding to vfio-pci. But it's not true for mlx5 (ConnectX-4/5/6/7), which is a bifurcated driver — the NIC stays fully visible to the kernel while DPDK runs. On Mellanox hardware, the main practical argument for AF_XDP largely disappears.
On implementation effort: even with libbpf and libxdp, custom AF_XDP has high code complexity and plenty of driver-specific quirks. Its four lock-free SPSC rings (fill/RX/TX/completion) are counterintuitive and fairly difficult to comprehend. Without the helper libraries I'd call it a serious long-term project. For most use cases I'd recommend DPDK's AF_XDP PMD instead of a from-scratch implementation — in my results, my custom implementation performed only marginally better than DPDK’s AF_XDP PMD.
Most public AF_XDP examples I found lack rigorous benchmarking on real hardware; that's the gap this project aims to fill. Everything is open source: the library, the full results tables, histograms, and per-driver known-issues notes. Next up in the same repo: Solarflare ef_vi vs DPDK on an X2522-PLUS — the DPDK layer is done, the ef_vi backend is in progress.
Let me know if you guys have feedback on the code, benchmark methodology and/or anything. I’m also happy to answer any questions.