From time to time, the virtual server I rented acted up. When logging into the system, I would get error messages indicating the server wasn’t able to create any more processes: “cannot fork”. This was weird because
ps(1) showed only 20 processes, while the hard limit of the virtual machine host was apparently set to 94.
My server doesn’t do a lot: There’s just a couple of deamons, including an Apache instance that servers less than 1000 page impressions per day. Load is pretty much zero most of the time, there’s very little network I/O, and memory use is below limits, too.
After some head scratching, I realized what the problem was: The virtual machine host counts kernel level threads towards the process limit! It’s quite obvious when you think about it; a quick
"ps -efL" confirmed the suspicion.
The culprit was Apache with its threaded worker model (
apache2-mpm-worker). The default settings were unsuitable for my rather limited virtual machine, they caused Apache to spawn too many threads. Fortunately, after reading the documentation this was rather easy to fix. I edited the configuration (
/etc/apache2/apache2.conf on my system), adjusting the default settings:
<IfModule mpm_worker_module> StartServers 2 ServerLimit 4 MaxClients 64 ThreadsPerChild 16 MinSpareThreads 4 MaxSpareThreads 8 MaxRequestsPerChild 0 </IfModule>
After an Apache restart, my problems were gone.
This configuration limits the number of active worker threads to 64 (
MaxClients), which is well below the virtual machine’s threshold. Those 64 threads run in up to 4 child processes (
ServerLimit), with 2 processes created on startup (
StartServers). Each server process contains at most 16 threads (
ThreadsPerChild), with 4 threads created at minimum and at most 8 idle threads kept in the worker pool (
MaxSpareThreads respectively). There’s no limit on the number of requests a process may serve (
An alternative solution would be to switch to the prefork module. It works with processes rather than threads and is a lot easier to configure. Just install the
apache2-mpm-prefork and set its
Keep in mind that browsers typically open several connections to your host, so one client can easily hog half a dozen workers. For my site, that’s no problem, for others it may very well be.