IN AFRICA

ALBANIA

ARGENTINA

AUSTRALIA

AUSTRIA

AZERBAIJAN

B AND H

BANGLADESH

BELGIUM

BRAZIL

BULGARIA

CANADA

CHILE

CHINA

COLOMBIA

COSTA RICA

CROATIA

CYPRUS

CZECH

DENMARK

ECUADOR

EGYPT

EL SALVADOR

ESTONIA

FINLAND

FOR BACKUP AND STORAGE

FOR DATABASE

FOR EMAIL

FOR MEDIA STREAMING

FRANCE

GEORGIA

GERMANY

GREECE

GUATEMALA

HUNGARY

ICELAND

IN ASIA

IN AUSTRALIA

IN EUROPE

IN NORTH AMERICA

IN SOUTH AMERICA

INDIA

INDONESIA

IRELAND

ISRAEL

ITALY

JAPAN

KAZAKHSTAN

KENYA

KOSOVO

LATVIA

LIBYA

LITHUANIA

LUXEMBOURG

MALAYSIA

MALTA

MEXICO

MOLDOVA

MONTENEGRO

MOROCCO

NETHERLANDS

NEW ZEALAND

NIGERIA

NORWAY

PAKISTAN

PANAMA

PARAGUAY

PERU

PHILIPPINES

POLAND

PORTUGAL

QATAR

ROMANIA

RUSSIA

SAUDI ARABIA

SERBIA

SINGAPORE

SLOVAKIA

SLOVENIA

SOUTH AFRICA

SOUTH KOREA

SPAIN

SWEDEN

SWITZERLAND

TAIWAN

THAILAND

TUNISIA

TURKEY

UK

UKRAINE

UNITED ARAB EMIRATES

URUGUAY

USA

UZBEKISTAN

VIETNAM

The NUMA Bottleneck: Pinning Processes for Maximum RAM Speed on Bare Metal

Are your high-core servers underperforming? Discover how the physical layout of modern CPUs causes silent memory latency, and learn how to use numactl to bind your enterprise applications directly to local memory banks for maximum bare-metal throughput.

Optimize AMD & Intel Servers: Fix NUMA Latency with numactl

When enterprises provision high-end dedicated servers featuring modern AMD EPYC or dual-socket Intel Xeon processors, they expect uncompromising performance. However, out of the box, standard Linux distributions can silently strangle the performance of databases, hypervisors, and AI workloads due to a hardware concept known as NUMA (Non-Uniform Memory Access).

Modern high-core servers do not treat all RAM equally. They divide their CPU cores and physical memory into separate zones called NUMA nodes. If an application (like Redis, PostgreSQL, or a virtual machine) is running on a CPU core in Node 0, but the Linux kernel allocates its memory from the RAM sticks physically attached to Node 1, the data must travel across a physical bridge on the motherboard (like Intel's UPI or AMD's Infinity Fabric).

This cross-node traffic introduces massive microsecond latency, silently crippling throughput. The solution is straightforward but often overlooked: explicitly pinning high-performance applications to specific CPU cores and their local memory banks using numactl and hwloc. In this tutorial, we will show you how to map your hardware and enforce strict NUMA policies for maximum speed.

What You'll Learn

Understanding the NUMA Node Bottleneck

In older SMP (Symmetric Multiprocessing) architectures, all CPUs accessed a single, shared pool of memory at the same speed. As core counts exploded, this shared bus became a massive traffic jam. Hardware manufacturers solved this with NUMA.

In a NUMA architecture, a processor and the memory slots closest to it form a "Node".

  • Local Memory Access: When a CPU reads memory from its own node, it is extremely fast and high-bandwidth.

  • Remote Memory Access: When a CPU needs to read memory from another node, the request must traverse the QPI/UPI (Intel) or Infinity Fabric (AMD) interconnect. This adds latency and reduces bandwidth.

By default, the Linux CPU scheduler moves processes around to balance the load. A Redis thread might start on Node 0, allocate 10GB of RAM on Node 0, and then get moved by the kernel to Node 1. Suddenly, every RAM access by Redis becomes a "remote" access. By pinning the process, we eliminate this scheduler jitter and guarantee 100% localized memory access.

