January 6, 2012

Drupal Performance Tuning

Performance problems are a bit of an embarrassment of riches. It's great that your site is getting a lot of visitors, but are all those visitors slowing down your site or potentially causing crashes? How do you go about resolving this issue? Unfortunately there's no hard-and-fast answer to performance problems, and examining the shear breadth and depth of the topic would result in the longest and most boring blog post ever. However I will attempt to outline the general strategies you might follow to diagnose and solve problems.

The first step is to consider what part of your site is experiencing problems. A particular page or View, for example, being slow will generally indicate a different set of problems to the entire site feeling sluggish. Another issue to consider is whether it's the backend that's slow, or the front-end. A tool such as Chrome's web inspector can tell you what assets (CSS files, JS files, images) are being loaded, how big they are and how long it is taking, among other useful metrics.

Secondly, it's a good idea to determine what the bottleneck is, if possible. Take a look at the load on your CPU when you notice poor performance as serving complex PHP applications can be quite taxing. You might also want to turn on the Devel module's query log (or the MySQL slow query log) to determine if any queries are taking an exceptional amount of time.

When tuning the performance of a site and its server I'll typically follow a strategy where by I'll implement a number of steps then re-examine performance, before moving on to more gradually more complex solutions if the need arises. On every production Drupal site I'll take the following steps:

  • Enable CSS/JS compression
  • Make sure APC is enabled and properly configured
  • Disable unnecessary modules
  • Clean up as many PHP errors as possible, especially if we're logging with the dblog or syslog modules
  • Make sure the MySQL query cache is enabled and properly configured
  • Sprite images where possible for front-end performance benefits

The aforementioned steps will go a long way to ensuring that your site is performant while having very few, if any, detrimental effects. With that said, sometimes this isn't enough. Fear not, we can go further to attempt to address outstanding issues:

  • Cache expensive or time consuming operations, for example, requesting data from a web service. Drupal makes this simple with cache_set() / cache_get().
  • Turn on additional caching, such as Views or Block, if possible
  • Use the MySQL slow query log and run EXPLAIN on the logged queries. Look for queries which have joins using filesort or temporary tables and determine whether these could be rewritten or sped up with an index.
  • Analyze the traffic pattern. A site with a largely anonymous user base can see a significant benefits from implementing the Boost module or Varnish in to the server stack.
  • Change cache backends. Drupal reads and writes a lot of data from its caches (as it should) so you can see some great speed improvements storing this data in memory (fast!) rather than the database (on the disk, slow!).

We're still just scratching the surface of optimizations that can be made to a website or the server stack, or even the servers themselves. Scaling vertically (using bigger servers) or horizontally (using more servers) are solutions that are often utilized when a site has outgrown its existing server (and sometimes before that point).

If your interest in performance and tuning has been piqued there's a couple of great resources for Drupal. Swing by the High Performance group (http://groups.drupal.org/high-performance) or http://2bits.com/ for a number of helpful tips on how you can improve the performance of your Drupal website.

We'd also be happy to discuss any questions or observations you might have, so feel free to post a comment!