Apache Performance tuning involves implementing activities that optimize the server’s configuration and settings to improve its speed, efficiency, and scalability. In this guide, we would like to take you through a step-by-step process on how to improve your apache performance, providing a smooth browsing experience for your users:
Configure Enough RAM & CPU
The first step is to ensure that the server on which Apache is installed has enough RAM and CPU resources to handle the expected load. Apache should not have to use swap space, as this will significantly degrade performance.
Traffic Level | RAM (GB) | CPU Cores |
---|---|---|
Low Traffic | 1-2 | 1-2 |
Medium Traffic | 2-4 | 2-4 |
High Traffic | 4-8 | 4-8 |
Very High Traffic | 8+ | 8+ |
If you are unsure how much RAM and CPU your Apache webserver needs, you can use a tool like Apache Bench or Siege to test the server’s performance under load. This will give you an idea of how much resources the server needs, helping you achieve the performance tunning goals.
RECOMMENDED READING: How many concurrent connections can Apache Server handle?
Keep the operating system up to date
Keeping an operating system up to date helps to tune the performance of the Apache web server in the following ways:
- Security fixes: They often include security fixes that can protect the Apache web server from vulnerabilities. This can help to improve the performance of the web server by reducing the risk of attacks and malware infections.
- Bug fixes: updates also often include bug fixes that can improve the overall stability and performance of the operating system. This can have a positive impact on the performance of the Apache web server, which relies on the operating system to function properly.
- Performance enhancements: System updates can also include performance enhancements, speeding up the responsiveness of the system. This can also benefit the Apache web server, which can process requests more quickly and efficiently when the operating system is running smoothly.
- Kernel optimizations: Updates can facilitate kernel optimizations which improve the overall performance of the Apache web server by reducing the overhead associated with system calls and other kernel-level operations.
- Networking enhancements: System updates can include networking enhancements that improve the performance of the Apache web server by reducing the latency and increasing the throughput of network traffic.
- New features: Updates can ship in new features that can be used to tune the performance of the Apache web server. For example, some operating systems include features that allow you to prioritize traffic to the Apache web server or to allocate more resources to the web server processes.
How to set up automatic updates on Ubuntu Server
Setting up automatic updates can save you time and effort. This means that your server will do the updates by itself without requiring any manual intervention from you.
RECOMMENDED READING: How to use the apt command in Linux | Syntaxes & Examples
On Ubuntu, we can set up automatic updates using the unattended-upgrades package. This can be installed using the following command:
sudo apt install unattended-upgrades
After the installation of the unattended-upgrades package, you can configure automatic updates by typing the following command:
sudo dpkg-reconfigure unattended-upgrades
Running the above package will open a pop-up on the terminal as seen in the image below:
The next step is to edit and customize the configuration file using nano
or any other editor of your choice. In this case, we’re using nano editor by running the following command:
sudo nano /etc/apt/apt.conf.d/50unattended-upgrades
Inside the configuration file, you need to look for the section that looks something like this:
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}";
"${distro_id}:${distro_codename}-security";
// "${distro_id}:${distro_codename}-updates";
// "${distro_id}:${distro_codename}-proposed";
// "${distro_id}:${distro_codename}-backports";
};
Now, you need to make sure the final file configuration in your setup should look as follows:
Unattended-Upgrade::Allowed-Origins {
// "${distro_id}:${distro_codename}";
"${distro_id}:${distro_codename}-security";
// "${distro_id}:${distro_codename}-updates";
// "${distro_id}:${distro_codename}-proposed";
// "${distro_id}:${distro_codename}-backports";
};
From the above code, the second line is uncommented and the first and the last 3 lines are commented with // meaning they won’t be considered.
The uncommented line;
"${distro_id}:${distro_codename}-security";
This line is necessary to allow automatically installing security updates.
If you need to set up auto-cleanup and remove older kernel versions, you can add the following line in the configuration file:
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
Configure Prefork MPM for moderate to low-traffic websites
Multi-Processing Modules (MPMs) are responsible for how the Apache HTTP Server handles concurrent requests. They determine how the server binds to network ports, accepts requests, and dispatches child processes to handle the requests.
The prefork MPM creates a fixed number of child processes that handle web requests. Each child process can handle multiple connections simultaneously. This model is simple and reliable, but it can be resource-intensive, especially when handling a high volume of connections.
RECOMMENDED READING: A beginner’s Guide to Cross-origin Resource Sharing (CORS)
If you want to use Prefork, you can check if it’s installed by running the following command:
apache2ctl -M | grep prefork
If the prefork module is installed and loaded, the following will be output on the terminal:
mpm_prefork_module (shared)
This indicates that the prefork module is loaded and shared. The module is also likely being used as the server’s Multi-Processing Module (MPM) if the output of apache2ctl -V | grep MPM
is:
Server MPM: prefork.worker
However, the prefork module may be loaded but not be used as the server’s MPM. This could be the case if:
- The server is configured to use a different MPM, such as worker.
- The prefork module is loaded as a dynamic shared object, but another MPM is loaded directly into the server executable.
To check which MPM is being used by the server, you can use the command:
apache2ctl -V | grep MPM
This command will output the following:
Server MPM: <mpm_name>
Where <mpm_name>
is the name of the MPM currently being used by the server, such as prefork, worker, or event.
RECOMMENDED READING: How to Troubleshoot Apache not Serving Web Pages?
If Prefork is not installed on your system, then you need to run the following command on your Ubuntu terminal:
sudo apt install libapache2-mod-prefork
To configure Prefork, you have to edit the Apache configuration file and uncomment the following lines:
LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
StartServers 8
MinSpareServers 20
MaxSpareServers 40
MaxRequestWorkers 200
MaxConnectionsPerChild 4500
Let’s break down this configuration for beginners:
1. LoadModule:
LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
This line tells Apache to load the prefork MPM module. It specifies the module’s full path:
mpm_prefork_module
: Name of the prefork modulemodules/mod_mpm_prefork.so
: Path to the module file
2. StartServers:
StartServers 8
This line defines the initial number of child processes Apache will spawn when it starts. These child processes are also called workers or servers. In this case, Apache will start 8 workers initially.
The most significant factor is your server’s available RAM. Each Prefork process consumes memory, and starting too many can lead to exhaustion. It’s generally recommended to allocate around 128-256MB per process, but this can vary depending on your application’s memory usage.
RECOMMENDED READING: How to troubleshoot Apache “Connection refused” error?
Also, while Prefork processes are single-threaded, having multiple active processes can still benefit from multiple CPU cores. However, excessive processes can lead to diminishing returns due to context-switching overhead.
3. MinSpareServers:
MinSpareServers 20
This line defines the minimum number of idle child processes Apache will maintain. These idle workers are ready to handle incoming requests immediately. This ensures some level of performance even if traffic spikes suddenly.
4. MaxSpareServers:
MaxSpareServers 40
This line defines the maximum number of idle child processes Apache will maintain. This value should be higher than MinSpareServers
to ensure a sufficient pool of idle workers. However, setting it too high can consume excessive resources.
5. MaxRequestWorkers:
MaxRequestWorkers 200
This line defines the maximum number of child processes Apache can spawn concurrently. This limits the total number of requests served simultaneously. Setting it too low can lead to bottlenecks while setting it too high can overload the system.
RECOMMENDED READING: Could not reliably determine the server’s fully qualified domain
When do you need to use Prefork MPM in Apache?
You should use the Prefork Multi-Processing Module (MPM) in your Apache configuration under the following circumstances:
- Compatibility with non-thread-safe libraries
If your application relies on libraries that are not thread-safe, Prefork is the only safe option. Thread-unsafe libraries can lead to crashes or unpredictable behavior when accessed by multiple threads simultaneously. Prefork avoids this issue by using separate processes for each request, ensuring that each library instance operates in isolation. For example, websites using older versions of PHP (5.4 or earlier): These versions of PHP were not thread-safe and required Prefork for safe operation. Additionally, applications use external libraries or modules that are not thread-safe.
- Isolation of requests:
Prefork excels at isolating requests from each other. Each request is handled by a dedicated child process, preventing issues in one request from affecting others. This can be crucial for applications where stability and reliability are paramount. In this case, Servers where each request needs to be isolated for security reasons would require Prefork to be configured.
- Limited memory
While Prefork requires more memory than other MPMs due to its process-based approach, it can be a good choice for servers with limited memory. This is because Prefork avoids the memory overhead associated with thread stacks and other thread-related data structures. For example, Servers with limited memory and a need for high stability can be configured to use Prefork in the Apache configuration.
6. MaxConnectionsPerChild:
MaxConnectionsPerChild 4500
This line defines the maximum number of concurrent connections each child process can handle. This value should be chosen based on the expected request volume and server resources. A higher value allows each worker to handle more connections, but it can also lead to memory exhaustion if not chosen carefully.
Child processes are individual instances of the Apache server program that handle incoming requests. They are created during server startup and remain active until terminated by the parent process or reach their maximum connection limit.
It’s important to note the following:
- Each child process waits for incoming client connections, processes incoming requests, and sends responses back to the clients.
- Each child process operates in its isolated environment, preventing issues in one process from affecting others. This improves stability and security.
- The number of child processes can be adjusted to handle varying traffic loads. This enables the server to scale to meet demand.
- Prefork uses a single thread within each child process. This means only one request can be handled at a time per child.
- Child processes are designed to handle a specific number of connections before being recycled. This helps prevent memory leaks and performance issues.
- The parent process is responsible for creating, managing, and terminating child processes based on server needs.
Set up Worker MPM for high-traffic applications
The Worker MPM is a hybrid between prefork and threaded MPMs. It creates a fixed number of child processes, each of which has a pool of threads that handle requests. Worker is more scalable than prefork, but it is also more complex and can be less stable.
To enable Worker MPM, you need to modify the Apache configuration file. The location of this file may vary depending on your system, but it’s typically found at:
/etc/apache2/httpd.conf
Open the file using a text editor and locate the following line:
LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
Comment this line out by adding a #
at the beginning:
#LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
Then, uncomment the following line to enable Worker MPM:
LoadModule mpm_worker_module modules/mod_mpm_worker.so
Configuring Worker MPM Parameters:
Once Worker MPM is enabled, you need to adjust some configuration parameters to optimize performance for your specific needs. Here are some key directives to consider:
- StartServers: This directive specifies the number of child processes launched when Apache starts. A good starting point is 4-8, but you can adjust this based on your server’s resources.
- MinSpareServers: This directive defines the minimum number of idle child processes kept available to handle sudden spikes in traffic. A good starting point is 4-8.
- MaxSpareServers: This directive sets the maximum number of idle child processes. Keep it at a slightly higher value than MinSpareServers, typically 8-16.
- MaxClients: This directive limits the maximum number of simultaneous connections allowed by Apache. The recommended value is 256, but adjust it based on available memory and CPU resources.
- ThreadsPerChild: This directive specifies the number of threads per child process. A higher value can improve performance, but it also consumes more resources. Start with 4-8 and adjust based on your needs.
Here’s an exemplary configuration section for Worker MPM:
LoadModule mpm_worker_module modules/mod_mpm_worker.so
StartServers 5
MinSpareServers 10
MaxSpareServers 20
MaxClients 256
ThreadsPerChild 25
When do you need to use Worker MPM?
You should use the Worker MPM in the following situations:
- High concurrency: If your website receives a large number of concurrent connections, the Worker MPM will be more efficient than the Prefork MPM. This is because the Worker MPM can use threads to handle multiple requests simultaneously.
- Non-blocking I/O: If your website uses non-blocking I/O operations, such as those provided by PHP-FPM, the Worker MPM will be able to handle them more efficiently than the Prefork MPM.
- FastCGI applications: If your website uses FastCGI applications, such as PHP-FPM, the Worker MPM is the recommended MPM.
- mod_perl applications: If your website uses mod_perl, the Worker MPM is the recommended MPM.
- Scalability: If you expect your website to grow in the future, the Worker MPM is a good choice because it is more scalable than the Prefork MPM.
Types of applications that need Worker MPM
Here are some specific cases where Worker MPM shines
- High-traffic websites: Websites experiencing high volumes of concurrent visitors will benefit from the performance and scalability provided by Worker MPM.
- Web applications with real-time features: Applications like chat rooms, online gaming platforms, and collaboration tools rely on fast and efficient handling of concurrent connections, which Worker MPM excels at.
- E-commerce platforms: High-traffic e-commerce websites with frequent product updates and shopping cart functionality can leverage Worker MPM for optimal performance.
- Media streaming services: Streaming websites and multimedia platforms require smooth and efficient streaming for large audiences, which Worker MPM facilitates.
Customize other Core apache directives
Optimizing Apache core directives can significantly improve your web server’s performance and efficiency. Here are some key directives you can adjust to achieve maximum performance:
KeepAlive directive
Keepalive connections are a valuable tool for improving the performance of your Apache web server. By enabling keepalive, you allow clients to reuse the same TCP connection for multiple requests, reducing the overhead of establishing new connections for each request. This can significantly improve server response times and reduce overall resource usage.
Find the KeepAlive
directive within the configuration file. By default, it might be commented out. Uncomment it and set it to On
:
KeepAlive On
Configure Keepalive Timeout
The KeepAliveTimeout
directive specifies how long (in seconds) the server should wait for a new request from a client before closing the keepalive connection. A typical value is 5 seconds:
KeepAliveTimeout 5
A higher value allows longer idle connections but consumes more resources.
Configure Maximum Keepalive Requests
The MaxKeepAliveRequests
directive sets the maximum number of requests that can be processed through a single keepalive connection. A value of 100 is a common setting:
MaxKeepAliveRequests 100
Additional Configuration Options
There are several other Keepalive options you can configure, depending on your specific needs. These options include:
KeepAliveMax
: Defines the maximum number of keepalive connections the server will handle at once.
KeepAliveMin
: Sets the minimum number of keepalive connections the server will keep open.
KeepAliveIdleTimeout
: Specifies how long an idle keepalive connection should be kept open before being closed.
Enable Caching in Apache Server
Caching is one of the most effective ways to improve the performance of an Apache web server. Caching stores static content in memory, so that it can be served to users without having to regenerate it each time.
To enable caching on your Apache web server, you will need to implement the following:
Method #1: Enable mod_cache and mod_cache_disk modules for Server-side caching
Server-side caching is a technique for improving the performance of web applications and websites by storing frequently accessed data on the server rather than retrieving it from the origin server every time a request is made. This can significantly reduce server load, improve response times, and enhance user experience.
Server-side caching works in such a way that:
- A user sends a request to the web server for a specific piece of data, such as a web page, image, or API endpoint.
- The server checks its cache to see if the requested data is already stored there.
- If the data is found in the cache, it is immediately served to the user, bypassing the need to retrieve it from the origin server. This results in a much faster response time for the user.
- If the data is not found in the cache, the server retrieves it from the origin server.
- Once the data is retrieved, the server stores it in its cache for future requests.
The mod_cache
modeule is used to provide the core server-side caching functionality and the mod_cache_disk
allows caching static content on disk for improved performance.
To enable these two modules, run these commands on your server terminal:
sudo a2enmod cache
sudo a2enmod cache_disk
When these modules are enabled, you need to add the following code in your Apache configuration file:
<IfModule mod_cache.c>
CacheEnable disk /
CacheDefaultExpire 3600
<FilesMatch "\.(ico|pdf|jpg|jpeg|png|gif|svg|js|css|swf)$">
CacheControl public
</FilesMatch>
</IfModule>
The breakdown of the above code is as follows:
- CacheEnable: This directive enables caching for a specific file or directory.
- CacheControl: This directive specifies how long browsers and intermediaries can cache the content.
- CacheHeader: This directive adds custom headers to the response for better cache control.
Therefore, this configuration enables disk caching for all files and sets the default expiration time to 1 hour (3600 seconds). It also sets the Cache-Control
header to public
for static files, allowing them to be cached by browsers and intermediaries.
After making changes to the configuration file, restart Apache for the changes to take effect:
sudo systemctl restart apache2
Method #2: Enable the mod_expires for Browser Caching
Browser caching is a mechanism used by web browsers to store website resources locally on users’ devices. These resources include things like images, videos, JavaScript files, CSS files, and HTML files. When you visit a website for the first time, your browser downloads all of the necessary resources and stores them in its cache. This means that the next time a user visits your website, their browsers will be able to load the resources much faster, as they will no longer need to download them from the server.
The mod_expires
module is responsible for browser caching and you can enable it by running the following command:
sudo a2enmod expires
The mod_expires module controls how long static content is cached. To configure this module, open the Apache configuration file (usually located at:
/etc/apache2/httpd.conf
Or located on this path
/etc/httpd/conf/httpd.conf
To load the mod_expires module, you need to add the following line in the Apache configuration:
LoadModule expires_module modules/mod_expires.so
When the mod_expires module is loaded, you can customize the browser caching behavior as follows
LoadModule expires_module modules/mod_expires.so
ExpiresActive On
ExpiresDefault "access plus 1 week"
The ExpiresActive On directive enables caching and the ExpiresDefault
directive sets the default expiration time for cached content. You can change the expiration time to meet your specific needs.
You can also customize the browser caching period for various file types as seen below:
ExpiresByType image/gif "access plus 1 hour"
ExpiresByType image/jpeg "access plus 1 hour"
ExpiresByType image/png "access plus 1 hour"
If you don’t want to specify the cache expiration period for each AddType, you can simply use the ExpiresDefault
directive to set a default expiration time for all files that don’t have an explicit rule.
Can I use both mod_expires and mod_cache?
Yes, you can implement both mod_expires for browser caching and mod_cache for server-side caching in Apache web server.
mod_expires
focuses on setting expiration times for static content like images, CSS, and JavaScript files. It adds headers to responses telling browsers to cache these files for a specific duration, reducing server load and improving website loading times.
This is a simple and effective way to improve website performance, especially for websites with a lot of static content.
On the other hand, mod_cache
focuses on caching entire responses in memory on the server. This allows subsequent requests for the same content to be served directly from the cache, further reducing server load and improving website responsiveness.
This is particularly beneficial for dynamic content that is accessed frequently, such as product pages or user profiles.
What to consider if you’re using both mod_expires and mod_cache modules
While using both modules together can be advantageous, it’s important to carefully configure them to avoid conflicts or performance issues. Here are some key points to remember:
- Order of modules: Make sure
mod_expires
is loaded beforemod_cache
in the Apache configuration file. This ensures that expiration headers are added before the content is cached.
- Caching rules: Define different caching rules for static and dynamic content. For example, static content can have longer expiration times than dynamic content.
- Cache invalidation: Implement mechanisms to invalidate cached content when it becomes outdated or changes. This can be done manually or using automated tools.
Enable Compression in Apache Server
Compression reduces the size of web pages before they are sent to the user’s browser, which can significantly improve page load times.
Configure the mod_deflate module
The mod_deflate module compresses web pages before they are sent to the user’s browser. So, to enable this module in Apache, you need to run the following command:
sudo a2enmod deflate
After enabling the mod_deflate module, you will have to configure the appropriate parameters in the Apache configuration file and add the following lines to the end of the file:
LoadModule deflate_module modules/mod_deflate.so
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css application/javascript
DeflateCompressionLevel 9
DeflateBufferSize 8096
DeflateMemLevel 9
</IfModule>
The ModDeflate On directive enables compression and the AddOutputFilterByType directive specifies the types of content that should be compressed.
Once you have enabled caching and compression, you need to restart the Apache web server for the changes to take effect. On most Linux distributions, you can do this by running the following command:
sudo systemctl restart apache2
Once you have enabled caching and compression, you should notice a significant improvement in the performance of your Apache web server. Your web pages will load faster, and your users will be happier.
Removing unused modules in Apache for performance tuning
Removing unused modules in Apache can improve performance by reducing memory usage and CPU load. Here’s how to achieve this:
Identify unused modules
You need to review the list of available Apache modules and compare it to your website’s functionality. Analyze which modules are not used by your website or applications.
You can utilize tools like:
apachectl -t -D DUMP_MODULES
or
apache2ctl -t -D DUMP_MODULES
Use any of the above to identify loaded modules and their dependencies.
Alternatively, you can analyze your Apache logs to see which modules are actively used. Tools like grep
can help you filter entries related to specific modules.
Locate and disable the module in the configuration files
Apache modules are typically loaded from files located in the /etc/apache2/mods-available
directory. Each module has a corresponding configuration file.
- Comment out lines: Open the relevant module configuration file and comment out the line starting with
LoadModule
. This will prevent the module from being loaded.
- Disable dynamically loaded modules: Inside the Apache configuration file, look for the line
IncludeOptional conf.d/*.conf
. This line instructs Apache to load modules from the/etc/apache2/conf.d
directory. You can disable specific modules by renaming or moving their corresponding.conf
files.
Verify configuration
After disabling modules, restart Apache by running the following command:
sudo systemctl restart apache2
Then, verify the configuration syntax using this command:
sudo apache2ctl -t
If there are any errors, you might have disabled a required module.
Increase PHP Memory Limit
Increasing PHP memory can potentially optimize Apache performance, but it’s important to do so carefully and strategically to avoid negative effects.
Modifying PHP memory limit using the php.ini file
You can edit the php.ini
file and adjust the memory_limit
directive. For example, the following configuration increases the PHP memory limit to 4GB
memory_limit = 4096M
PHP-FPM (Optional)
PHP-FPM (FastCGI Process Manager) is a daemon that manages the execution of PHP scripts. It acts as a bridge between web servers (like Apache or NGINX) and the actual PHP interpreter. When a web server receives a request for a PHP script, it sends the request to PHP-FPM, which then spawns a child process to execute the script. This process model allows for the efficient handling of multiple concurrent PHP requests.
To Modify the pool configuration file:
- Locate the pool configuration file for your PHP-FPM pool. This file is typically named
www.conf
or similar.
- Open the file and locate the
pm.max_children
directive. This directive controls the maximum number of child processes that can be spawned.
- Reduce the value of
pm.max_children
to reduce the overall memory consumption by PHP-FPM.
- Save the file and restart your PHP-FPM service.