Step 1: Installing hwloc and numactl

To fix the bottleneck, we need the right tools. We will use hwloc to visually and structurally map our hardware, and numactl to enforce the binding.

Install on Ubuntu/Debian

Log into your server via SSH and execute the following:

bash

sudo apt update
sudo apt install numactl hwloc hwloc-nox -y
                                

Install on CentOS/RHEL/AlmaLinux

bash

sudo dnf install numactl hwloc -y
                                

Step 2: Analyzing Your Server's NUMA Topology

Before we pin a process, we must understand the physical layout of the server. Let's inspect the hardware.

View Hardware Layout with lstopo

The lstopo command (part of the hwloc package) provides an excellent text-based or graphical representation of your system's architecture.

bash

lstopo-no-graphics
                                

The output will display your NUMA nodes, L3 caches, and the specific CPU core numbers attached to each node. Pay close attention to which PCI devices (like your NVMe drives or 10Gbps NICs) are physically wired to which NUMA node.

Map Memory and Cores with numactl

To get a clear matrix of memory and distances, use numactl:

bash

numactl --hardware
                                

You will see output similar to this:

plaintext

available: 2 nodes (0-1)
node 0 cpus: 0 1 2 3 4 5 6 7
node 0 size: 64123 MB
node 0 free: 32000 MB
node 1 cpus: 8 9 10 11 12 13 14 15
node 1 size: 64511 MB
node 1 free: 41000 MB
node distances:
node   0   1
  0:  10  21
  1:  21  10
                                

Notice the "node distances" matrix. A distance of 10 represents local memory access. A distance of 21 represents the penalty of accessing memory on the remote node.

Step 3: Pinning Processes to Specific NUMA Nodes

Now that we know which cores belong to which node, we can bind an application. The numactl command acts as a wrapper around the application you want to run.

Basic CPU and Memory Binding

To force an application to run exclusively on the CPU cores of Node 0, and only allocate RAM from Node 0, use the following syntax:

bash

numactl --cpunodebind=0 --membind=0 my_application --start
                                

Key Flags:

  • --cpunodebind=0: Restricts the process to only execute on the logical CPU cores attached to Node 0.

  • --membind=0: Forces the kernel to strictly allocate memory from Node 0. If Node 0 runs out of RAM, the application will throw an Out of Memory (OOM) error rather than using slower remote memory. (If you prefer to allow fallback to Node 1 rather than crashing, use --preferred=0 instead of membind).

Pinning to Specific Cores

If you want even finer control, you can pin a process to exact CPU core numbers (e.g., cores 2, 3, and 4) using the --physcpubind flag:

bash

numactl --physcpubind=2,3,4 --membind=0 redis-server /etc/redis/redis.conf
                                

Step 4: Automating NUMA Policies with Systemd

Running commands manually is great for testing, but in a production environment, services are managed by systemd. You must modify the service files to ensure your databases or web servers are pinned automatically on startup.

Modifying a Systemd Service File

Let's say we want to optimize a high-traffic Redis instance. Edit the Redis service override file:

bash

sudo systemctl edit redis-server.service
                                

This will open a blank override file. Add the following lines to clear the default ExecStart command and replace it with a numactl wrapped version:

ini

[Service]
ExecStart=
ExecStart=/usr/bin/numactl --cpunodebind=0 --preferred=0 /usr/bin/redis-server /etc/redis/redis.conf
                                

Save the file, reload the systemd daemon, and restart the service:

bash

sudo systemctl daemon-reload
sudo systemctl restart redis-server
                                

Verify that the process is correctly pinned by checking its NUMA map:

bash

numastat -p $(pidof redis-server)
                                

You should see memory allocations heavily concentrated in the specific node you requested.

Conclusion

By taking manual control over your CPU cache and memory allocations with numactl, you stop the Linux kernel from making inefficient scheduling guesses. Pinning your heavy workloads to specific NUMA nodes ensures that memory access remains local, latency remains low, and your bare-metal hardware performs exactly the way enterprise infrastructure should.

Discover iDatam Dedicated Server Locations

iDatam servers are available around the world, providing diverse options for hosting websites. Each region offers unique advantages, making it easier to choose a location that best suits your specific hosting needs.

Up