According to a recent report by Netcraft (a well-known Internet company that provides among other services web browser usage statistics), Apache continues to be the most widely used web server among sites and Internet-facing computers.
Additionally, Apache keeps experiencing the largest growth among the top web servers, followed by Nginx and IIS. Thus, if you are a system administrator in charge of managing Apache installations, you need to know how to make sure your web server performs at the best of its capacity according to your (or you client’s) needs.
In this article we will discuss a few tips that will help you ensure that Apache will run smoothly and be able to handle the number of requests you are expecting from remote clients.
However, please keep in mind that Apache was not designed with the objective of setting benchmark records – but, even so, it is still capable of providing high performance in almost any usage case you can possibly think of.
TIP #1: Always keep Apache updated to its latest version
It goes without saying that having the latest version of Apache installed is probably one of the first things you need to consider. As of November 19, 2015, the latest version of Apache available in the CentOS 7 repositories is 2.4.6, whereas in Debian’s is 2.4.10.
However, there may be a recent improvement or a bug fix that has been added to a newly-released stable version, which is then made available to download and install from source. Compilation and installation instructions are also provided here – just remember that if you choose this update method, you may want to back up your current configuration files / sites / virtual hosts as a precaution.
In any event, you can check your currently installed version as follows:
# httpd -v [On RedHat/CentOS based systems] # apache2 –v [On Debian/Ubuntu based systems]
As a rule of thumb, stick with the update method provided by the package manager of your chosen distribution (yum update httpd
or aptitude safe-upgrade apache2
, for CentOS or Debian, respectively) unless there is no other way. You can read the latest release notes in the Apache Documentation section in the Apache HTTP server Project website.
TIP #2: If you are using a Kernel older than 2.4, consider upgrading now
Why? Kernel versions 2.4 and above have the sendfile kernel system call enabled by default. That, in turn, facilitates high performance network file transfers (which are desired in the context of web server-client communications) and enables Apache to deliver static content faster and with lower CPU utilization by performing simultaneous read and send operations.
You can view your currently installed kernel with:
# uname -r
and compare it to the latest stable kernel in www.kernel.org (4.3 at the time of this writing).
Although it is a process not intended for beginners, upgrading your kernel is an interesting exercise to learn more about the internals of Linux.
TIP #3: Choose the Multi-Processing Module (MPM) that works best for your case
In practice, MPMs extend the modular functionality of Apache by allowing you to decide how to configure the web server to bind to network ports on the machine, accept requests from clients, and use children processes (and threads, alternatively) to handle such requests.
Beginning with version 2.4, Apache offers three different MPMs to choose from, depending on your needs:
- The
prefork
MPM uses multiple child processes without threading. Each process handles one connection at a time without creating separate threads for each. Without going into too much detail, we can say that you will want to use this MPM only when debugging an application that uses, or if your application needs to deal with, non-thread-safe modules like mod_php. - The
worker
MPM uses several threads per child processes, where each thread handles one connection at a time. This is a good choice for high-traffic servers as it allows more concurrent connections to be handled with less RAM than in the previous case. - Finally, the
event
MPM is the default MPM in most Apache installations for versions 2.4 and above. It is similar to the worker MPM in that it also creates multiple threads per child process but with an advantage: it causes KeepAlive or idle connections (while they remain in that state) to be handled by a single thread, thus freeing up memory that can be allocated to other threads. This MPM is not suitable for use with non-thread-safe modules like mod_php, for which a replacement such a PHP-FPM must be used instead.
To check the MPM used by your Apache installation, you can do:
# httpd -V
The image below show that this particular web server is using the prefork MPM.
To change this, you will need to edit:
# /etc/httpd/conf.modules.d/00-mpm.conf [On RedHat/CentOS based systems] # /etc/apache2/mods-available/<mpm>.load [On Debian/Ubuntu based systems]
Where <mpm> can be mpm_event, mpm_worker, or mpm_prefork.
and uncomment the line that loads the desired module like so:
LoadModule mpm_event_module modules/mod_mpm_event.so
Note: To make the event MPM work in Debian, you may have to install the libapache2-mod-fastcgi package from the non-free repositories.
Additionally, for CentOS you will need php-fpm (along with fcgi and mod_fcgid) whereas in Debian it’s called php5-fpm (along with apache2-mpm-event).
Last, but not least, restart the web server and the newly installed php-fpm (or php5-fpm) service:
On RedHat/CentOS
# systemctl restart httpd php-fpm && systemctl enable httpd php-fpm
On Debian/Ubuntu
# systemctl restart apache2 php5-fpm && systemctl enable apache2 php5-fpm
Although you can set Apache to use a specific MPM, that configuration can be overridden on a per-virtual host basis in the same fashion as indicated earlier.
Just drop the corresponding tags into the configuration file for each virtual host and you’re ready to go – but make sure you’re using one and only one MPM per vhost.
Finally, please note that regardless of your chosen distribution, php-fpm relies on the implementation of FastCGI, which is the reason why I recommended the additional package installations earlier.
For more details and examples on php-fpm and how it can along with the event MPM increase the performance of Apache, you should refer to the official documentation.
This is what I see after changing the default MPM from prefork to event in the same box shown in the previous image:
In CentOS 7, you will need to make sure that the http and https services are enabled through the firewall, and that the network interface(s) are properly added to the default zone.
For example:
# firewall-cmd --zone=internal --add-interface=tun6to4 # firewall-cmd --zone=internal --add-interface=tun6to4 --permanent # firewall-cmd --set-default-zone=internal # firewall-cmd --add-service=http # firewall-cmd --add-service=https # firewall-cmd --add-service=http --permanent # firewall-cmd --add-service=https --permanent # firewall-cmd --reload
The reason why I’m bringing this up is because I recently experienced an issue where the default firewalld configuration settings in a cloud VPS prevented php-fpm and Apache from processing php files.
As a basic test (I am sure you can think of more complicated or stressful ones), I will create a php file that checkes the existence of another file named test.php
in the same directory of two CentOS 7 servers with the same hardware characteristics and load but with different MPM. One of them will use event and the other one will use prefork:
This is the php code that I’ve saved into a file named checkiffileexists.php
:
<?php $filename = 'test.php'; if (file_exists($filename)) { echo "The file $filename exists"; } else { echo "The file $filename does not exist"; } ?>
Then we will run the Apache benchmark tool (ab) with 200 simultaneous requests until 2000 requests are completed:
# ab -k -c 100 -n 2000 localhost/checkiffileexists.php
Let’s run the test and compare the results. Pay attention to the performance statistics:
As you can see, the performance of the server with event is highly superior to its prefork counterpart in every aspect of this test.
TIP #4: Allocate RAM wisely for Apache
Perhaps the most critical hardware item to be taken into account is the amount of RAM allocated for each Apache process. While you cannot control this directly, you can restrict the number of child processes through the MaxRequestWorkers directive (formerly known as MaxClients in Apache 2.2), which will put limits on the RAM usage by Apache. Again, you can set this value on a per host or per virtual host basis.
To do this, you should take note of the average amount of RAM used by Apache, then multiply it by the number of MaxRequestWorkers, and that is the amount of memory that will be allocated for Apache processes. One thing you never want your web server to do is to begin using swap, as that will significantly decrease its performance. Thus, you should always keep the usage of RAM by Apache within the limits that you can afford and never rely on swap for it.
For example, the following block will restrict the number of simultaneous clients to 30. If more clients hit the host, they may experience a delay or a momentary failure that can be easily solved by refreshing the browser. While this may be considered undesirable, it is healthier for the server and in the long run, best for your site as well.
You can place this block inside /etc/httpd/conf/httpd.conf
or /etc/apache2/apache2.conf
, depending on whether you are using CentOS or Debian.
Please note that the same principle applies to all MPMs – I am using event here to continue with the concept outlined in the previous tip:
<IfModule mpm_event_module> StartServers 3 MinSpareThreads 25 MaxSpareThreads 75 ThreadLimit 64 ThreadsPerChild 25 MaxRequestWorkers 30 MaxConnectionsPerChild 1000 </IfModule>
In any event, it is highly recommended that you refer to the Apache 2.4 docs to see which directives are allowed for your chosen MPM.
TIP #5: Know your applications
As a rule of thumb, you should not load any Apache modules that are not strictly needed for your application to work. This will require at least an overall knowledge of the applications running on your server, specially if you are a system administrator and there’s another team in charge of development.
You can list the currently loaded modules with:
# httpd -M [On RedHat/CentOS based systems] # apache2ctl -M [On Debian/Ubuntu based systems]
To unload / disable modules in CentOS, you will need to comment out the line that begins with LoadModule (either in the main configuration file or in an auxiliary one inside /etc/httpd/conf.modules.d.
On the other hand, Debian provides a tool called a2dismod to disable modules and is used as follows:
# a2dismod module_name
To enable it back:
# a2enmod module_name
In either case, remember to restart Apache for the changes to take effect.
Summary
In this article we have reviewed 5 tips that will help you tune the Apache web server and increase its performance. In addition, you should remember that optimization and performance without security is pointless, so you may want to refer to the install mod_pagespeed to improve webserver performance and Apache hardening tips article in Tecmint.com as well.
Since we cannot adequately cover all the aspects of this topic in this article, perhaps you will think of other ideas that you would like to share with the rest of the community. If so, feel free to let us know using the comment form below.
Hello, I benefitted immensely from the migration from prefork to Event.
this is the only tutorial that showed differences both made.
Mine Prefork loaded in 80+ seconds, now with the event, it didn’t budge much but RAM usage was much less. sadly server was on PHP 5.6. now I have updated it and getting the time of 25 seconds.
Quite an Improvement. Thanks
Sorry I am a little confused, So if I am using PHP 7.2 and mpm prefork and I want to change my mpm to event, my project will still working or I must use php-fpm first ?
I have apache 2.4.18 and Ubuntu 16 ..
@Ahmad,
Yes, you can change your Apache from MPM to Event, your all application will work without any errors..
Hi, after implement this tutorial to my centos 7 server. i check with
httpd -V
is show event mod. but on test.php is still show version api apache 2 handler. what its normal? when I don’t know how to solve this? thanks in advancedI have the same problem, any clue please
Hi,
I have done same configuration on centos 7, but when i try to run (localhost/checkiffileexists.php) on browser it gives me error for event module.
Do we need to any changes in apache to run php files using php-fpm?
@Pankaj,
Could you share exact error message? so that we can get idea.
I have done the same steps and my results are different, in my case, event is better without php-fpm and and prefork has so much request in apache 2.4.28 on Fedora 26 — it seems a little crazy.
This is a TERRIBLE guide.
You don’t need to compile from Source unless you need to do something differently to the package maintainer!
And having your server drop a connection and force a user to refresh? WTF are you on!?
what do you mean with your statement? can you explain that to get more education about this case.
I completely disagree with some tips:
#1. Why do you have to compile Apache?, that’s a dumb idea in a production environment. Even if you do that you need to optimize your binary at the same level as the distro mantainers.
#2. Hey: are you SERIOUS? RHEL/CentOS 4.x, and Debian 4 ALREADY have kernel >2.4 those are distros 11-12 years old!!! Excuse me what are you running in 2.4 your wrt54g?
#3 Fine but bad explained, the main reason which prefork exists is backwards compatibility not debug, period.
Believe it or not, there are people using really, really old distros. If tip #2 (or any of the tips listed in this article) does not apply to you, don’t just assume it’s not gonna be useful for other people.
I’m sorry, I think #1 is very bad advice. There’s absolutely no reason to forgo the distribution’s apache security updates (which are fairly frequent) and make a mess of your servers by compiling software on them. It’s 2017 and I cannot believe there are still people who “make; make install” on servers. Barbaric.
Tim,
Why then, in your opinion, does the Apache website include a section dedicated to compiling and installing from source?
Because you have to know how to? You realize you can’t build a package without knowing how to build something from source, right?
I have a dedicated Jenkins build that automatically downloads all the parts, including OpenSSL and FIPS, complies them all, then uploads to our repository, that we then put on our servers, thus servers are clean.
The script I wrote do do all this cleans up afterwards, so the build server is just as clean after the build as it was before.
Thank you Gabriel, It was such a useful tip…
Apart from configuring Apache, there are other ways of boosting performance of your PHP based websites. I have hosted my PHP website on AWS through Cloudways. Their platform is using Apache, Varnish, Memcached, Nginx and MySQL stack with Cloudflare. When I upgrade my website to PHP 7 the benchmarks were 4ms response time with 250 concurrent users.
@olivedev,
Thanks for your insightful comment. We usually write these tutorials on VirtualBox VMs, and thus unfortunately we don’t have the same resources you are referring to. However, it’s great to know in case our readers are considering using the same services.
MPM Configuration depend upon your server confirguration and application run over the apache. For basic tuning you may refer http://www.techflirt.com/apache-performance-tuning
@Davi,
Thank you for sharing that link with us!
Hi Gabriel,
I’m running CentOS 7 and Apache 2.4.6 with event MPM. Not PHP.
Visitors can distribute certian files, both upload and download. However, while the download speed is quite good, the upload speed is horrible low, just 64-240 kb/s. Downloadspeed is about 2 mb/s. Do you think this is an Apache issue?
@Yaroslav,
At first glance I would say no, it is not an Apache issue, as there are other considerations to be taken into account. Is this a production server? Do your clients have the same upload speeds when checking their Internet connections against a service such as speedtest.net (assuming this server is facing the Internet)? You mentioned a upload speed range (64-240kb/s). Is this an average for all users? Any time of day?
this kills PHP on Apache 2.4.6
standard prefork – fine
worker or event – PHP does not work.
@rob,
You forgot to tell us which distro you are using. Note there is a warning in the article for Debian and Debian-based distros. It DOES work on CentOS 7. I know that for a fact since that’s the distro I used to write the article.
This another ones:
– Disable non use shared modules
– Do not use .htaccess
– Set HostnameLookups = Off
@Yoander,
Thank you for sharing! We will keep this in mind.
Yes, very useful, learned a few new things. Thanks!
Very useful tips, thank you Gabriel!