Check Apache Httpd MPM Config Limits

A little while ago I had to reboot a client’s VM because the web server forked too many processes. They were making use of PHP, but the web server had not been configured for the resulting larger process size. I searched for a tool that would analyze the size of running httpd processes, and project the impact of starting the maximum number of processes allowed by MaxClients or ServerLimit, but didn’t find anything, so ended-up writing my own.

The following check_httpd_limits.pl script compares the size of running Apache httpd processes, the configured prefork/worker/event MPM limits, and the server’s available memory. The script exits with a warning or error message if the configured limits exceed the server’s available memory.

check_httpd_limits.pl does not use any 3rd-party perl modules, unless the --save/days/max command-line options are used, in which case you will need to have the DBD::SQLite module installed. It should work on any UNIX server that provides /proc/meminfo, /proc/*/exe, /proc/*/stat, and /proc/*/statm files. You will probably have to run the script as root for it to read the /proc/*/exe symbolic links.

Process Description

When executed, the script will follow this general process.

  • Read the /proc/meminfo file for server memory values (total memory, free memory, etc.).
  • Read the /proc/*/exe symbolic links to find the matching httpd binaries. By default, the script will use the first httpd binary found in the @httpd_paths array. You can specify an alternate binary path using the --exe=/path command-line option.
  • Read the /proc/*/stat files for pid, process name, ppid, and rss values.
  • Read the /proc/*/statm files for the shared memory size.
  • Execute the httpd binary with “-V” to get the config file path and MPM info.
  • Read the httpd configuration file to get MPM (prefork or worker) settings.
  • Calculate the average and total HTTP process sizes, taking into account the shared memory used.
  • Calculates possible changes to MPM settings based on available memory and process sizes.
  • Display all the values found and settings calculated if the --verbose command-line option is used.
  • Exit with OK (0), WARNING (1), or ERROR (2) based on the projected memory used by all httpd processes running.
    • OK: The maximum number of httpd processes fit within the available RAM.
    • WARNING: The maximum number of httpd processes exceed the available RAM, but still fits within the free swap.
    • ERROR: The maximum number of httpd processes exceed the available RAM and swap space.

Command-Line Options

A few command-line options can modify the behavior of the script.

  • --help Display a summary of command-line options.
  • --debug Show debugging messages as the script is executing.
  • --verbose Display a detailed report of all values found and calculated.
  • --exe=/path The complete path to an httpd binary file. By default the script will look in the following locations, and use the first executable found: /usr/sbin/httpd, /usr/local/sbin/httpd, /usr/sbin/apache2, /usr/local/sbin/apache2.
  • --swappct=# The percent of free swap that is allowed to be used before exiting with a WARNING condition. The default is 0% — if the projected size of all httpd processes allowed exceeds the available RAM, the script will exit with a WARNING message.

The DBD::SQLite perl module must be installed if any of the following command-line options are used. By default, the script will analyze and report on the current httpd process sizes. Since httpd processes may grow over time, these options allow you to save historical information to a database file, and use it to predict memory use based on the process sizes over a number of days.

  • --save Save the current process average sizes to an SQLite database file (/var/tmp/check_httpd_limits.sqlite).
  • --days=# Remove all database entries that are older than # days. The default is 30 days and using --days=0 will remove all entries from the database.
  • --max=realavg Use the largest HttpdRealAvg size value from the database, or calculated from the current httpd processes.
  • --max=running Use the HttpdRealAvg size value associated with the maximum number of running httpd processes saved in the database.

All three command-line options must be used to report on historical data. By itself, the --save option only saves current process information, the --days=# option will only remove old database entries, and --max will only use HttpdRealAvg from the database to predict memory usage.

Use --max=running if the size and number of httpd processes on the web server increase and decrease rapidly or unpredictably. The --max=realavg setting should be more accurate for web servers that have stable httpd sizes, and progressive increase / decrease in the number of httpd processes.

The check_httpd_limits.pl Script

Download the check_httpd_limits.pl script here or
visit the check-httpd-limits project on Google Code.

Examples

Here are a few examples of check_httpd_limits.pl’s usage and screen output.

An example of a prefork MPM with a MaxClients / ServerLimit that exceeds the available RAM, but still fits within the free swap space. The first execution generates a WARNING message, and the second uses the --swappct command-line option to allow up to 20% use of the free swap space before exiting with a WARNING.

An example of a prefork MPM with a MaxClients / ServerLimit that exceeds the available RAM and swap space. The --save/days/max command-line options are used to predict memory use based on the maximum process size averages, instead of just the current process list.

check_httpd_limits.pl can also be executed with --verbose to get detailed information on the httpd processes, configuration values, and the server’s memory. The MaxClients / ServerLimit in this example is low enough to fit within available RAM.

17 thoughts on “Check Apache Httpd MPM Config Limits

  1. I have the same problem as Sam (comment 5) but the fix doesn’t work for me…
    I’m root, using Ubuntu & Apache 2.2.22

    root@www:/home/ubuntu# ./check_httpd_limits.pl
    ERROR: No /usr/sbin/apache2 processes found in /proc/*/exe! Are you root?

    root@www:/home/ubuntu# ps -ef | grep apache
    root 13974 1 0 09:08 ? 00:00:09 /usr/sbin/apache2 -k start
    www-data 13978 13974 0 09:08 ? 00:00:00 /usr/sbin/apache2 -k start
    www-data 18502 13974 0 10:39 ? 00:00:09 /usr/sbin/apache2 -k start
    www-data 19212 13974 0 10:46 ? 00:00:08 /usr/sbin/apache2 -k start
    www-data 19288 13974 0 10:47 ? 00:00:05 /usr/sbin/apache2 -k start
    … (goes on.. 80-100 apache2 processes running)

    root@www:/home/ubuntu# ./check_httpd_limits.pl –exe=/usr/sbin/apache2
    ERROR: No /usr/sbin/apache2 processes found in /proc/*/exe! Are you root?

    I’m fairly certain I need to reduce MaxClients – but not so sure what to reduce it to. Would love to use your script to figure that out
    Many thanks
    Andy

    • This command should show you the correct exe path to use:

      js.

      • Thanks.

        Interestingly (at least to me) the “find” command didn’t work executed with sudo, but once I “sudo su -” and then run it it works a gem.

        My exe was /usr/lib/apache2/mpm-prefork/apache2

        ./check_httpd_limits.pl -exe=/usr/lib/apache2/mpm-prefork/apache2
        OK: AllProcsTotalMem (1240.33 MB) fits within MemTotal (1652.89 MB).

        Perfect .. thanks
        Andy

  2. Great work, has helped me to tune my Apache daemon to serve over 1400 requests/minute at 1GB RAM. Thanks for the time and efforts.

  3. This is very cool. Hoping it’ll help me get my server running a bit more smoothly. One question, though: after making the changes recommended and running it again, I got different, significantly lower recommended MaxClients number – any idea why?

    • The script bases its calculations on the running processes (or the information it saves over time). Depending on when you started Apache, how many requests each process is allowed to service before it gets re-spawned (if ever), if your using PHP / APC, etc., and what your traffic is like, the calculated maximum values for the configuration file will change slightly.

      BTW, if you’re using PHP, you might want to have a look at APC. I’ve found that it actually saved me memory and allowed me to run more Apache processes. ;-) See http://surniaulula.com/2012/11/22/save-memory-with-alternative-php-cache-apc/ for more info.

      js.

  4. I found this script to pretty neat. A couple of issues though.

    1. The “plain text” view of the code inserts your CDN address into three lines, beginning on line 402. That threw me for a loop.

    2. We do not use the default httpd.conf file, and unfortunately this script relies on this. I added the ability to specify the config file at the command line. I am sure I am not the only person that may find this useful. Here are my additions:

  5. # ./check_httpd_limits.pl
    ERROR: No /usr/sbin/apache2 processes found in /proc/*/exe! Are you root?

    # ps -ef | grep apache
    www-data 1034 10974 0 10:50 ? 00:00:00 /usr/sbin/apache


    ..

    /proc/10974# ls | grep exe
    exe

    • Sam,

      The script must have found a /usr/sbin/apache2 executable on disk, and is looking for it in /proc/*/exe. Since you’re using /usr/sbin/apache and not /usr/sbin/apache2, you’ll have to use the --exe=/usr/sbin/apache parameter to tell the script specifically which binary you’re using.

      Let me know if that helps.

      Thanks,

      js.

      • Every time I run the script , I get different ” numbers to modify in the areas of
        serverlimit and maxclients ( apache 2.2 )

        Is that normal , due to load variations?

        Thanks

        Dave M

        • Yup, completely normal – depends on how long Apache has been started, if/when processes respawn, etc. It’s rather approximate. The result basically says “if the traffic increases in the same way as things are now, here’s what the limits should be”. ;-)

          There’s a history feature that’s useful too. It saves stats and recommends limits based on the largest values it calculated in the past.

          js.

Comments are closed.