Strip Down Apache to Improve Performance & Memory Efficiency

Can you believe that it’s been more than a decade since the release of Apache 2.4?! If you haven’t replaced Apache with Nginx, then here’s a quick guide for boosting Apache’s performance using a method that’s often overlooked.

Now, before we get into that, please note that I’m not claiming that Apache is faster than Nginx. However, I’m also not claiming it’s slower. For the most part, out-of-the-box Apache will be slower than Nginx. However, when configured correctly, Apache can be just-as-fast as Nginx!

There are tons of articles on the web about Apache’s performance, mostly with unfair comparisons touting how Nginx is much faster than Apache. Yet, the fact is that Apache is a tried and true web server that has played and still plays, a large role in what has become the internet of web servers. With about 30% of all web servers still running Apache.

Apache 2.4 vs Nginx benchmarks
Using Apache 2.4 in “threaded” mode vs. Nginx – (Source)

Nginx is more of a lightweight static HTTP server. Apache comes with tons of features and modules. Most times you only need a few of these. While Nginx offers a more bare-bones approach. Thus, if you consider how heavy default Apache is, it actually performs a lot better than given credit for.

 

Stripping Apache 2.4 (httpd) of unused modules

That’s where you have to ask yourself, how many of Apache’s modules am actually using? 50%, 60% maybe 70%? Yes, one important approach to improving Apache performance – often overlooked – is stripping it down to only the modules/features which you require. This increases throughput while reducing memory and CPU consumption.

Ok so lets take a look at what modules your Apache install loads by default on most systems. You can view a list of enabled modules by typing the following from shell:

For CentOS/Fedora/RHEL (httpd):

httpd -M

For Ubuntu/Debian (apache2):

apache2 -M

 

List of Apache Modules Loaded by Default on CentOS

In red are those modules that can safely be removed in most environments:

core_module (static)
mpm_prefork_module (static)
http_module (static)
so_module (static)
auth_basic_module (shared)
auth_digest_module (shared)
authn_file_module (shared)
authn_alias_module (shared)
authn_anon_module (shared)
authn_dbm_module (shared)
authn_default_module (shared)
authz_host_module (shared)
authz_user_module (shared)
authz_owner_module (shared)
authz_groupfile_module (shared)
authz_dbm_module (shared)
authz_default_module (shared)
ldap_module (shared)
authnz_ldap_module (shared)
include_module (shared)
log_config_module (shared)
logio_module (shared)
env_module (shared)
ext_filter_module (shared)
mime_magic_module (shared)
expires_module (shared)
deflate_module (shared)
headers_module (shared)
usertrack_module (shared)
setenvif_module (shared)
mime_module (shared)
dav_module (shared)
status_module (shared)
autoindex_module (shared)
info_module (shared)
dav_fs_module (shared)
vhost_alias_module (shared)
negotiation_module (shared)
dir_module (shared)
actions_module (shared)
speling_module (shared)
userdir_module (shared)
alias_module (shared)
substitute_module (shared)
rewrite_module (shared)
proxy_module (shared)
proxy_balancer_module (shared)
proxy_ftp_module (shared)
proxy_http_module (shared)
proxy_ajp_module (shared)
proxy_connect_module (shared)
cache_module (shared)
suexec_module (shared)
disk_cache_module (shared)
cgi_module (shared)
version_module (shared)

The reason for removing is that Apache will load all of these into server memory. As a result making Apache heavier and slower for each request, especially as web server throughput increases!

 

Here’s my final list of modules

core_module (static)
mpm_event_module (static)
http_module (static)
so_module (static)
authz_host_module (shared)
authz_user_module (shared)
authn_file_module (shared)
auth_basic_module (shared)
log_config_module (shared)
logio_module (static)
expires_module (shared)
deflate_module (shared)
headers_module (shared)
setenvif_module (shared)
mime_module (shared)
dir_module (shared)
alias_module (shared)
rewrite_module (shared)
proxy_module (shared)
proxy_fcgi_module (shared)

Notice more than half of the preloaded modules have been stripped. I’ve also replaced MPM prefork with MPM event and added proxy_module and proxy_fcgi_module for PHP-FPM (see notes at the end of the article). Over the years since this article was originally published, the default before vs after has significantly improved.

 

Apache Modules Loaded by Default on Ubuntu

core_module (static)
log_config_module (static)
logio_module (static)
version_module (static)
mpm_prefork_module (static)
http_module (static)
so_module (static)
alias_module (shared)
auth_basic_module (shared)
authn_file_module (shared)
authz_default_module (shared)
authz_groupfile_module (shared)
authz_host_module (shared)
authz_user_module (shared)
autoindex_module (shared)
cgi_module (shared)
deflate_module (shared)
dir_module (shared)
env_module (shared)
mime_module (shared)
negotiation_module (shared)
reqtimeout_module (shared)
setenvif_module (shared)
status_module (shared)

