How to Fix Nginx Out of Memory (OOM) on Ubuntu 22.04
The Root Cause
Ubuntu 22.04 actively employs systemd-oomd by default, which can be more aggressive in terminating processes consuming excessive memory compared to the traditional kernel OOM killer. This behavior, combined with Nginx’s default or misconfigured settings leading to high memory demands, frequently results in Nginx worker processes being targeted and killed due to out-of-memory conditions.
Quick Fix (CLI)
# 1. Identify current memory usage and top memory consumers to confirm OOM conditions
free -h
ps aux --sort -rss | head -n 10
# 2. Restart the Nginx service to release allocated memory and attempt a clean start
sudo systemctl restart nginx
# 3. Verify Nginx service status immediately after restart
sudo systemctl status nginx
Configuration Check
1. Nginx Configuration Adjustments
Edit the main Nginx configuration file, typically /etc/nginx/nginx.conf, or relevant virtual host configuration files in /etc/nginx/conf.d/.
# /etc/nginx/nginx.conf (or relevant included config files)
# Adjust the number of worker processes.
# 'auto' is often fine, but for memory-constrained systems, set a specific low number.
# Example: If you have 2 CPU cores and limited RAM, start with 2.
# worker_processes auto;
worker_processes 2; # Example: Reduce to match CPU cores or available RAM
events {
# Limit the number of connections per worker process to conserve memory.
# Each connection consumes memory for buffers.
worker_connections 512; # Reduce from default 1024 if memory is tight
}
http {
# Reduce buffer sizes for client request bodies and proxy operations.
# These values significantly impact memory usage per connection.
# Defaults are often 8k/16k; reducing them can save significant memory.
client_body_buffer_size 8k; # Reduce from default 16k if not handling large POSTs
proxy_buffer_size 4k; # Reduce from default 8k/16k for proxy operations
proxy_buffers 4 4k; # Number and size of buffers for proxy responses
fastcgi_buffer_size 4k; # If using FastCGI, reduce from default 8k/16k
fastcgi_buffers 4 4k; # Number and size of buffers for FastCGI responses
# Ensure client_max_body_size is not excessively large if you don't expect huge uploads.
# client_max_body_size 1m; # Example: Limit maximum body size
}
2. Systemd OOM Killer Integration
To make Nginx less susceptible to being killed by the kernel OOM killer (and by extension systemd-oomd which often respects OOMScoreAdjust), create a systemd override for the Nginx service.
# Create or edit an override file for the Nginx service
sudo systemctl edit nginx
Add the following lines to the editor that appears:
# /etc/systemd/system/nginx.service.d/override.conf
[Service]
# Adjust OOMScore to make Nginx less likely to be killed by the kernel OOM killer.
# A negative value makes it less likely to be chosen for termination.
OOMScoreAdjust=-500
Save and exit the editor. Then, reload systemd daemon and restart Nginx:
sudo systemctl daemon-reload
sudo systemctl restart nginx
Verification
# 1. Check Nginx service status to confirm it's running without immediate failures
sudo systemctl status nginx
# 2. Monitor Nginx error logs and systemd journal for any OOM-related messages or startup issues
sudo journalctl -u nginx --follow
sudo tail -f /var/log/nginx/error.log
# 3. Monitor system memory usage and Nginx process memory consumption under load
# Observe 'free' memory and Nginx process RSS (Resident Set Size) values
free -h
top # Or htop for a more interactive view
# 4. (Optional) Simulate typical or peak load using a tool like ApacheBench (ab)
# Replace 'http://your_domain.com/' with an actual URL Nginx serves
# sudo apt install apache2-utils # If 'ab' is not installed
# ab -n 10000 -c 100 http://your_domain.com/