2026-07-22
Stack Overflow: View Question
Tags: rust, memory-management, async-await, numa
Score: 0 | Views: 177
The asker wants to build a high-performance Rust application on a NUMA (Non-Uniform Memory Access) system and is looking for concrete guidance on three intertwined problems: which async runtime to pick when the default choice (Tokio) has no NUMA awareness, how custom allocators fit in, and what off-the-shelf NUMA-aware allocation options exist. On a NUMA box, a core reaching memory on a remote socket pays multiples of the latency of local access, so the entire performance model of "just spawn tasks" quietly breaks down.
Why this is genuinely hard. NUMA performance is a systems problem that cuts across the runtime, allocator, and OS scheduler simultaneously. It's not enough to pin threads to a node — you also need memory allocated on that node's local DIMMs, and you need work-stealing runtimes to not steal tasks across NUMA boundaries, or you throw away the locality you set up. Tokio's work-stealing scheduler is explicitly node-agnostic, and Rust's global allocator is a single instance across the whole process. The three concerns aren't independent — a fix at one layer is undermined by ignorance at another.
A workable direction:
core_affinity or hwloc to the cores of that node. Route incoming work to the runtime whose node owns the data. This gives you Tokio's ecosystem without pretending it's NUMA-aware.mimalloc and jemalloc both use per-thread arenas — combined with pinned threads, allocations end up node-local via the OS's first-touch policy. For explicit control, use libnuma bindings (numa-sys) with numa_alloc_onnode, or mmap + mbind(MPOL_BIND).perf stat -e node-loads,node-load-misses or Intel PCM will tell you whether remote accesses are actually dropping. Without measurement, this is all cargo-cult.Gotchas:
spawn_local pattern with LocalSet per node avoids cross-node migration.numactl --interleave=all) can accidentally improve average latency while destroying tail latency — decide which you're optimizing./proc/sys/kernel/numa_balancing) may migrate pages under you; for deterministic workloads, disable it.