[error] server reached MaxClients setting, consider raising the MaxClients setting
Tuning in general is a complex topic and highly dependent on the use case. Apache HTTP Server can be adapted for many different workloads on many different systems, and these call for varying parameters. Every parameter involves some kind of tradeoff and the preferred choice depends on the situation. This is why, when a customer asks VMware support what seems like a simple question like, "What should MaxClients be?", we have to ask a lot of questions before we can give a helpful response.
The choice of MPM determines how processes are created and thus how limits are set. Typically the operating system only displays RAM and CPU usage per process but processes may vary in size and load depending on ThreadsPerChild and ThreadStackSize (if threaded) and workload.
Note: Remember that actual results depend heavily on traffic, configuration, and OS parameters. You must load-test your server under conditions similar to real-world traffic to determine real performance characteristics.
To determine a rough approximation for server RAM usage, multiply the number of child processes by the amount of resident RAM a process uses (tools like "top" report multiple forms of RAM use - resident is typically the relevant one). Restrict the number of processes (or their thread resources) such that available RAM is never exceeded. Traffic beyond the limit is queued or eventually refused. CPU percentage usage can similarly be approximated and limited.
Example:
Suppose that by using worker, you have set ThreadsPerChild 25 and MaxClients 50 and the two child processes each use 128MB of RAM and 5% of CPU under full load. You can roughly expect 8 children (MaxClients 200 = 25 x 8) to use 1GB of RAM and 40% of CPU under full load.
Under Windows, there is only one child process, so as a rough approximation, assume that RAM and CPU usage is evenly divided among the worker threads. Restrict the number of worker threads such that available RAM and CPU will never be exceeded.
Example:
Suppose using mpm_winnt
you have set ThreadsPerChild 500, and the child process uses 1GB of resident RAM and 5% of CPU under full load. You can roughly expect that increasing ThreadsPerChild to 1000 would increase RAM usage to 2GB and CPU usage to 10% if fully loaded.
Of course, the only way to determine how your system actually performs is to put it into actual usage, or at least test with a load representative of actual usage. Type of usage determines how much RAM and CPU a worker will use and for how long. For example, a server that mainly serves static local content uses resources depending on the size of that content. A server with many heavy-CPU or long-lasting CGI requests needs more severe limits. A server that mainly serves as a proxy consumes little RAM or CPU and in general can support many more workers. Under real world usage, where you may have a variety of requests, a reasonable approach is to start with conservative limits and expand them as needed as long as host resources are not exhausted under peak traffic.
Note: You can change most of these parameters during a graceful restart so that no interruption of service is necessary to test new settings or scale them back. However, ServerLimit and ThreadLimit can not be modified during a graceful restart.
Note: The amount of free RAM reported by the OS may be less than what is actually available, as the OS may use available RAM for caching purposes and can release it as needed. You do not necessarily need to be concerned if free RAM is low. You should be concerned if the host is swapping and if the resident memory used by all processes sums to more RAM than the host has.
Be cautious of configurations that result in lots of child process creation and destruction, as this overhead can become significant for a high-traffic site. Consider two common scenarios:
This setting forces child processes to exit after a number of requests. Ideally this should be set to 0, meaning that a process could persist forever. But with some use cases, processes may become unstable over long usage and it is easier to just restart processes than to find and fix the source of instability. In that case you need to limit MaxRequestsPerChild, but it is critical not to set it too low, especially with mpm_winnt
(which is designed specifically to avoid the overhead of process regeneration). Try a number like 1000000 (one million) to begin with and only lower it if the instability persists.
Apache HTTP Server allows you to specify how many worker processes you want to start with, how many to grow to as a limit, and when to destroy them. Under highly variable traffic on a busy site, the defaults may lead to lots of processes being created, then quickly torn down again when idle, many times over in a short period.
This sort of churn can be very detrimental to performance.
Fortunately, the solution is fairly simple: there's very little reason for an enterprise server to reclaim idle resources so just configure the server to begin with the maximum number of workers and leave it there.
mpm_winnt
this is the behavior regardless.Hopefully the discussion above has given you a basic understanding of how the server handles traffic and you can use this to determine fundamental settings. For common ways to maximize performance, you may want to read and understand the Apache Performance Tuning page, particularly the discussion of AllowOverride, HostnameLookups/DNS, and removing modules. There is no simple trick to just speed up your server, but depending on usage you may find many optimizations.