What is RLIMIT_RSS?
RLIMIT_RSS (Resident Set Size) was intended to limit the number of virtual memory pages currently held in physical memory. It is BSD-derived and absent from SUSv3. Linux provides the constant and accepts the system calls, but the limit currently has no effect on modern Linux kernels.
Why It Has No Effect
Linux’s virtual memory manager (VMM) uses a global LRU page reclaim system. The decision of which pages to evict from physical RAM is made globally across all processes based on usage patterns, not per-process quotas. Implementing per-process RSS limits in a way that cooperates correctly with the global VMM is complex and has never been done in mainline Linux.
The constant RLIMIT_RSS exists so that code written on BSD which uses it can be compiled on Linux without errors. setrlimit(RLIMIT_RSS, …) succeeds silently, getrlimit(RLIMIT_RSS, …) returns the stored value, but the kernel never actually uses it.
madvise(MADV_WILLNEED). If the operation could not be performed because the RSS limit would be exceeded, the error EIO was returned. This behaviour was removed in subsequent kernel versions.Alternatives to RLIMIT_RSS on Modern Linux
If you need to limit a process’s physical memory usage on modern Linux, use these mechanisms instead:
- Control Groups (cgroups) —
memory.limit_in_bytesin the memory cgroup subsystem enforces a hard limit on RSS + swap. This is the correct modern approach. - RLIMIT_AS — Limits virtual address space (a superset that includes RSS). Enforced, unlike RLIMIT_RSS.
Code Example — getrlimit/setrlimit with RLIMIT_RSS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/resource.h>
int main(void)
{
struct rlimit rl;
getrlimit(RLIMIT_RSS, &rl);
printf("RLIMIT_RSS before: soft=%lld hard=%lld\n",
(long long)rl.rlim_cur, (long long)rl.rlim_max);
/* Set an RSS limit — this will SUCCEED but have NO effect */
rl.rlim_cur = 32 * 1024 * 1024; /* 32 MB */
rl.rlim_max = 32 * 1024 * 1024;
if (setrlimit(RLIMIT_RSS, &rl) == 0)
printf("setrlimit(RLIMIT_RSS, 32MB) succeeded\n");
/* Allocate 64 MB — this will NOT be prevented by RLIMIT_RSS */
char *buf = malloc(64 * 1024 * 1024);
if (buf) {
memset(buf, 1, 64 * 1024 * 1024); /* Touch all pages */
printf("Allocated and touched 64 MB — RSS limit not enforced\n");
free(buf);
}
return 0;
}
/* Compile: gcc -o rss_demo rss_demo.c
Lesson: setrlimit(RLIMIT_RSS) returns success but the kernel ignores
the limit value. Use cgroups memory.limit_in_bytes for real enforcement. */
Interview Questions
No. On modern Linux kernels, RLIMIT_RSS is accepted by setrlimit() and stored, but the kernel never enforces it. The constant exists for source-level compatibility with BSD code. setrlimit(RLIMIT_RSS) returns 0 (success) but the limit is never checked.
Control Groups (cgroups) with the memory subsystem. The memory.limit_in_bytes file in a memory cgroup enforces a hard limit on a process group’s RSS plus swap usage. This is the production-grade mechanism used by containers (Docker, systemd, etc.).
