httpd-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sander Temme <>
Subject Re: [users@httpd] How does Prefork work?
Date Fri, 29 May 2009 05:20:07 GMT

On May 28, 2009, at 12:55 PM, CrystalCracker wrote:

> Thanks a lot for the response.
> I will do some ab and siege tests to verify it, but I am trying to
> conceptually understand it first.
> <IfModule prefork.c>
> StartServers         5
> MinSpareServers   5
> MaxSpareServers  20
> MaxClients            250
> MaxRequestsPerChild  4000

This seems way low: you would be killing off children after they  
handled 4,000 connections (connections, not requests making this a  
slight misnomer).  Unless you have something that is leaking memory  
like a sieve, you can raise this significantly or omit it alltogether.

MaxClients is also a misnomer: see below.

> </IfModule>
> I have at least 20 active apache threads (ps -ef | grep httpd),  
> average is
> about 40 threads and goes upto 70 at the peak. Does the above  
> setting sounds
> resonable?

Besides the above: sure.  Apache is quite apt at managing its pool of  
children.  According to some performance lore, memory allocation might  
happen more efficiently if you start your maximum number of children  
at startup and leave them running.  So,

StartServers 250
MinSpareServers 0
MaxSpareServers 250
MaxClients 250

and no MaxRequestsPerChild (if you have no memory leaks).  Doug's note  
on memory usage is spot-on: make sure you never run out of physical  
RAM by limiting that MaxClients value.  Note that mod_perls or mod_php  
can make child processes right big.

> Doug Bell-4 wrote:
>> On May 27, 2009, at 11:14 PM, CrystalCracker wrote:
>>> Can anyone explain me how exactly prefork works?

Not really, but I can have a stab.

The parent process, which typically runs as root, binds to a socket  
(usually port 80 or 443).  It spawns children, which inherit the open  
file descriptor for the socket, and change uid and gid to the  
unprivileged user and group.  The children construct a pollset of the  
listener file descriptors (if there is more than one listener) and  
watch for activity on it/them. If activity is found, the child calls  
accept() on the active socket and handles the connection.  When it is  
done with that, it returns to watching the pollset (or listener file  

Since multiple children are active and they all inherited the same  
socket file descriptor(s), they will be watching the same pollset.  An  
accept mutex allows only a single child to actually watch the pollset,  
and once that has found an active socket it will unlock the mutex so  
the next child can start watching the pollset.  If there is only a  
single listener, that accept mutex is not used and all children will  
hang in accept().

Children record in a shared memory area (the scoreboard) when they  
last served a request.  Idle children may be killed by the parent  
process to satisfy MaxSpareServers.  If too few children are idle, the  
parent will spawn children to satisfy MinSpareServers.

On a quiet server, arrival of a new connection will be relatively  
scarce, and most children will be camping on the accept mutex, or in  
accept().  On a busy server, the poll or naked accept() will return  
immediately and few if any children are idle.  On an extremely busy  
server, the parent will keep spawning children until it hits  
MaxClients.  Arriving connections will back up in the kernel before  
they are accepted by child processes (see the ServerBacklog  
directive).  This is why MaxClients is a misnomer: it *only* applies  
to the number of child processes spawned and does not take into  
account either the backlog, or the fact that most HTTP traffic is  
short-lived and bursty, and clients will make many short-lived  
requests that can be handled by any of the child processes.

There is of course more to it, but this is pretty much what the  
Prefork MPM does.


>>> StartServers 2
>>> MaxClients 150
>>> MinSpareThreads 25
>>> MaxSpareThreads 75
>>> ThreadsPerChild 25
>>> ServerLimit 16
>> Prefork works by spawning one process to handle one connection. So
>> here, Apache can spawn a maximum of 150 httpd processes (MaxClients  
>> is
>> maximum number of concurrent connections, which in prefork works out
>> to number of processes).
>>> I think I got confused between the terms - server, process and
>>> thread. If
>>> prefork is a single thread process, what does that ThreadsPerChild
>>> mean for
>>> prefork?
>> Prefork is not threaded, so the thread config values do not apply.
>>> Lets say, I wan't to support 250 active sessions logged into my
>>> site, what would be a tentative settings to meet the load?
>> "Active sessions" is difficult to measure. Let's say a person  
>> requests
>> a page which takes 10 seconds, then looks at it for 20 seconds (on
>> average). This means that you need one httpd process for three users
>> (the other two people using the 20 seconds the first user isn't  
>> using).
>> So to get 250 users from these assumptions, we need MaxClients 74.
>> I would use "siege" to measure your performance. It has settings for
>> how many concurrent users, and can attempt to simulate randomness and
>> "user is reading the page" time.
>> Doug Bell -- Senior Developer, Plain Black Corp.
>> [ ]
>> ---------------------------------------------------------------------
>> The official User-To-User support forum of the Apache HTTP Server  
>> Project.
>> See <URL:> for more info.
>> To unsubscribe, e-mail:
>>   "   from the digest:
>> For additional commands, e-mail:
> -- 
> View this message in context:
> Sent from the Apache HTTP Server - Users mailing list archive at  
> ---------------------------------------------------------------------
> The official User-To-User support forum of the Apache HTTP Server  
> Project.
> See <URL:> for more info.
> To unsubscribe, e-mail:
>   "   from the digest:
> For additional commands, e-mail:

Sander Temme
PGP FP: 51B4 8727 466A 0BC3 69F4  B7B8 B2BE BC40 1529 24AF

View raw message