SITE SPEED = SUCCESS! Optimizing WordPress from the server up Anthony Somerset
ABOUT• Anthony Somerset – Infrastructure Engineer, W3 EDGE • Manage W3 EDGE servers day to day • Build out Servers and infrastructure for new clients primarily on Amazon Web Services • Supporting existing users of W3 Total Cache plugin • Some work on the W3 Total Cache plugin • Motorsport Nut (the 4 wheel variety!)
ROADMAP• Configuring & Optimizing MySQL (Including general WP based optimizations)• Configuring PHP for efficient memory usage• Installing & Configuring APC – Common Caveats• W3 Total Cache recommended configuration• Questions?
ROOT ACCESS REQUIRED!• You need a dedicated server or VPS to do 90% of the following stuff and root level access• I’m assuming you already have the Web Stack built whether that be LEMP, LAMP etc.• I’m assuming Linux is the OS being used! – Sorry no WAMP here please!• I’m assuming you are comfortable with SSH, command line, Vi/Nano etc.• Recommended Resources (just some of many) • http://www.if-not-true-then-false.com/2011/nginx-and-php-fpm-configuration-and- optimizing-tips-and-tricks/ • https://www.digitalocean.com/community/articles/how-to-install-linux-nginx-mysql- php-lemp-stack-on-ubuntu-12-04 • http://wiki.nginx.org/Wordpress • http://codex.wordpress.org/Nginx
MYSQL TUNING• The DB is often the first bottleneck in WordPress• Config file most commonly located in /etc/my.cnf • Debian/Ubuntu symlinks this to /etc/mysql/my.cnf• Most config options often don’t need a restart (they will have a matching set @@global. Query)• /etc/init.d/mysql reload does not work reliably on all systems – restart is safer• Useful Tools (direct download links to latest version): • Mysqltuner - http://sts.io/mysqltuner • Tuning-primer - http://sts.io/tuningprimer
MYSQL TUNING• Convert MyISAM tables to InnoDB • You lose default WP search (which was never that great) • Some alternative search plugins: • http://wordpress.org/extend/plugins/wordpress-sphinx-plugin/ - you need sphinx installed and running – the plugin can do this though • http://wordpress.org/extend/plugins/google-custom-search/ - requires no extra running software, but does need signing up for at Google• InnoDB scales better because it does row level locking instead of table level locking • This has greater impact for busier sites, lots of wp-admin traffic or lots of comments • InnoDB has better memory caching support than MyISAM – whole DB can be stored in RAM (if you have it available)
MYSQL TUNING• max_connections – make sure its set to the max number of DB connections you see at peak time + 20%• skip_name_resolve – can save up to 20% time on initial connection performance • Caveat – you cannot use hostnames in MySQL user permissions only IP’s • Doesn’t have any effect if you are using MySQL sockets (e.g. localhost) – which are faster than TCP anyway!• query_cache_size – don’t set to more than 128M the cost to clear it above that generally is worse than the performance gained by the larger cache• tmp_table_size, max_heap_table_size – set both to at least size of your largest table (if you have the ram)• innodb_buffer_pool_size – set this to the overall size of your InnoDB tables + 15%
MYSQL TUNING• innodb_file_per_table – great on multi disk Hardware RAID arrays (note, avoid RAID 5 or RAID 6 and variants for MySQL if you can RAID 10 is still fastest with least problems in event of a disk failure)• innodb_flush_method = O_DIRECT – great if you have Hardware raid and Battery backup• innodb_log_file_size = 1024M – stop MySQL before you make this change! Saves file descriptors being used for too many log files• innodb_log_buffer_size = 32M – set this adequately to avoid writing to disk too much but not so high that you could lose a large amount of data in the event of failure• Only enable the Slow log if you are actively debugging – leave it disabled otherwise
MYSQL TUNING - WORDPRESS• Delete Spam comments – don’t just leave them hanging around• Clear out old post/page revisions and limit number of created revisions - http://codex.wordpress.org/Editing_wp-config.php#Post_Revisions• Limit the auto-save interval, useful if you have lots of editors - http://codex.wordpress.org/Editing_wp-config.php#Modify_AutoSave_Interval• Clear out trash posts, can even be automated via wp_cron - http://codex.wordpress.org/Editing_wp-config.php#Empty_Trash• Use an alternative comment system – e.g. Disqus• If a single DB server cant cope then look at DB caching (W3TC) or DB replication (HyperDB or W3TC Enterprise)
TUNING PHP• Config files in various locations depending on the OS and may or may not use an included files based system • Debian/Ubuntu /etc/php5/…. And users/etc/php5/conf.d/ • Red Hat/CentOS /etc/php.ini /etc/php.d/• Generally need to restart PHP service to activate changes (except when using apache/mod_php)• Using an Opcode Cache (like APC) is often where biggest gains are had.• Only enable/compile the minimum modules needed to run your site• Only do the required tasks in WordPress/PHP – e.g. don’t use WP plugins to do site backups – use a proper DB/File backup tool – if you use VaultPress – use the (S)FTP and MySQL connection options to reduce impact on the site code
TUNING PHP• Watch your memory usage – if you consistently need more than 128M memory_limit then look at what parts of your site/code is using large amounts of memory• Don’t extend max_execution_time – if something takes more than 30 seconds to process then something is wrong or should be done outside of the webserver process• Disable WP_Cron and switch it to a system cron task – wp-config.php: define(DISABLE_WP_CRON, true); - reduces number of PHP calls quite a bit and prevents race conditions in PHP on some busier sites – running it at regular defined intervals is more reliable and often more efficient• Remember to set post_max_size and upload_max_filesize for your uploads• Set date.timezone – it will save a warning in your logs which could cause slow downs because of disk writes on busy servers (I have seen this happen!)• If using multiple webservers – then set session.save_handler to use Memcached or similar
INSTALLING APC• APC will generally give biggest gains in PHP (or any other opcode cache)• Debian (assuming using the DotDeb repositories) • apt-get install php5-apc• Red Hat/Centos (use EPEL/Remi for most up to date) • yum install php-pecl-apc• cPanel – use WHM or: • pecl install APC
CONFIGURING APC - CAVEATS• apc.stat = setting to 0 means it wont check for file changes • Means you have to manually clear APC caches • But gives much much more scale to servers by saving on many file system calls• Make sure apc.shm_size is large enough for your cache • APC is known to show nasty errors or just plain white screen a site when it runs out of memory• In rare cases apc.mmap_file_mask set to the /tmp directory can cause an abnormally high number of disk writes setting it to /dev/zero tends to solve the issue• Set TTL’s too low and things don’t get cached for long enough – too high and you might hit a cache full error – setting it to zero means caches get flushed as soon as cache gets full (this is bad)
W3 TOTAL CACHE• The Defaults are only a fail safe – they will not give you the best overall performance• Best config for a single server is not the best for a multi server setup• Page Cache – Use Disk Enhanced for single servers, Memcached for multiple – Nginx/Apache Rewrites are generally much faster than PHP or Memcached but consistency needed when multiple servers in play• Minify – same applies here, Disk for single server, Memcached for multiple• DB – Avoid Disk if you can. Memcached works very well here for both single and multiple server setups – APC is better than file if you don’t have Memcached if you use Disk make sure your Disks are fast – and prefer no caching if your DB is faster than File caching• Object – APC is fastest here, use Memcached if you have to for multiple servers• CDN – Enable it! – origin pull is generally easiest and simplest to manage – make use of any available API’s if we support it (e.g. MaxCDN/NetDNA, Amazon CloudFront)
W3 TOTAL CACHE – BROWSER CACHE• Enable all the options under Browser Cache.• Do Not Process 404s – make sure that any plugins that require WordPress for static files have there files whitelisted – e.g. WordPress SEO by Yoast – sitemap feature requires whitelisting• Prevent caching of objects after settings change – this appends a query string to all static file URL’s allowing you to set very long expires times (the default in W3TC if expires enabled)• If using CDN, make sure to enable the set cookie domain option to make sure new users cant send cookies in requests to your CDN resources• eTags are often not needed for sites using single servers – leave them disabled unless you know they are needed, it reduces the http header response size.
W3 TOTAL CACHE – PAGE CACHE• Enabling cache 404 pages in page cache – this returns a 200 error which can have an adverse effect on SEO use at your peril! Better to make sure your 404 page is efficient in its WP calls and that you generally have no 404’s in the first place• Dont cache pages for logged in users – if you disable this beware of the admin bar appearing for logged out users – with a logged in users username! A good idea to disable the admin bar on the front end when you do this• Cache Feeds if you can – even if you redirect to FeedBurner or similar services, w3tc will purge the feed from its cache every time you update/publish a post• Use a sitemap plugin and prime your cache with the sitemap