Setting vm.overcommit_memory Correctly: Understanding Memory Overcommit
AI generated
$
/etc
Linux
vm.overcommit_memory
Setting memory overcommit correctly

The warning 'overcommit_memory is set to 0, background save may fail' at Redis startup is one of the most common kernel tuning hints in Magento hosting environments. Understanding the three overcommit modes and their relationship to the OOM killer leads to the right decision, instead of blindly following a copy-paste recommendation.

9 min read Linux Kernel Tuning Redis

1. What memory overcommit actually means

When a process requests memory via malloc, the kernel initially reserves only virtual address space, not necessarily physical memory. Only on an actual write access to a memory page does a page fault trigger the assignment of physical memory, a mechanism called lazy allocation, which forms the basis for memory overcommit.

Overcommit means the kernel can promise more virtual memory than is physically available together with configured swap, on the assumption that most processes never actually write their entire requested memory anyway. Many programs, including PHP-FPM and the JVM in some Elasticsearch setups, reserve generous virtual memory regions up front without ever using them in full.

2. The three overcommit modes in detail

The kernel parameter vm.overcommit_memory supports three values. Mode 0, the default, enables a heuristic check: the kernel allows most requests but rejects obviously nonsensical ones, such as a single allocation significantly larger than the available address space. This heuristic is not precisely documented and can shift slightly between kernel versions.

Mode 1 disables any check entirely and allows essentially unlimited overcommit. That is exactly what Redis needs for reliable background snapshots via fork(), since the child process initially references the same virtual address space as the parent when forking, without immediately requiring extra physical memory. Mode 2, on the other hand, strictly caps total commitment at swap plus a configurable share of physical RAM via vm.overcommit_ratio or vm.overcommit_kbytes, and rejects allocations beyond that limit with an error instead of letting them fail later.


# Show the current overcommit mode
cat /proc/sys/vm/overcommit_memory

# Set mode 1 (Redis recommendation) temporarily
sysctl -w vm.overcommit_memory=1

# For mode 2: allowed share of physical RAM in percent
cat /proc/sys/vm/overcommit_ratio

3. The relationship to the OOM killer

In modes 0 and 1, the kernel can promise significantly more memory than is physically available. If many processes simultaneously try to actually write the full amount of memory they were promised, the system reaches a state where neither physical memory nor swap suffices to serve all page faults. That is exactly when the OOM killer steps in and terminates a process to free memory.

Mode 2 shifts this risk: instead of an allocation appearing to succeed and the process being terminated later by the OOM killer, the allocation itself fails immediately with an error as soon as the configured upper limit would be exceeded. Applications that handle allocation failures cleanly benefit from that, though PHP-FPM and most database systems are not prepared for it in every code path and often react to a failed malloc call with a crash as well.

4. Understanding the Redis warning in detail

For persistent background snapshots, both RDB snapshots and AOF rewrites, Redis relies by default on fork() to create a child process that freezes the dataset at the moment of the fork and writes it out at leisure. The parent process keeps running unchanged in the meantime and serves new writes via copy on write, meaning memory pages are only duplicated once actually modified.

In mode 0, the kernel can reject that fork if it heuristically decides there is not enough memory to promise for the child process's full virtual address space, even though copy on write would in practice barely need any additional physical memory. Redis proactively reports this potential risk at startup, which is why the official Redis documentation explicitly recommends mode 1 for production systems.


# Typical Redis warning in the log
# WARNING overcommit_memory is set to 0! Background save may fail under low memory condition.

# Set mode 1 permanently
echo "vm.overcommit_memory = 1" >> /etc/sysctl.d/99-redis-overcommit.conf
sysctl --system

5. Recommendation for database and cache servers

For dedicated Redis hosts, whether used as session storage or cache backend for Magento, mode 1 is the clear, upstream recommended choice, since it reliably enables fork based persistence without kernel interference. The risk that overcommit is actually exploited and the OOM killer has to intervene can be reduced to an acceptable level through generously sized RAM and consistent memory monitoring.

For MySQL or MariaDB servers, which typically operate with a fixed configured innodb_buffer_pool_size and rarely fork, overcommit is less critical, and the heuristic default mode 0 is usually sufficient here. Elasticsearch servers with their JVM heap reservation also gain little from mode 1, since the JVM typically commits its heap fully at startup instead of allocating lazily.

On mixed hosts running both Redis and other memory intensive services, mode 1 should be set system wide once Redis is running, combined with strict memory monitoring via vm.min_free_kbytes and active OOM score tuning for less critical processes, so that the right processes get terminated first in a real emergency.

6. OOM score tuning as a complement to overcommit

Regardless of the chosen overcommit mode, it pays off to deliberately control the OOM priority of critical processes. Via /proc/<pid>/oom_score_adj a value between minus one thousand and one thousand can be set, where lower values protect a process from the OOM killer and higher values make it a preferred target.

For a Redis process serving as a central cache for several Magento instances, a negative oom_score_adj makes sense, so that in an emergency a less important background process gets terminated before the cache itself. This fine tuning does not replace adequately sized RAM, but it does reduce the risk of the OOM killer hitting the wrong process.


# Preferentially protect the Redis process from the OOM killer
REDIS_PID=$(pgrep -x redis-server | head -n1)
echo -500 > /proc/${REDIS_PID}/oom_score_adj

# Check the current effective OOM score
cat /proc/${REDIS_PID}/oom_score

7. Continuously monitoring the overcommit state

The current degree of overcommit can be read from /proc/meminfo: CommitLimit shows the theoretical upper limit for promised memory, Committed_AS the sum of already promised allocations across all processes. If Committed_AS clearly exceeds physically available memory, a closer look at actual memory usage is worthwhile before an OOM event occurs.

