TAG | Business Transactions
We all know performance is important, but performance tuning is too often an afterthought. As a result, taking on a performance tuning project for a slow application can be pretty intimidating – where do you even begin? In this series I’ll tell you about the strategies and technologies that (in my experience) have been the most successful in improving PHP performance. To start off, however, we’ll talk about some of the easy wins in PHP performance tuning. These are the things you can do that’ll get you the most performance bang for your buck, and you should be sure you’ve checked off all of them before you take on any of the more complex stuff.
Why does performance matter?
The simple truth is that application performance has a direct impact on your bottom line:
Follow these simple best practices to start improving PHP performance:
One of the easiest improvements you can make to improve performance and stability is to upgrade your version of PHP. PHP 5.3.x was released in 2009. If you haven’t migrated to PHP 5.4, now is the time! Not only do you benefit from bug fixes and new features, but you will also see faster response times immediately. See PHP.net to get started.
- Installing the latest PHP on Linux
- Installing the latest PHP on OSX
- Installing the latest PHP on Windows
Once you’ve finished upgrading PHP, be sure to disable any unused extensions in production such as xdebug or xhprof.
Use an opcode cache
PHP is an interpreted language, which means that every time a PHP page is requested, the server will interpet the PHP file and compile it into something the machine can understand (opcode). Opcode caches preserve this generated code in a cache so that it will only need to be interpreted on the first request. If you aren’t using an opcode cache you’re missing out on a very easy performance gain. Pick your flavor: APC, Zend Optimizer, XCache, or Eaccellerator. I highly recommend APC, written by the creator of PHP, Rasmus Lerdorf.
Many developers writing object-oriented applications create one PHP source file per class definition. One of the biggest annoyances in writing PHP is having to write a long list of needed includes at the beginning of each script (one for each class). PHP re-evaluates these require/include expressions over and over during the evaluation period each time a file containing one or more of these expressions is loaded into the runtime. Using an autoloader will enable you to remove all of your require/include statements and benefit from a performance improvement. You can even cache the class map of your autoloader in APC for a small performance improvement.
Optimize your sessions
While HTTP is stateless, most real life web applications require a way to manage user data. In PHP, application state is managed via sessions. The default configuration for PHP is to persist session data to disk. This is extremely slow and not scalable beyond a single server. A better solution is to store your session data in a database and front with an LRU (Least Recently Used) cache with Memcached or Redis. If you are super smart you will realize you should limit your session data size (4096 bytes) and store all session data in a signed or encrypted cookie.
- Encrypting PHP sessions with Suhosin
- Storing sessions in Memcached
- Using a database to persist sessions
Use a distributed data cache
Applications usually require data. Data is usually structured and organized in a database. Depending on the data set and how it is accessed it can be expensive to query. An easy solution is to cache the result of the first query in a data cache like Memcached or Redis. If the data changes, you invalidate the cache and make another SQL query to get the updated result set from the database.
There are many use cases for a distributed data cache from caching web service responses and app configurations to entire rendered pages.
Do blocking work in the background
Often times web applications have to run tasks that can take a while to complete. In most cases there is no good reason to force the end-user to have to wait for the job to finish. The solution is to queue blocking work to run in background jobs. Background jobs are jobs that are executed outside the main flow of your program, and usually handled by a queue or message system. There are a lot of great solutions that can help solve running backgrounds jobs. The benefits come in terms of both end-user experience and scaling by writing and processing long running jobs from a queue. I am a big fan of Resque for PHP that is a simple toolkit for running tasks from queues. There are a variety of tools that provide queuing or messaging systems that work well with PHP:
I highly recommend Wan Qi Chen’s excellent blog post series about getting started with background jobs and Resque for PHP.
Leverage HTTP caching
HTTP caching is one of the most misunderstood technologies on the Internet. Go read the HTTP caching specification. Don’t worry, I’ll wait. Seriously, go do it! They solved all of these caching design problems a few decades ago. It boils down to expiration or invalidation and when used properly can save your app servers a lot of load. Please read the excellent HTTP caching guide from Mark Nottingam. I highly recommend using Varnish as a reverse proxy cache to alleviate load on your app servers.
Optimize your favorite framework
Deep diving into the specifics of optimizing each framework is outside of the scope of this post, but these principles apply to every framework:
- Stay up-to-date with the latest stable version of your favorite framework
- Disable features you are not using (I18N, Security, etc)
- Enable caching features for view and result set caching
Learn to how to profile code for PHP performance
Xdebug is a PHP extension for powerful debugging. It supports stack and function traces, profiling information and memory allocation and script execution analysis. It allows developers to easily profile PHP code.
WebGrind is an Xdebug profiling web frontend in PHP5. It implements a subset of the features of kcachegrind and installs in seconds and works on all platforms. For quick-and-dirty optimizations it does the job. Here’s a screenshot showing the output from profiling:
XHprof is a function-level hierarchical profiler for PHP with a reporting and UI layer. XHProf is capable of reporting function-level inclusive and exclusive wall times, memory usage, CPU times and number of calls for each function. Additionally, it supports the ability to compare two runs (hierarchical DIFF reports) or aggregate results from multiple runs.
AppDynamics is application performance management software designed to help dev and ops troubleshoot problems in complex production apps.
Get started with AppDynamics today and get in-depth analysis of your applications performance.
PHP application performance is only part of the battle
Now that you have optimized the server-side, you can spend time improving the client side! In modern web applications most of the end-user experience time is spent waiting on the client side to render. Google has dedicated many resources to helping developers improve client side performance.
See us live!
Here at AppDynamics we’re very proud of how easy our solution is to deploy and maintain. We also tout the fact that in many cases there is no configuration required to gain the insight needed to solve complex application problems. All of this is absolutely true, but does it mean that AppDynamics doesn’t have enough functionality to support complex deployments that make little to no use of common frameworks? Absolutely not! But don’t take our word for it, see for yourself in this presentation by Orbitz (Geoff Kramer and Nick Jasieniecki) at one of our Chicago User Group meetings. In case you don’t know what Orbitz does I think this quote from Geoff Kramer sums it up quite well… “Orbitz unlocks the joy of travel for our customers. You can’t do that if you are having site problems.”
If you don’t have 50 minutes to spare right now I will summarize the videos key points in this blog post.
I have yet to meet anyone in Dev or Ops who likes alerts. I’ve also yet to meet anyone who was fast enough to acknowledge an alert, so they could prevent an application from slowing down or crashing. In the real world alerts just don’t work, nobody has the time or patience anymore, alerts are truly evil and no-one trusts them. The most efficient alert today is an angry end user phone call, because Dev and Ops physically hear and feel the pain of someone suffering
Why? There is little or no intelligence in how a monitoring solution determines what is normal or abnormal for application performance. Today, monitoring solutions are only as good as the users that configure them, which is bad news because humans make mistakes, configuration takes time, and time is something many of us have little of.
Its therefore no surprise to learn that behavioral learning and analytics are becoming key requirements for modern application performance monitoring (APM) solutions. In fact, Will Capelli from Gartner recently published a report on IT Operational Analytics and pattern based strategies in the data center. The report covered the role of Complex Event Processing (CEP), behavior learning engines (BLEs) and analytics as a means for monitoring solutions to deliver better intelligence and quality information to Dev and Ops. Rather than just collect, store and report data, monitoring solutions must now learn and make sense of the data they collect, thus enabling them to become smarter and deliver better intelligence back to their users.
Change is constant for applications and infrastructure thanks to agile cycles, therefore monitoring solutions must also change so they can adapt and stay relevant. For example, if the performance of a business transaction in an application is 2.5 secs one week, and that drops to 200ms the week after because of a development fix. 200ms should become the new performance baseline for that same transaction, otherwise the monitoring solution won’t learn or alert of any performance regression. If the end user experience of a business transaction goes from 2.5 secs to 200ms, then end user expectations change instantly, and users become used to an instant response. Monitoring solutions have to keep up with user expectations, otherwise IT will become blind to the one thing that impacts customer loyalty and experience the most.
Peter Drucker proclaimed: “If you can’t measure it, you can’t manage it.” Do you know what’s “normal” for your mission-critical application? Actually, wait a second–with Halloween having just finished up, maybe the following Young Frankenstein reference is more appropriate. Whenever I focus on the word “normal,” the first thing that pops into my head (pardon the pun) is that famous scene from Young Frankenstein:
DR. FREDERICK FRANKENSTEIN: Abby Normal?
IGOR: I’m almost sure that was the name.
DR. FREDERICK FRANKENSTEIN: [chuckles] Are you saying that I put an abnormal brain into a seven and a half foot long, fifty-four inch wide GORILLA?
[grabs Igor and starts throttling him]
DR. FREDERICK FRANKENSTEIN: Is that what you’re telling me?