Apache Performance Tuning Best Practices

Apache 2.0 is a general-purpose web server, designed to provide a balance of flexibility, portability, and performance. It is capable of high performance in many real-world situations.
There are few compile-time and run-time configuration choices that can significantly affect performance and could be recommended as best practices.
  • Hardware and Operating System Issues ApacheBest Practises
  • Run-Time Configuration Issues
  • Compile-Time Configuration Issues
Contents [show]

1.1 Hardware and Operating System Issues

The single biggest hardware issue affecting web server performance is RAM. A web server should never have to swap.  Swapping increases latency of each request beyond a point that users consider “fast enough”. These cause users to stop and reload which further increase the load. The Maxclients setting should be controlled so that server does not spawn so many children that it starts swapping.
Operating system choice is largely a matter of local concerns. Below are the guidelines that have been very useful for obtaining good OS Performance:
  • Run the latest stable release and patch level of the operating system.
  • If the OS supports sendfile(2) system call, make sure you install the release and/or patches needed to enable it.  Sendfile enables Apache 2 to deliver static content faster and with lower CPU utilization.
If you use any Allow from domain or Deny from domain directives then you will pay for a double reverse DNS lookup. For best performance, use IP addresses, rather than names, when using these directives.
1.1.1  AllowOverride
Wherever in your URL-space you allow overrides (typically .htaccess files) Apache will attempt to open .htaccess for each filename component.
Example
DocumentRoot/www/htdocs
<Directory/>
AllowOverrideall
</Directory>
For best performance use AllowOverride None everywhere in your filesystem.
1.1.2  Negotiation
Avoid content-negotiation for best performance of your web server. The benefits of negotiation outweigh the performance penalties. Use the option below to speed up the performance of the server
Instead of using a wildcard such as: “DirectoryIndex index”, use a complete list of options:  “DirectoryIndex index.cgi index.pl index.shtml index.htmllist the most common choice first.
Also note that explicitly creating a type-map file provides better performance than usingMultiViews, as the necessary information can be determined by reading this single file, rather than having to scan the directory for files.
1.1.3  Memory-mapping
In situations where Apache 2.0 needs to look at the contents of a file being delivered, it normally memory-maps the file if the OS supports some form of mmap(2).
On some platforms, memory-mapping improves performance.
There are few scenarios where memory-mapping can hurt the performance or even the stability of the httpd:
  • On some operating systems, mmap does not scale as well as read(2) when the number of CPUs increases. On multiprocessor Solaris servers, Apache 2.0 sometimes delivers server-parsed files faster when mmap is disabled.
  • If you memory-map a file located on an NFS-mounted filesystem and a process on another NFS client machine deletes or truncates the file, your process may get a bus error the next time it tries to access the mapped file content.
The installations where either of these factors applies, you should use EnableMMAP off to disable the memory-mapping of delivered files.
(Note: This directive can be overridden on a per-directory basis.)
1.1.4  Sendfile
In situations where Apache 2.0 can ignore the contents of the file to be delivered, it normally uses the kernel sendfile if the OS supports the sendfile(2) operation.
On most platforms, using sendfile improves performance by eliminating separate read and send mechanics.
There are cases where using sendfile can harm the stability of the httpd:
  • Some platforms may have broken sendfile support that the build system did not detect, especially if the binaries were built on another box and moved to such a machine with broken sendfile support.
  • With an NFS-mounted files, the kernel may be unable to reliably serve the network file through its own cache.
For installations where either of these factors applies, you should use EnableSendfile off to disable sendfile delivery of file contents.
(Note: This directive can be overridden on a per-directory basis.)
1.1.5  Process Creation
Related to process creation is process death induced by the MaxRequestsPerChild setting. By default this is 0, which means that there is no limit to the number of requests handled per child.
If your configuration has this set to some very low number, you increase this up significantly.
If you are running SunOS or an old version of Solaris, limit this to 10000, because of memory leaks.
When keep-alives are in use, child would be kept busy doing nothing but waiting for more requests on the already open connection. The default KeepAliveTimeout of 15 seconds attempts to minimize this effect.  At any time you should not raise this option above 60 seconds, or else the benefits of this feature would be largely lost.
1.1.6  Choosing an MPM
Apache 2.x supports pluggable concurrency models, called Multi-Processing Modules (MPMs). While building Apache, you have to choose a MPM.
There are platform-specific MPMs for some platforms are: beos, mpm_netware,mpmt_os2, and mpm_winnt.
The choice of MPM can affect the speed and scalability of the httpd:
  • The worker MPM uses multiple child processes with many threads each. Each thread handles one connection at a time. Worker generally is a good choice for high-traffic servers because it has a smaller memory footprint than the prefork MPM.
  • The prefork MPM uses multiple child processes with one thread each. Each process handles one connection at a time. On many systems, prefork is comparable in speed to worker, but it uses more memory. Prefork’s thread less design has advantages over worker in some situations: it can be used with non-thread-safe third-party modules, and it is easier to debug on platforms with poor thread debugging support.
1.1.7  Modules
Since memory usage is such an important consideration in performance, you should attempt to eliminate modules that you’re not actually using. If you have built the modules as DSOs, eliminating modules is a simple matter of commenting out the associated LoadModule directive for that module. This allows you to experiment with removing modules, and seeing if your site still functions in their absence.
If, on the other hand, you have modules statically linked into your Apache binary, you will need to recompile Apache in order to remove unwanted modules.
An associated question that arises here is, of course, what modules you need, and which ones you don’t. The answer here will, of course, vary from one web site to another. However, the minimal list of modules which you can get by with tends to include mod_mime, mod_dir, andmod_log_config. mod_log_config is, of course, optional, as you can run a web site without log files. This is, however, not recommended
1.1.8  DYNAMIC_MODULE_LIMIT
If you have no intention of using dynamically loaded modules (you probably don’t if you’re reading this and tuning your server for every last ounce of performance) then you should add -DDYNAMIC_MODULE_LIMIT=0 when building your server. This will save RAM that’s allocated only for supporting dynamically loaded modules.

1.2  Protect Server Files by Default

One aspect of Apache which is occasionally misunderstood is the feature of default access.
For instance, consider the following example:
# cd /; ln -s / public_html
Accessing http://localhost/~root/
This would allow clients to walk through the entire filesystem.
Add the following to block your server’s configuration:
<Directory />
Order Deny,Allow
Deny from all
</Directory>
This will forbid default access to filesystem locations.
Add appropriate Directory blocks to allow access only to those locations you wish to give access.
For example,
<Directory /usr/users/*/public_html>
Order Deny,Allow
Allow from all
</Directory>
<Directory /usr/local/httpd>
Order Deny,Allow
Allow from all
</Directory>
Pay particular attention to the interactions of Location and Directory directives.
The UserDir directive should be handled carefully. Setting this directive to  “./” would have the similar effect, for root, to as that in the example given above.
If you are using Apache 1.3 or above, it is strongly recommend that  the following line is included in your server configuration files:
UserDir disabled root