Not a member yet? Register now and get started.

lock and key

Sign in to your account.

Account Login

Forgot your password?

tune apache performance using mpm prefork module

There could be many reasons why your website performance is poor, one of them can possibly be that Apache is not coping with the load. Below you’ll find ready to consume configuration to make Apache performance better using the Apache MPM prefork module.

apache logo

To do this, just include the below lines into your httpd.conf apache configuration file:

<IfModule mpm_prefork_module>
StartServers 2
MinSpareServers 2
MaxSpareServers 5
MaxClients 200 #must be customized
ServerLimit 200 #must be customized
MaxRequestsPerChild 100

KeepAlive Off

Some explanations are here:

  • StartServers – this is how many apache instances should start at the very beginning when apache is started. I set it to 2, and it works fine for me.


  • MinSpareServers – minimum number of spare servers that should be running waiting for potential requests. MinSpareServers=2 worked fine for me too.


  • MaxSpareServers – maximum number of spare servers that should be running waiting for potential requests, obviously >= MinSpareServers. In my working example MaxSpareServers=5.


  • MaxClients & ServerLimit. You can use this shell script to determine an average amount of memory consumed by one Apache process. In addition to that it’ll show total amount of memory consumed by all Apache processes. Just unzip and execute as follows:




    The output will be something like that:

    Apache Memory Usage (MB): 1372.6
    Average Proccess Size (MB): 54.9041

    Try to execute it several times to compare the numbers; good results will be shown when server is under a heavy load. Now when you know average amount of memory consumed by Apache and total amount of memory of your server, it is possible to calculate value to be used for MaxClients setting. For example, if in average one your Apache process consumes 50MB RAM and server RAM is 2GB, and you want to leave 512MB for the rest processes, then:
    MaxClients = (2GB – 512MB)/50MB = 30.72 ~ 30.
    ServerLimit is, as I understand, the same thing, but while MaxClient setting can be changed on the go without a need to restart Apache, for new ServerLimit value to take effect Apache restart is required. MaxClients should always be <= ServerLimit. To make it easy, I set ServerLimit = MaxClients calculated by above formula.


  • By default MaxRequestsPerChild = 0, which means that httpd process will never expire. However, it can happen that there are some memory leaks in your PHP scripts (especially if you are using lot’s of third-party contributed modules). To protect yourself from accidental memory leaks, you can set how many requests should be processed by Apache process before it dies. In my example I used MaxRequestsPerChild = 100 and it worked fine. You can experiment to find a value that suits you better.


  • KeepAlive directive description is pretty straight forward on Apache site. If KeepAlive is On, it allows multiple requests to be sent over the same TCP connection, which can boost site performance up to 50% for some sites. This mostly works for pages that have lot’s of images. However, I’ve noticed that it can lead to the situation when processes never die and that can load the server a lot. Instead, I’m using a proxy server to serve images and other static content (I’ll make another post to clarify it) and in my configs KeepAlive is set to Off.
  1. Mark P09-21-12

    Your maths looks wrong:

    MaxClients = (2048MB – 512MB)/50MB = 30.7 ~ 30

    • Olga09-24-12

      Good point! Thank you for the feedback. The article was corrected 🙂

  2. Demon09-27-12

    Thanks you for the great tutorial, finaly one that explains it in human lang and a calculation to get started… Helped me prevent crashes and memory usage from apache whent down with about 60%!

    • Olga10-01-12

      I’m happy someone found it useful!

      • mdhande06-06-14

        Could you please provide me the script for AIX oprating system ?

  3. Jean-Sebastien Morisset11-20-12


    I came across your page a few weeks ago when I needed to tune some apache web servers for a client. Your script is nice, but it doesn’t take into account the shared memory each process uses. I’m surprised that I couldn’t find anything to analyze a running web server and it’s config, so ended up writing my own. 😉 You can find the weblog entry here, and the Google Code page here

    Enjoy! 🙂


    • Olga11-20-12

      Oh wow, looks like you invested lot’s of time into this! Thank you for sharing, will definitely check it out.

    • Jan03-06-14

      Thanks for the script, very useful.

  4. Dave02-16-13

    Newb question, how does MaxClients & ServerLimit relate to how many people can get on your site?

    For instance, if it’s set to only 30, does that severely limit the traffic?

    Does that mean only 30 people can connect at one time?

    I’m trying to wrap my head around all this, lol.

    I also see, for me, that my server load is high, but memory used is low. Would that at all be related to these settings?

    Would increasing use more memory and than lessen the load on the server?

    Thanks. 🙂

    • Olga04-24-13

      Hi Dave,

      That has been a while since you posted this, so most probably you’ve already figured that out. Just in case…

      From official apache documentation: The MaxClients directive sets the limit on the number of simultaneous requests that will be served. So basically yes, if you set MaxClients to 30, apache would only be able to execute 30 requests _at the same moment of time_. So the actual thing would be to understand (a) how much requests do you usually have at the peak time, (b) what your hardware is, and (3) how much memory an average request consumes. Then you’ll be able to figure out if your current hardware can do the job!

  5. Slavi03-16-13


    just want to mention in my case (CentOS) the process was called httpd so I had to tweak the code a little.

    ps -ylC httpd | awk ‘{x += $8;y += 1} END {print “Apache Memory Usage (MB): “x/1024; print “Average Proccess Size (MB): “x/((y-1)*1024)}’


    • Olga04-24-13

      Good catch! Basically, the script can be easily adjusted to check memory consumption for any other process, not only apache (i.e. nginx, mysqld or whatever).

  6. Mudassir Aftab03-25-13

    My Site has daily 4000 traffic , it reached to 6000 on weekend. Also i hv 3.5 GB RAM and 16 core virtual machine on Citrix. I gave full priority of this machine on Citrix.

    please suggest what settings should i use

    Apache Memory Usage (MB): 6737.74
    Average Proccess Size (MB): 26.951

    current MPM settings

    StartServers 16
    MinSpareServers 16
    MaxSpareServers 32
    ServerLimit 1024
    MaxClients 1024
    MaxRequestsPerChild 50000

    • Olga04-24-13

      Hi Mudassir,

      It has been a while since you posted this, so most probably you have already sorted things out.

      Daily 4000-6000 is not that big a number considering your hardware and Average Process Size. I’m not familiar with what is included into Citrix package you are using (i.e., in addition to the apache, what other processes have to get resources), but how did you get he ServerLimit value? Assuming you have 3.5Gb RAM, with, let’s say 512Mb left for the system, and 3Gb for apache, the formula would be:

      3*1024Mb / 27 Mb = 113

      In your example you have set ServerLimit to 1024, that is too high. Even 113 is high, depending on what other processes are running (i.e. you would want to give more memory to other processes as well).

      All above is just from my personal experience, which means this is not guaranteed to be 100% correct.

  7. Kevin M05-11-13

    That was good one.

    Helpful for troubleshooting 🙂 ,

    Thanks Olga , keep it up…

    • Olga05-13-13

      You are very welcome!

  8. Ashok Kumar05-16-13


    Please let me know if we have 50GB in server and i want to use 30GB RAM for apache and 120MB using per process.

    what is max client and MaxKeepAliveRequests


    • Olga05-16-13

      Hi Ashok,

      Regarding the MaxClients you can use the formula above:

      30*1024 / 120 = 256, which means that your server should be able to handle 256 apache processes of 120MB each. You can use this value as a starting one, watch your server performance and tune the value based on your observations.

      Regarding MaxKeepAliveRequests, there is a good article here, that explains the parameter use:

  9. e8hfff05-21-13

    I just deployed these values for a 2GB virtual server;

    StartServers 2
    MinSpareServers 1
    MaxSpareServers 18
    MaxClients 75
    ServerLimit 256
    MaxRequestsPerChild 100

    • e8hfff05-21-13

      for a mpm_prefork_module.
      (ap =apache)
      StartServers = how many os ap threads to start
      MinSpareServers = how many os ap theads waiting ready
      MaxSpareServers = limit on SpareServers/total ap os trheads
      MaxClients = max tasks per thread (child server processes)
      ServerLimit = cap on tasks for all os ap threads. (Prefork default = 256)
      MaxRequestsPerChild = max request-connections for a task. (0 = ∞ but risks memory blowout, especially on DDoS)

    • e8hfff05-21-13

      Best thing is to tweak the settings of MaxSpareServers as when you change values the threads will perform differently and therefore have different memory expectations.

      Once I put in my settings my mem use per thread went from 79MB to 158MB. So (2048 – 512) / 150 = 10 thread suggestion. I’m going to now set MaxSpareServers to 12 to get a 30% end sweet spot based on the differential between 18 and 10.

  10. sorabh10-04-13

    Hi –
    I have a real problems with my Apache in load and performance test.
    my settings are

    StartServers 100
    MinSpareServers 30
    MaxSpareServers 100
    MaxClients 1000
    MaxRequestsPerChild 0

    we need to test for 4000 users.
    we are having 4 Front end apache, all having same conf and hardware.
    Ram – 4 GB,2 core, 50 GB storage.
    Any help with be immensely appreciated.

    • sorabh10-04-13

      StartServers 100
      MinSpareServers 30
      MaxSpareServers 100
      MaxClients 1000
      MaxRequestsPerChild 0


      • Olga10-04-13

        Hi Sorabh,

        Did you run the script to determine how much memory does one apache process consume on average?

  11. andrew lorien11-03-13

    and here’s a version of that handy script which works on Solaris 10:

    ps -A -o rss,args |grep http|awk ‘{x += $1;y += 1} END {print “Apache Memory Usage (MB): “x/1024; print “Average Proccess Size (MB): “x/((y-1)*1024)}’

  12. Sebastian04-10-14

    Thanks a lot

  13. Leo05-23-14

    This one is helpful…

  14. hao198709-19-14

    nice article, i have a simple question:
    i was setting my server wrong by having a large MaxClients than it should be, and the server is frequently down because of swapping memory… on the log, i cant really remember. So my question is how this swapping memory works to slow down or crashing the server ?

  15. Ritesh02-27-15

    At my server having 200000 to 300000 trafic regular & We Need to increase more traffic on my server So what will be the best mpm setting for apache prefork & worker …Thanks in advanced

  16. Vijay Kr02-28-15

    Hi Olga,
    First of all thanks to writing this post, its very helpfull. Accordinf to shell my result is :
    Apache Memory Usage(MB): 2588.83
    Average Proccess Size (MB): 10.0733

    I have 30GB RAM with SSD hard disk. I want to give 25GB dedicately at apache. so i had below mention configuration but getting error while restart the apache2 service.
    Please help me out from this stuff. We are already live from today n site is loading very slow.

    ERROR :
    sudo /etc/init.d/apache2 restart
    * Restarting web server apache2 AH00180: WARNING: MaxRequestWorkers of 2500 exceeds ServerLimit value of
    256 servers, decreasing MaxRequestWorkers to 256.
    To increase, please see the ServerLimit directive.

    my configuration :

    StartServers 50
    MinSpareServers 50
    MaxSpareServers 100
    MaxRequestWorkers 2500
    #MaxRequestWorkers 150
    MaxConnectionsPerChild 500
    #MaxConnectionsPerChild 0

    KeepAlive On

    Thanks , hoping reply asap.
    Vijay Kr

  17. ALTR06-11-15

    We ran our sites on DO vps. 2 servers / 1Gig Ram; 1 Cpu core /

    StartServers 2
    MaxSpareServers 16
    MaxRequestWorkers 150
    MaxConnectionsPerChild 0

  18. Ayman Qaidi10-17-15

    thanks for this
    but i am getting error while run your script

    [/downloads]# sh
    Apache Memory Usage (MB): 0
    awk: (FILENAME=- FNR=1) fatal: division by zero attempted

    • Olga11-24-15

      Most probably you don’t have apache running!

      • Misty Jhones11-26-15

        Olga! Thanks for your informative feedbacks. I really want to appreciate your work. Your calculations and observations are awesome.

        Thanks for your guidance.

  19. Jonas Berg05-10-16

    I got 32 GB RAM total on a server used for a bunch of PHP+mySQL sites.

    Apache Memory Usage: 3 GB
    Average Process Size: 20 MB

    MPM Prefork:

    ServerLimit 500
    MaxClients 500
    StartServers 10
    MinSpareServers 10
    MaxSpareServers 30
    MaxRequestWorkers 256
    MaxConnectionsPerChild 200

    Please suggest changes.

  20. Addams Scrub01-04-17

    Nice article and great ps script, for those who can’t use the script, replace ‘apache2’ with the named of your apache daemon. Ex: httpd, apache, etc.

  1. Install latest apache on CentOS - how to? - full tutorial11-12-16