For ongoing monitoring, a simple cron based check that logs both values regularly and alerts on a critical ratio works well, combined with checking the system log for OOM killer events, which can be identified via dmesg or the kernel log.


# Show commit limit and currently promised memory
grep -E "CommitLimit|Committed_AS" /proc/meminfo

# Search the kernel log for past OOM killer events
dmesg -T | grep -i "out of memory"

8. Common pitfalls in overcommit tuning

A common mistake is blindly setting mode 1 on every server because a Redis warning suggests it, without considering that other services on the same host also become more heavily overcommitted as a result. On shared hosts running several memory intensive services, the decision should always be made host specifically, not adopted wholesale from a blog recommendation.

Another pitfall is setting the value only temporarily with sysctl -w and forgetting to persist it permanently in /etc/sysctl.d/. After the next reboot the value silently reverts to the default mode 0, and the Redis warning reappears at the next service restart, usually at the least convenient moment.

9. Checklist for production use

Before switching a server, it should first be checked which services actually run on the host and whether any of them actively fork, as Redis does. Only if a fork-heavy service is present does a blanket switch to mode 1 make sense, otherwise the heuristic default mode 0 usually remains the more conservative choice that works just as well.

After every change to vm.overcommit_memory, restarting the affected service belongs into the verification step, to confirm the original warning has actually disappeared. The setting should also be added to server documentation or configuration management, such as Ansible or a simple provisioning script, so it does not get forgotten again on a fresh install.

Finally, a regular look at Committed_AS relative to CommitLimit belongs into production monitoring regardless of the chosen mode, since a ratio persistently close to the limit is an early warning sign of future memory pressure, long before the OOM killer actually has to step in.


# Short check command for server documentation
echo "Overcommit mode: $(cat /proc/sys/vm/overcommit_memory)"
grep -E "CommitLimit|Committed_AS" /proc/meminfo
Mode Behavior Typical Use Risk
0 (heuristic) Heuristic check, rejects obviously nonsensical requests Default servers without fork-heavy workloads Redis fork can be rejected in edge cases
1 (always) No check, practically unlimited overcommit Redis/cache servers with fork based persistence OOM killer must intervene in an emergency
2 (never) Strict upper limit from swap plus a share of RAM Systems with predictable, fixed memory needs Allocations can fail hard
Combined with oom_score_adj Protect critical processes from the OOM killer specifically Mixed hosts running several services Requires manual maintenance per process

Mironsoft

Server administration, Docker hosts, and performance tuning

Linux servers nobody on the team really understands anymore?

We handle setup, hardening, and performance tuning of Linux servers and Docker hosts for Magento deployments, documented and traceable instead of grown and unclear.

Server Audit

Review the existing server configuration for security gaps and performance bottlenecks.

Docker Host Setup

Set up and secure production-ready Docker environments for Magento cleanly.

Monitoring & Tuning

Measure resource usage and tune systemd, kernel, and services with purpose.

10. Summary

vm.overcommit_memory

Audience

Admins of Redis/database servers hitting overcommit warnings

Kernel parameter

vm.overcommit_memory (0, 1, or 2)

Redis recommendation

Mode 1, persisted permanently via /etc/sysctl.d/

Biggest pitfall

Setting it only temporarily with sysctl -w instead of persisting it

11. FAQ: vm.overcommit_memory

1Why does Redis warn about overcommit_memory being 0?
Because in mode 0 the kernel can heuristically reject a fork() if it decides it cannot promise enough memory for the child process's full virtual address space, even though copy on write would barely need any extra physical memory. That threatens Redis's background persistence.
2Is mode 1 safe on every server?
Not automatically. Mode 1 increases the risk that several processes simultaneously write the full amount of memory they were promised, forcing the OOM killer to intervene. On dedicated Redis storage the risk is usually acceptable, on mixed hosts it should be evaluated per host.
3How do I set vm.overcommit_memory permanently?
Via a file in /etc/sysctl.d/, for example /etc/sysctl.d/99-redis-overcommit.conf containing vm.overcommit_memory = 1, followed by sysctl --system. A plain sysctl -w is lost after a reboot.
4What does CommitLimit in /proc/meminfo mean?
CommitLimit shows the theoretical upper limit for total promised virtual memory, based on physical RAM, swap, and the chosen overcommit mode. Committed_AS shows how much of that has already been promised to processes.
5When should I choose mode 2 instead of mode 1?
Mode 2 suits systems with predictable, fixed memory needs, where an immediate allocation failure is preferable to a later, uncontrolled OOM kill. For Redis with fork based persistence, mode 2 is unsuitable, since it can block the necessary fork.
6How does the OOM killer relate to overcommit?
In modes 0 and 1, the kernel can promise more memory than is physically available. If several processes simultaneously try to fully use their promised memory, physical memory plus swap eventually runs out, and the OOM killer terminates a process to free space again.
7Can I protect individual processes from the OOM killer?
Yes, via /proc/PID/oom_score_adj with a negative value such as minus 500. That lowers the priority of that process as an OOM killer target, but it does not replace adequately sized server RAM.
8Does overcommit_memory also affect MySQL or MariaDB?
Less strongly than Redis, since these databases usually operate with a fixed configured buffer pool and rarely fork. For them, the heuristic default mode 0 is sufficient in most cases.
9How do I find past OOM killer events in the log?
With dmesg -T followed by a filter for out of memory or killed process, past OOM killer actions, including timestamp and affected process, can be traced in the kernel log.
10Is setting overcommit_memory enough to avoid OOM kills entirely?
No. The overcommit mode only affects how generously the kernel makes memory promises, not the actually available physical memory. Adequate RAM sizing and monitoring remain essential, regardless of the chosen mode.