Optimized WAMP Setting For Increased Performance

Posted: 2015-08-20 22:55:40

OS Layer

If your OS is a server edition, does not contain other software (such as active anti-virus programs), has a clean network layer, and has network drivers that are not broken, enable the use of the OS’s abilities to speed up memory access, file delivery, and network access.

Enable the use of:

1. Sending static files to the client without reading those files by using Apache directive EnableSendfile.

EnableSendfile On

2. Memory mapped files to provide a more direct access to files by using Apache directive EnableMMAP.

EnableMMAP On

This works better for delivering larger files, than smaller files.

3. OS API AcceptEx() rather than Accept() to optimize socket handling, and recycle sockets between connections, by using Apache directive AcceptFilter.

<IfVersion < 2.3>
  # Make sure this is commented out
  # Win32DisableAcceptEx
<IfVersion >= 2.3.3>
  AcceptFilter http data
  AcceptFilter https data

All the above settings are stored in file –

Save file and restart Apache for changes to take effect.

These setting can create operational problems such as: random issues with pages not being loaded or being loaded half way, Apache crashes, and in some cases performance degradation. WampDeveloper Pro defaults to turning all of these settings Off for stability and compatibility reasons, with the possible trade-off in performance.

Interfering Software

To prevent slowdowns, make sure to exclude the Apache, PHP, and MySQL processes and WAMP folder from anti-virus (and related software) scanning. The database files, the temporary folder files, and the log folder files, can update and change often – and any type of watching/reading/locking interference from outside applications will create issues.

The Windows Firewall has also been known to add a latency delay (0.5s) to requests in some circumstances (e.g., if IPv6 is enabled).

WAMP Layer

There are some general Apache, MySQL, and PHP settings that deal with resources that you can increase. But this should only be done on a server that is experiencing increasing loads (otherwise – on a web-dev box, it will just make your system more sluggish)…

Apache Worker Count

ThreadsPerChild is the number of threads Apache will spin up when it starts. Each thread can handle a separate simultaneous client.

Generally there would not be a realistic situation (for a typical website and access pattern) where more than 128 workers would be needed for a single server… If all other settings are tuned in, 128 threads can handle about 100 different clients all accessing the server within about a 3 second span. That’s allot of traffic, and a allot of resources.

Raising this value overly too much will just make each additional worker/thread take up resources.

File Config\Apache\extra\httpd-mpm.conf

ThreadsPerChild 96
ThreadLimit 128

If you check Apache’s general error log file and this message is present –

"AH00326: Server ran out of threads to serve requests. Consider raising the ThreadsPerChild setting."

Then the Apache worker count (ThreadsPerChild) should be raised (but not overly too much as each additional worker/thread will take up resources).

Also, if this message is shown –

"AH00358: Child: Process exiting because it reached MaxConnectionsPerChild. Signaling the parent to restart a new child process."

Then increase value of MaxRequestsPerChild.

On the other hand, if this message is not present, decrease the value of MaxRequestsPerChild.

This tells Apache when to recycle its workers/threads – to get rid of the memory leaks. Recycling workers/threads once per day is optimal.

MySQL Cache Size

File \Config\Mysql\my.ini

# Buffer sizes to 1/4 or 1/2 of your RAM
# For MyISAM
key_buffer_size = 512MB
# For InnoDB
innodb_buffer_pool_size = 1000MB

# Log size to 1/4 of the above innodb_buffer_pool_size
innodb_log_file_size = 256MB

The total of these caches and buffers should not exceed 2000MB when using MySQL 32 bit builds as this is about the max usable RAM allocation for a 32 bit process.

Changing the value of ‘innodb_log_file_size’ can cause some older versions of MySQL to fail to start, or for the InnoDB Engine to not load. You’ll need to move out (don’t delete just in case) file(s) Database\ib_logfile0 and ib_logfile1 (if it exists). This is a bit unclean, but if everything was flushed and shut down properly, should not be problematic.

PHP Memory Limit

This is generally not a good idea (and will not help scale the website), and only helps when a script needs more memory because it’s bad at managing it (and is crashing PHP)…

File \Config\Php\php.ini

memory_limit = 1000MB

Generally you don’t want set a value above 2000MB (slightly lower than 2GB / 2048MB) when using PHP 32 bit builds as it:
1) Begins to exhaust the memory space PHP can use (running under a 32 bit process).
2) Has been know to trigger PHP bugs.

Any script needing more than 1024MB is usually indicative of bad memory management or memory leakage by that script.

This is a value PER script.

This setting can also be overridden in the VirtualHost, the website’s .htaccess files, and in the script code itself via ini_set('memory_limit', ...). So it’s important to do a quick search to make sure nothing like that is happening.

If you check PHP’s general error log file and also the specific website’s PHP error log, and this message is present –

"PHP Fatal error: Allowed memory size of xxx bytes exhausted (tried to allocate xxx bytes) in file.php on line xxx."

Then PHP’s “memory_limit” value should be increased from the default of 256MB-512MB to somewhere between 512MB-2000MB (* this value cannot be set higher in 32bit PHP versions).

Enable PHP’s Opcode Cache

File \Config\Php\php.ini, Section: [Zend OPcache]

Un-comment Zend OPcache section. Save file. Restart Apache.

Use PHP’s Zend OPcode to cache PHP scripts as compiled objects.

Caching the PHP script files will alleviate some I/O issues, as the scripts will no longer need to be re-read and re-compiled on every request, and they will now exist as objects in memory. It’s usually good for a 50%-200% increase in handling requests/second, decreasing CPU time by 50%, and lowering script execution time… But that is for a typical wordpress website, and comparable to a system that’s currently maxing out (cpu 99%, requests/second peaked, etc)… Your particular case might be a bit different.

To exclude certain files from caching add paths to blacklist file:

Disable XDebug

File \Config\Php\php.ini, Section: [XDebug]

Make sure XDebug is not loaded, as it will slow everything down considerably (at least 2x).

MySQL Persistent Connections

Disable PHP’s MySQL persistent connections. They are never recommended and can cause all kinds of issues as user numbers increase.

File \Config\Php\php.ini, Section: [MySQL]

; Allow or prevent persistent links.

PHP FCGI Process vs. Apache Module mod_php

If Apache is crashing, try switching to PHP-FCGI, which is known to work better with these scale-related bugs and issues. When PHP-FCGI is used, PHP is ran outside of Apache in its own separate process pool.

True Caching Layer

For everything else, there is only one practical way to increase performance of a server that will produce 2x-10x results…

Use a caching layer such Apache’s mod_cache to temporarily cache output, or a front-end caching reverse proxy setup (e.g., Varnish or Squid).