How to Lock Memory Pages in Linux using the mlock System Call

The Risk of Memory Swapping

In a Linux environment, when the system runs low on physical RAM, the kernel aggressively moves inactive memory pages from the RAM to the hard drive (Swap space). This is a critical mechanism to prevent the system from crashing. However, for certain high-security or high-performance applications, swapping is unacceptable.

Consider a cryptographic daemon managing thousands of SSL certificates, or a highly secure password vault holding private keys in memory. If those sensitive keys are suddenly pushed from RAM to a standard Swap file on the hard drive, they are written to a permanent disk. If an attacker gains access to the physical hard drive, they can easily extract those plaintext keys from the Swap space.

Alternatively, consider a high-frequency trading database where a latency spike of 100 milliseconds is catastrophic. If the database engine is swapped to the disk, the application will stall. To guarantee that specific memory pages remain strictly in physical RAM and are never written to the disk, developers and system administrators use the mlock (Memory Lock) system call.

Understanding the mlock System Call

mlock is a low-level C system call. It instructs the Linux kernel to pin a specific range of virtual memory pages into physical RAM. Once locked, the kernel’s memory management subsystem is mathematically prohibited from paging that data out to Swap, regardless of how severe the memory pressure becomes.

The basic syntax in a C program looks like this:

#include <sys/mman.h>

int mlock(const void *addr, size_t len);

The application passes the starting memory address (addr) and the length of the buffer (len) it wishes to secure.

System Limits and Privileges

Because locking memory removes it from the pool available to the rest of the system, a rogue application could easily lock 100% of the RAM and instantly crash the server. Therefore, the Linux kernel tightly restricts who can use the mlock call.

By default, standard users can only lock a very small amount of memory (typically 64 Kilobytes). You can check the current limit using the ulimit command:

ulimit -l

If you are deploying a massive in-memory database like Redis or Memcached that requires gigabytes of locked memory, you must increase this limit. You do this by editing the security limits configuration file.

Open /etc/security/limits.conf as root and add the following lines:

redis soft memlock unlimited
redis hard memlock unlimited

This explicitly grants the redis user the authority to lock an unlimited amount of RAM.

Locking All Current and Future Memory

For applications where you want to ensure the entire process space (code, data, stack) is locked without having to specify specific memory addresses, Linux provides the mlockall variant.

int mlockall(int flags);

The application can pass two specific flags:

  • MCL_CURRENT: Instantly locks all pages currently mapped into the address space of the process.
  • MCL_FUTURE: A powerful directive that guarantees any memory the application allocates in the future will also be automatically locked into RAM upon creation.

When the application terminates naturally, or if it explicitly calls munlock, the kernel safely unpins the memory, returning it to the general pool where it can be swapped once again.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.