Skip to content
Menu
Poppy Ramblings Poppy Ramblings
  • About
Poppy Ramblings Poppy Ramblings

Apache performance tuning

Posted on 2025-09-192025-09-19 by herbcso

…or how not to set up your tiny server

In a surprise to absolutely noone, you need to adapt your Apache configs to your server setup – who knew!? ;]

In my case, I’m running this on a small Linode Nanode VPS with all of 1GB of RAM. In that 1GB I managed to fit:

  • This WordPress instance
  • Mariadb (for WordPress)
  • A separate personal website
  • 3 websites served from Docker containers with Apache handling the SSL termination
  • A wireguard server (also running in Docker)
  • A remote access server
  • A private syncthing relay node
  • A Watchtower instance to keep my containers up to date

Now, all of these are EXTREMELY low traffic – this is really all just for my personal use – but as you can see, you can fit a surprising amount of stuff into this one measly GB of RAM! ;]

However, I had one problem: the default Apache config allowed for WAY too many workers! The default setup uses mpm_prefork workers, which means Apache spins up one process per connection. Given my tiny websites and their minimal usage, this is totally fine in principle. However, occasionally I do get hit by script kiddies probing for vulnerabilities. In that scenario, a number of simultaneous connections are made as they probe for various vulnerabilities. That is fine in and of itself, however it does lead to OOM kills for mariadb… Wait, huh? Why?

The symptom

This is what I would see in my logs: mariadb gets OOM killed. “Weird!”, I thought, so I set up a general log for mariadb to see what kind of queries were running. However, that turned up nothing.

But then I started looking at my access logs and found that during the times I was getting OOM kills, there were a number of connection attempts to my various websites using non-existent PHP script paths and the like. So that’s when I got suspicious of the number of Apache workers running.

The fix

So it turns out that in the default Apache setup (that I had carried forward from the Debian 10 days), I had this in /etc/apache2/mods-enabled/mpm_prefork.conf:

StartServers            5
MinSpareServers         5
MaxSpareServers         10
MaxRequestWorkers       150
MaxConnectionsPerChild  0

This config would start up to 150 Apache worker processes if there were lots of simultaneous connections. At 50-100MB RAM usage each, you can see how that would quickly overwhelm my poor little Nanode! And then for some reason the kernel always chose to kill mariadb (probably because it uses a little more RAM than the individual Apache workers), so I was left with this red herring of “hey, mariadb is using all this memory, why!?” when in fact it was the fault of all these Apache workers!

To make matters worse, when this would happen I would of course not be able to log into the server via SSH anymore, since it was spending all its time trying to swap and run all these Apache workers. So I could never quite figure out what was actually going on.

Luckily this happened again this morning and I was able to jump on this time and see all the extra workers. That finally made me twig on to what was actually happening! So, I changed the config to this:

StartServers            2
MinSpareServers         2
MaxSpareServers         5
MaxRequestWorkers       10
MaxConnectionsPerChild  0

Now, this is obviously a VERY limited config, but given my teensy little VPS and my modest needs, it actually works just fine for me. Now I can hammer my node with all kinds of requests, and while a lot of them simply time out, and it becomes very slow to respond, it also no longer hits OOM kills, and recovers immediately after the onslaught is over. That’s really all I need!

Conclusion

So there we have it – a much more sane Apache config for this tiny little instance with very modest needs. Is it “web-scale”? Heck no! Do I need that? Heck no! ;] At least now I will stop getting intermittent alerts from my monitors saying that my website is down… well, at least until the next thing goes wrong. ;]

PS: this is literally the FIRST thing that they talk about in the Apache Performance Tuning docs… Guess I shoulda read that one… ;]

PPS: Yeah, this is old news, but it’s new to me. Sue me! ;]

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Recent Posts

  • Apache performance tuning
  • Shoutout for a nifty blog
  • Quick screenshots in Python
  • Getting IP address on very limited Docker containers
  • CIFS mount input/output error -5 with reading SOME directories

Recent Comments

  • herbcso on Debugging bash functions
  • herbcso on Everything you (n?)ever wanted to know about Unicode
  • herbcso on SpongeBob SquarePants in Buckaroo Banzai!?
  • mcshankins on SpongeBob SquarePants in Buckaroo Banzai!?
  • herbcso on PHP ZendDebugger and WAMP

Tags

ag AJAX bash blog cifs command-line cool debugging disk diun download firefox fix frameworks gdb homeassistant javascript packaging php plex portainer proxmox python ruby running samba search shoes silliness space SquarePants tcx therubyracer tips tricks tv unicode unix useful v8 WAMP weird windows xdebug zend

Archives

  • September 2025
  • September 2024
  • January 2024
  • August 2023
  • September 2022
  • June 2022
  • March 2022
  • January 2022
  • May 2019
  • March 2019
  • April 2014
  • February 2014
  • October 2013
  • June 2013
  • April 2013
  • December 2012
  • November 2012
  • June 2012
  • April 2012
  • September 2011
  • October 2010
  • September 2010
  • August 2010
  • June 2010
  • May 2010
  • April 2010
  • October 2009
  • August 2008
  • June 2008
  • April 2008

Categories

  • android
  • browsers
  • coding
  • homelab
  • random nifty stuff
  • silly
  • site updates
  • Uncategorized

Meta

  • Log in
  • Entries feed
  • Comments feed
  • WordPress.org
©2025 Poppy Ramblings | Powered by Superb Themes