How to implement performance tunning in Apache Webserver

Where necessary, you may need to have access to a VPS server so you can follow how to implement the steps in this article.  You can get a cheaper VPS Server from Contabo with 4vCPU cores, 8GM RAM, and 32TB Bandwidth for less than $5.50 per month. Get this deal here now

Table of Contents

Cloud VPS S

$5.50 Monthly
  • 4 vCPU Cores | 8GB RAM


$15.50 Monthly
  • 6 vCPU Cores | 16GB RAM


$17.50 Monthly
  • 8 vCPU Cores | 24GB RAM

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 LevelRAM (GB)CPU Cores
Low Traffic1-21-2
Medium Traffic2-42-4
High Traffic4-84-8
Very High Traffic8+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:

How to implement performance tunning in Apache Webserver

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}-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}-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;


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/
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/

This line tells Apache to load the prefork MPM module. It specifies the module’s full path:

  • mpm_prefork_module: Name of the prefork module
  • modules/ 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:


Open the file using a text editor and locate the following line:

LoadModule mpm_prefork_module modules/

Comment this line out by adding a # at the beginning:

#LoadModule mpm_prefork_module modules/

Then, uncomment the following line to enable Worker MPM:

LoadModule mpm_worker_module modules/

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/
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

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:


Or located on this path


To load the mod_expires module, you need to add the following line in the Apache configuration:

LoadModule expires_module modules/

When the mod_expires module is loaded, you can customize the browser caching behavior as follows

LoadModule expires_module modules/
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 before mod_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/

<IfModule mod_deflate.c>
   AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css application/javascript
   DeflateCompressionLevel 9
   DeflateBufferSize 8096
   DeflateMemLevel 9

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 


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.

Hire us to handle what you want

Hire us through our Fiverr Profile and leave all the complicated & technical stuff to us. Here are some of the things we can do for you:

  • Website migration, troubleshooting, and maintenance.
  • Server & application deployment, scaling, troubleshooting, and maintenance
  • Deployment of Kubernetes, Docker, Cloudron, Ant Media, Apache, Nginx,  OpenVPN, cPanel, WHMCS, WordPress, and more
  • Everything you need on AWS, IBM Cloud, GCP, Azure, Oracle Cloud, Alibaba Cloud, Linode, Contabo, DigitalOcean, Ionos, Vultr, GoDaddy, HostGator, Namecheap, DreamHost, and more.

We will design, configure, deploy, or troubleshoot anything you want. Starting from $10, we will get your job done in the shortest time possible. Your payment is safe with Fiverr as we will only be paid once your project is completed.