Notice, that fewer modules are enabled by default than with CentOS.

 

Here’s my final list of modules on Ubuntu

core_module (static)
log_config_module (static)
logio_module (static)
version_module (static)
mpm_event_module (static)
http_module (static)
so_module (static)
auth_basic_module (shared)
authn_file_module (shared)
authz_host_module (shared)
authz_user_module (shared)
expires_module (shared)
deflate_module (shared)
headers_module (shared)
dir_module (shared)
mime_module (shared)
setenvif_module (shared)
rewrite_module (shared)
proxy_module (shared)
proxy_fcgi_module (shared)

In green are modules I’ve added that will also improve performance when configured correctly. While the rewrite_module is simply required by web apps such as WordPress for friendly URL rewrites (WordPress permalinks). Again the proxy modules for PHP-FPM.

 

Apache (httpd) Specific Module notes

mpm_prefork_module – With Apache 2.4, replace this with mpm_event_module. It’s faster & uses less memory. You can use MPM event with PHP FastCGI/PHP-FPM. Event MPM is fully supported as of Apache 2.4+.

log_config_module – Once your web app is stable decide if to turn off access logging via Apache config. Access logs add extra overhead to every request. This is negligent, but on high-throughput web servers, access logging can cause a more noticeable performance hit with gigabytes of logs being written daily. This module is also responsible for extremely important error logs.

status_module – The Status module allows server admins to find out how well Apache is performing. Safe to disable. Tracks ALL requests.

 

How to disable Apache Modules – Ubuntu/Debian

If you’re on Ubuntu, you can disable Apache modules using shell commands. Simply type the following a2dismod nameofmodule for each module:

a2dismod authz_groupfile

Repeat for each module you need to disable.

 

How to disable Apache Modules – CentOS/Fedora

If you’re running a CentOS server then simply comment out the lines for each module listed in /etc/httpd/conf/httpd.conf.

Update March 2nd 2020: on CentOS comment out the lines in /etc/httpd/conf.modules.d/00-base.conf

For example, change:

LoadModule auth_digest_module modules/mod_auth_digest.so

to

#LoadModule auth_digest_module modules/mod_auth_digest.so

Repeat for each module. When unsure, disable, then test config, disable, test config, and so on.

 

Important notes

— Make sure you have a list of the modules used with Ubuntu before you start disabling. On CentOS, copy (cp) httpd.conf to something like httpd.conf_bak. This way you can easily revert changes.

— With some of the modules, when disabled you will also have to comment out (remove) corresponding lines of config from httpd.conf (CentOS) or apache2.conf (Ubuntu). If you are not very familiar with Apache, then disable the modules one by one. After you disable each module, restart Apache to test. This is useful because when you disable some modules such as dav_module, autoindex_module, etc, then some of the related config lines in httpd.conf or apache2.conf will be left stranded. Thus, when you restart Apache, it will show errors. For example:

“Starting httpd: Syntax error on line 565 of /etc/httpd/conf/httpd.conf: Invalid command ‘IndexOptions’, perhaps misspelled or defined by a module not included in the server configuration”

These errors are so self-explanatory, it’s not funny. When you see an error after Apache restart you have two options 1) re-enable the module 2) go to the line that Apache error reports – in the above case, line 565 of /etc/httpd/conf/httpd.conf – and comment out the line. Repeat until Apache starts without error and then move on with disabling the next module and so on.

— For PHP-FPM with Apache 2.4 please see: http://wiki.apache.org/httpd/PHP-FPM

— Apache performance (similar to Nginx) isn’t accomplished by one or two changes. It’s composite and although there are many areas that can be expanded on above, to keep things simple, I’ve kept this article limited to stripping down Apache’s modules. In the future, I may get around to posting more Apache performance tips. Let me know below if this is something you’d be interested in me writing about.

— Once you’ve performed the various areas of Apache tuning, if you still need a performance boost or load reduction and don’t want to get rid of Apache, consider installing Nginx just for static files (CSS, js, images, etc). However, Apache 2.4 MPM event is a lot faster and more efficient in serving static files than MPM prefork or MPM worker ever was!

 

Published: Aug 15th, 2017 | Last updated: April 20th, 2022.

Tags: , ,

Comments

  1. Thanks for the guide. I made the switch to nginx years ago. I hope others do too :sweat_smile::sweat_smile::sweat_smile:

  2. Very good article. Found our use case Apache now benchmarks faster.

  3. That is a good breakdown on how to improve performance.

Join the discussion - post a comment.

Participants