performance

Setting a max_execution_time limit for PHP CLI

PHP's command line interface doesn't respect the max_execution_time limit within your php.ini settings. This can be both a blessing and a curse (but more often the latter). There are some drush scripts that I run concurrently for batch operations that I want to make sure don't run away from me, because they perform database operations and network calls, and can sometimes slow down and block other operations.

Memory usage - PHP and MySQL locked from runaway threads
Can you tell when the batch got backlogged? CPU usage spiked to 20, and threads went from 100 to 400.

I found that some large batch operations (where there are hundreds of thousands of items to work on) would hold the server hostage and cause a major slowdown, and when I went to the command line and ran:

$ drush @site-alias ev "print ini_get('max_execution_time');"

Announcing Server Check.in - A simple, inexpensive website monitoring service

Server Check.in Logo

Midwestern Mac is proud to announce Server Check.in—a website and server monitoring service that is inexpensive and easy to use.

Server Check.in was built because, while there are some really powerful and flexible monitoring solutions out there, like Pingdom (we love Pingdom!), there aren't any really simple and inexpensive services that are better for individuals and small businesses who don't have a budget for more expensive and involved solutions, but still need to know when their servers or sites go down.

Server Check.in offers many features like free, unlimited SMS messages for outage notices, email notifications, and server latency monitoring. It will check on up to five servers or websites every fifteen minutes, and notify you when the servers and sites go down.

Sign up here for only $15/year—that's just $1.25 per month!

APC Caching to Dramatically Reduce MySQL traffic

One Drupal site I manage has seen MySQL data throughput numbers rising constantly for the past year or so, and the site's page generation times have become progressively slower. After profiling the code with XHProf and monitoring query times on a staging server using Devel's query log, I found that there were a few queries that were running on pretty much every page load, grabbing data from cache tables with 5-10 MB in certain rows.

The two main culprits were cache_views and cache_field. These two tables alone contained more than 16MB of data, which was queried on almost every page request. There's an issue on drupal.org (_field_info_collate_fields() memory usage) to address the poor performance of field info caching for sites with more than a few fields, but I haven't found anything about better views caching strategies.

Knowing that these two tables, along with the system cache table, were queried on almost every page request, I decided I needed a way to cache the data so MySQL didn't have to spend so much time passing the cached data back to Drupal. Can you guess, in the following graph, when I started caching these things?

MySQL Throughput graph - munin

Use delegation, threading, and queues to speed up operations

I posted this to my personal site, but I wanted to mention it on this blog, as it's a performance optimization that I use quite often when programming for the web or for native applications: Don't Wait, Delegate! Proper use of threading and queueing.

There are hundreds of ways you can improve your app or website's performance, but few have the potential to improve your app or website's responsiveness as much as queueing or using background processes.

Don't Wait, Delegate! Proper use of threading and queueing

There are hundreds of ways you can improve your app or website's performance, but few have the potential to improve your app or website's responsiveness as much as queueing or using background processes. There are so many complex operations that can be improved by looking at them in a new way. For example:

Not-so-Instant Oil Change

I like changing the oil in my car, but it often takes a bit of time (definitely not an 'instant!'), and involves the following:

  • Drive to auto parts store, pick up oil and oil wrench, and drive back (30 minutes).
  • Jack up front of car on stands (5 minutes).
  • Drain oil into oil pan, remove old filter, prep new filter (5 minutes).
  • Install new filter, refill oil reservoir (2 minutes).
  • Remove jack stands, clean up mess (5 minutes).
  • Drive to oil disposal center with old oil in pan, and drive back (20 minutes).

Total elapsed time: Over 1 hour! Maybe it's worth spending a few extra bucks on an 'instant' oil change to get back 45 minutes of my life.

Getting XHProf working well on Mac OS X Lion

I was inspired today to get XHProf working on my Mac, using MAMP PRO 2.0.5/PHP 5.3.6, after reading @Dave Reid's tweet. Since I'm not leaving for DrupalCon until tomorrow, what else could I do today? There's an excellent article on Lullabot that will help you get 85% of the way towards having XHProf up and running on your Mac, working with your Drupal sites, but there are a few missing pieces and little tips that will help you get XHProf fully-armed and operational.

XHProf Callgraph example
Ooh, pretty visualizations!

Running a Windows XP VM in Parallels (Mac) from a USB Flash Drive

I thought I'd post my experience here, for the benefit of others, because I couldn't find a whole lot of information about this specific use of an external USB flash drive.

I have a MacBook Air with a dainty 128GB SSD drive, so I try to keep large files that I rarely use on external drives. I have plenty of external USB and FireWire storage (over 6 TB), and running VMs in either Parallels or VMWare Fusion works great (very highly performant) off any of these external drives.

However, there's no way I'm going to lug around an external hard drive and USB cable (and maybe power adapter) just so I can test things in Internet Explorer (basically, the only use I have for Windows).

Flash Drive to the Rescue!

I found a cheap 32GB USB flash drive that only sticks out of my MacBook Air half an inch, and copies at a consistent rate of 30MB/second (which is quite sufficient for most tasks). Also, the little drive should have very good read performance, since it's not a spinning platter. Write speed wouldn't be anything to brag about, but writing shouldn't happen all that often when simply opening up Internet Explorer—I hope!

Using apachebench (ab) with Drupal 7 to load test site with authenticated users

apachebench is an excellent performance and load-testing tool for any website, and Drupal-based sites are no exception. A lot of Drupal sites, though, need to be measured not only under heavy anonymous traffic load (users who aren't logged in), but also under heavy authenticated-user load.

Drupal.org has some good tips for ab testing, but the details for using ab's '-C' option (notice the capital C... C is for Cookie) are lacking. Basically, if you pass the -C option with a valid session ID/cookie, Drupal will send ab the page as if ab were authenticated.

Instead of constantly going into the database and looking up session IDs and such nonsense, I have a simple script, which is quite revised from the 2008-era script originally from 2bits that worked with Drupal 5, which will give you the proper ab commands for stress-testing your Drupal site under authenticated user load. Simply copy the attached script (source pasted below) to your site's docroot, and run the command from the command line as follows:

Doing Some Benchmarks - Mac Processor Speed

I currently own or use a variety of Macs, and am approaching the end of a 'cycle' of Mac usage, where I need to decided what Mac I'd like to purchase next. Currently, I'm using a 27" iMac at work, an 11" MacBook Air (from work) for travel, and a 24" iMac at home. They're all great computers in their own right, and using Dropbox, MobileMe, and a couple other helper services, I can operate simultaneously on all three Macs, without any hiccups.

So, I'm thinking about getting a new Mac for hardcore development work (web and app), some graphic design, and possible portability. I have an iPad for lighter computing (reading, browsing, email, videos...), so even though the MacBook Air is probably the best thing to happen to a laptop in a very long time, I'm shying away from it as my primary personal computer.

Drupal 7 Front-End Performance - Shared Hosting Recommendations

Speedometer - BoostedI've spent a lot of time working on making sure my smaller Drupal sites (mostly run on shared hosts or very small VPSes) run lean and mean. This helps the pages load faster, users are happier, and my hosting providers don't have to shut down any of my sites, even when they're under pretty heavy load.

Here are my three recommendations for making your Drupal 7 website run great on a shared (or low-end VPS) host: