Skip to content

How do I tune the Apache web server's memory allocation to prevent out of memory errors in my EC2 Linux instance?

5 minute read
0

My Apache web server that runs on an Amazon Elastic Compute Cloud (Amazon EC2) Linux instance is intermittently unresponsive. I receive "out of memory", "oom", "oom-killer," "failure to fork process," or other insufficient memory messages in the instance's system log.

Short description

By default, Apache accepts 256 connections at the same time. Use the Apache configuration's ServerLimit to configure the quota.

Small instance types, such as t2.small, have only 2 gigabytes (GB) of memory and can't manage 256 simultaneous Apache connections. As a result, you might receive one of the following errors when the server gets heavy traffic:

  • "Out of memory"
  • "Oom"
  • "Oom-killer"
  • "Failure to fork process"
  • A note about insufficient memory in the system logs

To analyze your instance system logs, check the following log files based on your operating system (OS) distribution:

  • For Debian and Ubuntu, check /var/log/syslog.
  • For Amazon Linux, CentOS, and Red Hat Enterprise Linux (RHEL), check /var/log/messages.

Resolution

To avoid memory errors with your instance, set a quota on the number of simultaneous Apache and httpd connections that the server accepts. Use the MaxRequestWorkers (Apache 2.4) parameter in the Apache configuration to set the quota. For non-threaded Prefork servers, MaxRequestWorkers represents the maximum number of child processes that Apache launches to server requests.

The following resolution is for the default Prefork Apache multi-processing module (MPM) model that web servers use. To confirm your MPM, run the following command:

# apachectl -V | grep "MPM"

To calculate the approximate value to set for MaxRequestWorkers, determine how much your workload uses the following settings:

  • Your server's physical RAM
  • The memory that remains after other services use memory
  • Your Apache process that uses the most memory

Note: It's a best practice to use a range of 90-100% of REMAINING RAM for MaxRequestWorkers to balance server performance and stability. However, your workload might have different needs.

Calculate your server's physical RAM

To calculate RAM, run the following command:

# free -m | grep Mem: | awk '{print $2}'

Calculate the memory that remains after other services use memory

First, calculate the memory usage from all major services that aren't Apache. Run the following command for each service:

# usage_mbytes=0; for usage_by_pids in `ps -C $proc_cmd -o rss | grep -v RSS`; do usage_mbytes=$(($usage_mbytes + $usage_by_pids)); done; echo $(($usage_mbytes/1024)) MB;

Note: In the preceding command, replace $proc_cmd with the service name or command. For example, use mysqld to calculate the memory usage from the mysqld service.

After you calculate each service's memory usage, add the values together to get the sum total of memory usage by all other major services.

Then, use the following formula to subtract the memory usage by all other major services from your server's physical RAM in megabytes (MB):

Remaining memory = (Your server's physical RAM) - (Memory usage by all other major services)

Identify the Apache process that uses the most memory

To identify the process that uses the most memory, run the following command:

# sudo bash -c 'high_mem=0; for pid in $(ps aux | grep -E "httpd|apache2" | grep -v ^root | awk "{print \$2}"); do memory=$(pmap -d $pid | grep "writeable/private" | awk "{print \$4}" | sed "s/[^0-9]//g"); if [[ $memory -gt $high_mem ]]; then high_mem=$memory; fi; done; echo $((high_mem/1024)) MB'

Note how much memory the process uses.

Calculate MaxRequestWorkers

Use the following formula to calculate MaxRequestWorkers:

MaxRequestWorkers = (Remaining Memory * 90/100)/(Memory consumed by largest Apache process)

Note: Replace Remaining Memory with the memory that remains after other services use memory and Memory consumed by largest Apache process with the memory that the largest process uses.

The preceding calculation is the same for Ubuntu, Debian, and RHEL based systems. However, the Apache configuration path and file names depend on the OS type. Set MaxRequestWorkers based on your OS.

Note: The following examples use an Apache version 2.4 or later.

Debian and Ubuntu

Complete the following steps:

  1. Connect to your Linux instance.

  2. To open the /etc/apache2/mods-available/mpm_prefork.conf file in editor mode, run the following command:

    # vi /etc/apache2/mods-available/mpm_prefork.conf
  3. Change the MaxRequestWorkers parameter to the value that you calculated.
    Example:

    <IfModule mpm_prefork_module>      StartServers            5  
        MinSpareServers         5  
        MaxSpareServers        10  
        MaxRequestWorkers    your_value  
        MaxConnectionsPerChild  0  
    </IfModule>

    Note: Replace your_value with the calculated MaxRequestWorkers value. Also, configure the other parameters to align to your requirements.

  4. Save the file, and then exit the file.

  5. Run the following command to perform an Apache syntax check:

    # apachectl configtest
  6. If you receive an output of Syntax OK, then run the following command to restart Apache:

    # systemctl restart apache2

Amazon Linux, CentOS, and RHEL

Complete the following steps:

  1. Use SSH to log in to the server.

  2. Create a file with the /etc/httpd/conf.d/mpm_prefork.conf path, and then add the following command block:

    <IfModule mpm_prefork_module>      StartServers            5  
        MinSpareServers         5  
        MaxSpareServers        10  
        MaxRequestWorkers    your_value 
        MaxConnectionsPerChild  0  
    </IfModule>

    Note: Replace your_value with the calculated MaxRequestWorkers value. Also, configure the other parameters to align to your requirements.

  3. Save the file, and then exit the file.

  4. Run the following command to check Apache's configuration syntax:

    # httpd -t
  5. If you receive an output of Syntax OK, then run the following command to restart Apache:

    # systemctl restart httpd

Related information

Tutorial: Install a LAMP server on Amazon Linux 2

Tutorial: Install a LAMP server on Amazon Linux 2023

AWS OFFICIALUpdated a year ago
5 Comments

The above commands for ubuntu/debian returns following output in ubuntu 22.04

-bash: -1: substring expression < 0

All of the listed commands related to ubuntu with loops does not work. Please correct this.

replied 3 years ago

Thank you for your comment. We'll review and update the Knowledge Center article as needed.

AWS
MODERATOR
replied 3 years ago

I have the same issue (substring expression < 0), the commands above do not let me calculate my memory usage on an ubuntu instance which is in production and regularly failing because of this issue. I have had to guess at a value for now which is not ideal.

replied 2 years ago

Thank you for your comment. We'll review and update the Knowledge Center article as needed.

AWS
EXPERT
replied 2 years ago

After some research, I found that the Ubuntu issue mentioned above is because the command under the heading "Calculate the Apache process that uses the most memory" needs to be run as root under Ubuntu as the "pmap -d" command doesn't output the needed info if run as a regular user.

replied 2 years ago