{"id":1466,"date":"2010-09-13T09:17:13","date_gmt":"2010-09-13T13:17:13","guid":{"rendered":"http:\/\/www.webperformanceinc.com\/load_testing\/blog\/?p=1466"},"modified":"2011-10-06T18:14:29","modified_gmt":"2011-10-06T22:14:29","slug":"optimizing-drupal-introduction","status":"publish","type":"post","link":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/2010\/09\/optimizing-drupal-introduction\/","title":{"rendered":"Load Testing Drupal: Introduction"},"content":{"rendered":"<p>At Web Performance, we&#8217;re all about measuring and optimizing web applications.\u00a0 This quarter we decided to test a variety of <a href=\"http:\/\/drupal.org\/\">Drupal<\/a> configurations, starting with the most basic (unpack the drupal tarball into \/var\/www and run) and collecting benchmarks with increasingly sophisticated systems using optimized LAMP stacks and even a dual-server caching configuration.<\/p>\n<p>For our test scenario, we imagined that we had just started a small drupal-based blog when a popular website linked to one of our stories and directed massive traffic onto our server.  These visitors read stories, followed interesting links, and posted comments of their own.  We want to measure:<\/p>\n<ul>\n<li>How many simultaneous users can Drupal support under a given configuration?<\/li>\n<li>What is the bottleneck when Drupal does fail under load?  (CPU, memory, etc)<\/li>\n<li>How does Drupal behave or misbehave under load?  (Do page durations increase?  Do connections time out?  Or do we get a graceful error message?)<\/li>\n<\/ul>\n<p>For our purposes, we considered Drupal to be functioning adequately at a given user level if:<\/p>\n<ul>\n<li>Pages loaded, on average, in less then 4 seconds.<\/li>\n<li>It generated no errors.<\/li>\n<li>We detected no inconsistencies (e.g. users see their own user name while logged in).<\/li>\n<\/ul>\n<p><strong>Step 1:<\/strong> Server Configuration<\/p>\n<p>We established a Drupal installation on the Amazon Elastic Cloud, which allows us to start and customize a Drupal installation in a matter of minutes.  For these tests we used Amazon&#8217;s &#8220;Large&#8221; 64bit instance, which corresponds roughly to a dual-core machine with 7.5 GB of memory.  We used a stock Fedora Core 8 with Apache and PHP5.<\/p>\n<div id=\"attachment_1421\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/screenshot.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1421\" class=\"size-medium wp-image-1421\" title=\"Our Drupal Site\" src=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/screenshot-300x167.png\" alt=\"Our Drupal Instance, running on the Amazon Cloud\" width=\"300\" height=\"167\" srcset=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/screenshot-300x167.png 300w, https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/screenshot-500x278.png 500w, https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/screenshot.png 1452w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-1421\" class=\"wp-caption-text\">Our Drupal Instance, running on the Amazon Cloud.<\/p><\/div>\n<p><strong>Step 2: <\/strong>Test Cases<\/p>\n<p>We needed to develop a suite of test cases that would be both realistic and easy to reproduce.  To this end, we narrowed our test suite down to two variables: either the user is anonymous or logged in, and either the user follows a link to read more comments or posts a comment of her own.  <a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/2010\/08\/how-to-develop-a-robust-load-testing-plan\/\">Although there are other functions<\/a> that a user (or administrator) may perform, they usually amount to less than 1 percent of all transactions. Web Performance Load Tester allowed us to record our test cases and configure a wait times and unique user login\/password pairs.  We also configured Load Tester to <a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/2010\/09\/testing-tip-make-it-fail\/\">validate<\/a> responses from the server, meaning that Load Tester would monitor whether or not the information returned from the server was consistent with what a user would expect to see.<\/p>\n<div id=\"attachment_1422\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/drupal-in-load-tester.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1422\" class=\"size-medium wp-image-1422\" title=\"Drupal Test Case\" src=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/drupal-in-load-tester-300x170.png\" alt=\"A specific step in a Drupal test case, in Load Tester\" width=\"300\" height=\"170\" srcset=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/drupal-in-load-tester-300x170.png 300w, https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/drupal-in-load-tester-500x284.png 500w, https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/drupal-in-load-tester.png 1337w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-1422\" class=\"wp-caption-text\">A specific step in a Drupal test case, in Load Tester.<\/p><\/div>\n<p><strong>Step 3:<\/strong> Load Testing<\/p>\n<p>We then configured Web Performance Load Tester to launch several remote <em>load engines<\/em>, dedicated servers or Amazon cloud instances that generate traffic to our Drupal instance.  We configured our load test to ramp up, starting with a very small number of users and increasing over time until our Drupal server fell apart under load.  Load Tester randomizes the timing of the tests and collects metrics on relevant statistics such as page durations, number of errors, and bandwidth.  In a well performing system, bandwidth scales with the number of users, page durations remain roughly constant, and the number of errors is zero.<\/p>\n<div id=\"attachment_1423\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/drupal-broken-under-load.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1423\" class=\"size-medium wp-image-1423\" title=\"Drupal Failing Under Load\" src=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/drupal-broken-under-load-300x214.png\" alt=\"Our Drupal server fails under significant load. Can we make it faster?\" width=\"300\" height=\"214\" srcset=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/drupal-broken-under-load-300x214.png 300w, https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/drupal-broken-under-load-500x357.png 500w, https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/drupal-broken-under-load.png 1593w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-1423\" class=\"wp-caption-text\">Our Drupal server fails under significant load. Can we make it faster?<\/p><\/div>\n<p><strong>Step 4:<\/strong> Analysis<\/p>\n<p>Once our load test is complete, we import Web Performance Advanced Server Analysis Agent logs.  These logs contain counters for CPU usage, memory, disk I\/O and other pertinent metrics.  Load Tester correlates all of these metrics by user level and time index.  When we saw that our baseline Drupal installation exhibited 100% CPU usage and spiking page durations at 200 simultaneous users, we knew that the system was limited to about 150 users and that we needed to optimize Drupal to be less processor-intensive.<\/p>\n<p><strong>Step 5<\/strong>: Results<\/p>\n<p>We were able to improve the performance of our baseline installation by more than 10 times!\u00a0 To learn more, read our follow-up articles:<\/p>\n<ul>\n<li>Drupal Case Studies part 2: <a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/2010\/09\/optimizing-drupal-from-baseline-drupal-to-the-pantheon-drupal-platform\/\">From baseline Drupal to the Pantheon Drupal Platform<\/a><\/li>\n<li>Drupal Case Studies part 3: <a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/2010\/11\/aicache-and-drupal-a-case-study\/\">aiCache and Drupal<\/a><\/li>\n<\/ul>\n<p>&#8212; Lane, Engineer at Web Performance<\/p>\n","protected":false},"excerpt":{"rendered":"<p>At Web Performance, we&#8217;re all about measuring and optimizing web applications.\u00a0 This quarter we decided to test a variety of <a href=\"http:\/\/drupal.org\/\">Drupal<\/a> configurations, starting with the most basic (unpack the drupal tarball into \/var\/www and run) and collecting benchmarks with increasingly sophisticated systems using optimized LAMP stacks and even a dual-server caching configuration.<br \/>\nFor our test scenario, we imagined that we had just started a small drupal-based blog when a popular website linked to one of our stories and directed massive traffic onto our server.  These visitors read stories, followed interesting links, and posted comments of their own.  We &hellip; <a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/2010\/09\/optimizing-drupal-introduction\/\">Continue reading &raquo;<\/a><\/p>\n","protected":false},"author":53,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[40,131],"tags":[91,92,13],"class_list":["post-1466","post","type-post","status-publish","format-standard","hentry","category-case-studies","category-drupal-2","tag-drupal","tag-optimization","tag-performance"],"_links":{"self":[{"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/posts\/1466","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/users\/53"}],"replies":[{"embeddable":true,"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/comments?post=1466"}],"version-history":[{"count":20,"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/posts\/1466\/revisions"}],"predecessor-version":[{"id":2711,"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/posts\/1466\/revisions\/2711"}],"wp:attachment":[{"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/media?parent=1466"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/categories?post=1466"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/tags?post=1466"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}