{"id":2815,"date":"2011-11-16T20:22:19","date_gmt":"2011-11-17T00:22:19","guid":{"rendered":"http:\/\/www.webperformance.com\/load-testing-tools\/blog\/?p=2815"},"modified":"2018-08-09T09:10:43","modified_gmt":"2018-08-09T13:10:43","slug":"what-is-the-fastest-webserver","status":"publish","type":"post","link":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/2011\/11\/what-is-the-fastest-webserver\/","title":{"rendered":"The Fastest Webserver?"},"content":{"rendered":"<p>Looking for the snappiest, fastest web server software available on this here internet?\u00a0 So were we.\u00a0 Valid, independent, non-synthetic benchmarks can be difficult to find.\u00a0 Of course, we all know that benchmarks don&#8217;t tell us everything we need to know about real-world performance; but what&#8217;s the fun of having choices if we can&#8217;t pick the best?<\/p>\n<p>Exactly.\u00a0 I decided to do a little research project of my own.<\/p>\n<h3>Test Plan<\/h3>\n<p>I selected for this exercise recent (as of October 2011) versions of Apache, Nginx, Lighttpd, G-WAN, and IIS &#8212; a list that includes the most popular web servers as well as web servers that came recommended for their ability to rapidly serve static content.  The test machine was a modern quad-core workstation running CentOS 6.0.  For the IIS tests I booted the same machine off of a different hard drive running Windows Server 2008 SP2.<\/p>\n<div class=\"landing-page-7mh\">\n    <link href=\"\/css\/how-many-users.css\" rel=\"stylesheet\"\/>\n<div class=\"page-title grid\">\n<h2 class=\"unit\">Web Performance Consulting<\/h2>\n<div class=\"product-actions var--footer\">\n      <span><br \/>\n        Our experts find out how many users <strong>your website<\/strong> can handle!<br \/>\n      <\/span><br \/>\n        &nbsp;<br \/>\n        <a href=\"\/load-testing-consulting-services\/\">Learn More<\/a>\n      <\/div>\n<\/p><\/div>\n<\/p><\/div>\n<p>Each web server was left in its default configuration to the greatest extent practical &#8212; I was willing, for example, to increase Apache&#8217;s default connection limit, and to configure Lighttpd to use all four processor cores available on the test machine.\u00a0 I&#8217;m willing to revisit any of these tests if I discover that there is a commonly used optimization that for some reason is disabled by default, but these are all mature software packages that should perform well out of the box.<\/p>\n<p>I decided to run two suites of tests, named &#8220;realistic&#8221; and &#8220;benchmark.&#8221;  The &#8220;realistic&#8221; test represents a web server delivering a lightweight website with static HTML, images, javascript, and css.  The &#8220;benchmark&#8221; test represents an unlikely scenario involving numerous files of roughly 1 kilobyte.  The realistic test is intended to provide a performance profile for a web server under ordinary usage conditions, while the benchmark test is designed to stress the server software&#8217;s ability to rapidly write responses to the network card.<\/p>\n<p>The results in this article describe the behavior of heavily trafficked  web servers delivering static content.  I believe that performance  metrics of this nature can be useful for understanding the behavior of  systems under load, but we should remember that real-world systems are  complex and that performance can be constrained by many variables other  than the efficiency of any particular software package.  In particular,  these numbers will not necessarily be meaningful for systems that will  be performing functions related to dynamic content, such as maintaining  session state or performing searches.<\/p>\n<h3>The &#8220;Realistic&#8221; Test<\/h3>\n<p>For the realistic test, I downloaded a snapshot of Google&#8217;s front landing page and converted it into a very small static site.  I choose this page because it represents a real, minimalistic page with a variety of resource sizes and types.  Very few organizations offer a slimmer first impression.<\/p>\n<p>Apache, Nginx, Lighttpd, G-WAN and IIS all comfortably saturated the test network at roughly 930<del><\/del> megabits per second (after TCP overhead), but some variation in efficiency at near-saturation is still apparent:<\/p>\n<p><a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2011\/11\/cpu_utilization.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-2817 alignnone\" title=\"cpu_utilization\" src=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2011\/11\/cpu_utilization.png\" alt=\"\" width=\"480\" height=\"370\" \/><\/a><\/p>\n<p>A lower number here presumably implies reduced hardware and energy costs, and also represents excess capacity that presumably could be used for other tasks.<\/p>\n<p>(G-WAN, despite proving a snappy little web server in the benchmark test, eagerly consumed 50% of available CPU resources almost immediately upon receiving requests.  As nearly as I could tell given the time I had available, G-WAN uses a different process model from other server software and CPU utilization is not necessarily proportional to load.)<\/p>\n<h3>The &#8220;Benchmark&#8221; Test<\/h3>\n<p>For the benchmark test, I decreased the size of the resources to one kilobyte and increased the number of resources loaded per connection from 5 to 25.  The former action was a deliberate adjustment of a test variable, but the latter was simply an operational necessity: opening and closing TCP connections too rapidly burns a surprising amount of CPU power, tests the operating system&#8217;s TCP implementation as much if not more than the web server, and beyond a certain threshold simply isn&#8217;t permitted by the client-side OS even with tuning.<\/p>\n<p>The goal of the benchmark test was to measure the maximum throughput of each server in requests per second.  Each test was considered complete when throughput stopped increasing with respect to load.<\/p>\n<p><a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2011\/11\/responses_per_second1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2878\" title=\"responses_per_second\" src=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2011\/11\/responses_per_second1.png\" alt=\"\" width=\"474\" height=\"372\" \/><\/a><\/p>\n<p>I also monitored average response times; note that these are average round-trips for a single resource, running over 1 or 2 switches (varying due to the use of multiple load generating engines), such that all systems are within about 50 feet of each other.  The measurement is a running average taken during a sampling window between the second and third minutes into each test, when the system would be under only modest load (about 500 to 750 requests per second, actual).<\/p>\n<p><a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2011\/11\/response_time1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2879\" title=\"response_time\" src=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2011\/11\/response_time1.png\" alt=\"\" width=\"479\" height=\"368\" \/><\/a><\/p>\n<h4>A Note About Response Times<\/h4>\n<p>The ability to respond to a request in less than 3 milliseconds is certainly an impressive technological feat.\u00a0 But to put these numbers in perspective, lets look at how they would affect a typical use case.\u00a0 Let&#8217;s assume that the user has a 100 millisecond round-trip (ping) time to your server, that we will need at most 3 sequential round trips (which is about right if we&#8217;re loading a typical page with 12-18 resources), and also need one round-trip for the SYN\/ACK to establish the first TCP connection.\u00a0 Based on these assumptions, I calculated the simulated page load times below. The red bar represents the 1.5 second mark, a page duration goal that  Google, in their wisdom, has deemed the dividing line between &#8220;fast&#8221;  and &#8220;slow&#8221; web pages in their own analysis software.<\/p>\n<p>If you&#8217;re interested in round-trip times, how they affect the performance of your system, and how to optimize them away, Google has a <a href=\"http:\/\/code.google.com\/speed\/page-speed\/docs\/rtt.html\">comprehensive article<\/a> on the subject.<\/p>\n<p><a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2011\/11\/simulated_page_duration1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2852\" title=\"simulated_page_duration\" src=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2011\/11\/simulated_page_duration1.png\" alt=\"\" width=\"477\" height=\"382\" \/><\/a><\/p>\n<h3>Commentary<\/h3>\n<p>This data comes with a number of qualifications.<\/p>\n<p>For common use cases with lots of static content, such as a corporate front landing page, a 1 gigabit network card will become saturated long before any other resource.\u00a0  The larger your pages (including all resources, such as CSS and image files) in kilobytes, the more this advice rings true.<\/p>\n<p>Request-per-second numbers matter for systems that serve large numbers of small files.  Such systems should be unusual.  For example, if you are delivering pages with many small user interface elements, each requiring its own image resource, consider using CSS sprites to combine those resources into one.<\/p>\n<p>As concerns the simulated page durations, moving your servers closer to your end users is the best way to reduce those numbers.\u00a0  This is where content delivery networks make a strong showing.<\/p>\n<p>These measurements don&#8217;t describe the behavior of a system populated with many gigabytes of unique files that are accessed with uniform frequency.\u00a0 Such systems can&#8217;t keep all content in cache and can be limited by hard disk speed.<\/p>\n<p>Finally, static content delivery is infinitely scalable.\u00a0 No matter how inefficient the system, we can always increase capacity by adding more hardware, and the cost of doing so needs to be weighed carefully against the ease of maintaining an alternative software configuration.<\/p>\n<h3>Conclusions<\/h3>\n<p>Each test revealed IIS 7 as a clear frontrunner.<\/p>\n<p>IIS administrators may give themselves a big pat on the back and feel free to stop reading now.\u00a0 Our beloved Linux server administrators, however, will need to settle their priorities.<\/p>\n<p>Lightttpd is the platform of choice if you want a lean and fast environment.\u00a0 Its low CPU utilization should help reduce energy and hardware costs, and it&#8217;s response times are within a millisecond of the frontrunner.<\/p>\n<p>G-WAN is marketed on it&#8217;s ability to push requests per second, and it unquestionably delivers, but based on these tests it may not have the all-around efficiency that would recommend it for general purpose use.<\/p>\n<p>Apache, arguably the most popular software package in the list, yielded the worst results, and Nginx certainly deserves an honorable mention.\u00a0 Oh, but feel free to continue using any web server that suits your organization, as long as it suits you to run something other than . . . the Fastest Webserver.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Looking for the snappiest, fastest web server software available on this here internet?\u00a0 So were we.\u00a0 Valid, independent, non-synthetic benchmarks can be difficult to find.\u00a0 Of course, we all know that benchmarks don&#8217;t tell us everything we need to know about real-world performance; but what&#8217;s the fun of having choices if we can&#8217;t pick the best?<br \/>\nExactly.\u00a0 I decided to do a little research project of my own.<br \/>\nTest Plan<br \/>\nI selected for this exercise recent (as of October 2011) versions of Apache, Nginx, Lighttpd, G-WAN, and IIS &#8212; a list that includes the most popular web servers as well as web servers &hellip; <a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/2011\/11\/what-is-the-fastest-webserver\/\">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":[34,35,41],"tags":[23,166,165,164,113,163,162,13],"class_list":["post-2815","post","type-post","status-publish","format-standard","hentry","category-apache-httpd","category-aspnet","category-performance-reports","tag-apache","tag-fast","tag-fastest","tag-g-wan","tag-iis","tag-lighttpd","tag-nginx","tag-performance"],"_links":{"self":[{"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/posts\/2815","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=2815"}],"version-history":[{"count":41,"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/posts\/2815\/revisions"}],"predecessor-version":[{"id":6195,"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/posts\/2815\/revisions\/6195"}],"wp:attachment":[{"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/media?parent=2815"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/categories?post=2815"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/tags?post=2815"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}