This post is about the memory consumption of Apache’s HTTP Server (v2.2) using the prefork MPM configuration.
Apache does not use as much memory as many people think; I’ve seen a good number of blog posts, questions on Stackoverflow and Serverfault, and forum entries by people switching to Nginx or Lighttpd because they think “Apache uses 200-250mb per child process”. Apache uses nowhere near that kind of memory per-process.
Why do people think Apache uses 200-250mb per process?
If you run either of the top or ps commands on a Linux server then it looks like Apache is using 200-250mb per child process; but it’s not. Here’s an example ps output where Apache is only running one prefork MPM child (as specified in httpd.conf):
The process owned by root is the parent process and the one owned by apache is the child process that is waiting to process an HTTP request; it looks like they are both using 204mb (208916 / 1024) of memory, they aren’t.
The ps command lies to you and so does top. They lie because Linux uses shared libraries. Each of those processes above would consume 204mb if they were the only process running on the system but because they are other processes the 204mb is not representative of how much memory they are really using. All processes on a Linux system will re-use shared-libraries and in most cases the shared libraries make up the bulk of the memory footprint that ps shows you; ps says, “This is all the memory that this process is using” but it doesn’t add, “But this amount of that memory is shared by other processes too”.
So how much does Apache actually use?
Instead of using ps or top we are going to use the free command to show us the total amount of free and used memory for the whole system. To test Apache’s memory use I have configured it to run one child process, checked free, re-configured it to use 2 child processes, restarted and checked free, and so on; the test is only on memory use at startup, the server doesn’t process any webpages:
# child processes memory usage (MB) 1 4.8 2 5.2 3 5.85 10 9.66 20 16 50 35.1
Looks a lot better than 200-250mb per process! Even running 50 child processes only consumes 45mb at startup. Linux’s memory allocation system is complex and I don’t pretend to understand it but one thing is for sure: don’t believe ps and top, they are liars.