20 MB per Apache process? Granted, everyone's implementation is different, but if I had to guess, the author is relying on the results of `top` to determine his Apache memory utilization. This is fundamentally flawed because top doesn't accurately report physical memory usage[1]. It is an estimate at best. What you really want to look at (on Linux) is private dirty RSS, which top doesn't report.

For environments using Passenger, there is a great tool available for analyzing this: passenger-memory-stats. By examining the source code of this tool[2], we can see that it is examining the contents of `/proc/#{pid}/smaps' where pid is a collection of Apache process IDs that is iterated through. Writing a bash/awk script to accomplish the same should be pretty straight forward. But back to the topic of reducing memory usage and pre-forking.

In our deployments, an Apache process uses 0.5 MB of physical memory, which puts the reduction of Apache processes in to perspective. At this level, your Apache server would have to be grossly misconfigured for this to have a significant impact. Also, the purpose of spare processes is to disguise the overhead required to create new processes. The only reason you'd use this functionality is when you have a load that varies. That is to say, you should set your MaxClients configuration so that you don't spawn processes that your VPS can't support.

Any benefit of reducing pre-fork processes is lost once load increases to the point that you need those processes to serve requests. This cannot save you from an under-provisioned VPS instance. A better solution is to cap the maximum number of worker processes to limit swap usage (called thrashing). You'll still encounter a performance ceiling if you've under provisioned your VPS.

The same applies for any service that uses pre-forking. There is no substitute for understanding your service load requirements. You have to answer two questions: How many req/sec are you serving, and how many req/sec can each process/thread serve (depending upon your service worker model). This is accomplished using benchmarking tools.

While you should definitely make sure you're running an appropriate number of workers, you'll get more benefits from reducing the amount of memory used for each process. When I started, our Apache processes were around 7 MB of private dirty RSS usage each. The processes were large because there were all kinds of Apache modules loaded that weren't in use. PHP, mod_perl, etc. Each of these contribute to the process bottom line memory usage.

Let's look at memory usage as s * n where 's' is the size of each process and 'n' is the number of processes. Our variable 's' is typically a small number (say, 0.5 to 10 MB), while 'n' is typically a whole order of magnitude (or two) greater. In our case, 'n' is 150. Reducing 's' from 7 MB to 0.5 MB saved me 975 MB of real memory! If I had ignored my process size and only reduced the number of workers by 20% (which would still degrade performance at peak loads), I would only save 210 MB. The hit in performance cannot be understated. Running out of Apache workers is NOT good for performance.

In summary, the article offers good advice only in the fact that you should know and understand what your service requirements are. I would disagree that you should review your process/thread usage, and call it a day. There are many other 'low hanging fruit' items to reach out and grab.

1 - http://www.google.com/search?q=linux+top+vs+private+dirty+rs...

2 - http://github.com/FooBarWidget/passenger/blob/master/bin/pas...