{"id":3939,"date":"2012-12-05T12:17:49","date_gmt":"2012-12-05T16:17:49","guid":{"rendered":"http:\/\/www.webperformance.com\/load-testing-tools\/blog\/?p=3939"},"modified":"2018-08-09T08:24:16","modified_gmt":"2018-08-09T12:24:16","slug":"setting-apache2-ulimit-for-maximum-prefork-performance","status":"publish","type":"post","link":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/2012\/12\/setting-apache2-ulimit-for-maximum-prefork-performance\/","title":{"rendered":"Setting Apache2 ulimit for Maximum Performance"},"content":{"rendered":"<p>As strange as it seems, when you start up the standard RedHat or CentOS release, it is not configured for running Apache2 with any sort of performance! In fact, even on a large server you&#8217;ll be lucky to handle 100 concurrent users on even simple web pages. So many websites have very few visitors so often its not noticeable, but <em>even if you adjust all of the other apache2 settings<\/em>, if you don&#8217;t bother to adjust the ulimits, the site will be handicapped by really bad performance.<\/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>First, in running the tests I decided to stick with the default prefork MPM. There&#8217;s dozens of sources on the web for configuring Apache prefork for maximum performance that I won&#8217;t repeat here. Typically, though, the first thing to do is set a high number of MaxClients, which really isn&#8217;t that high considering a &#8220;client&#8221; is a socket connection, and modern browsers can open eight socket connections at a time. This turns the &#8220;8192&#8221; below into only 1,024 actual concurrent users. Of course its possible to set MaxClients higher than that, but with a typical test scenario only 500 clients can potentially max out the available bandwidth and CPU, so this isn&#8217;t a bad place to start:<code><\/p>\n<p>StartServers      20<br \/>\nMinSpareServers   25<br \/>\nMaxSpareServers   100<br \/>\nServerLimit      8192<br \/>\nMaxClients       8192<br \/>\nMaxRequestsPerChild  10000<\/p>\n<p><\/code><br \/>\nSo, what type of performance do you get with these settings? The testcase I used was browsing our company website, configured as static pages, with 4 second think times and a page-load goal of 2 seconds per page. Even though it should have been able to handle at least 512 browsers, the webserver started crashing at less than 100 concurrent users.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3952\" title=\"Hits\/Second\" src=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2012\/11\/Screen-Shot-2012-11-30-at-4.29.26-PM.jpg\" alt=\"\" width=\"500\" height=\"349\" \/><\/p>\n<p>As it turns out, despite setting MaxClients to 4096, the system never actually reaches that level because the compiled in limit for the number of processes is 1024, as can be seen below:<br \/>\n<code><br \/>\n[root@faith ~]# ulimit -a<br \/>\ncore file size          (blocks, -c) 0<br \/>\ndata seg size           (kbytes, -d) unlimited<br \/>\nscheduling priority             (-e) 0<br \/>\nfile size               (blocks, -f) unlimited<br \/>\npending signals                 (-i) 59400<br \/>\nmax locked memory       (kbytes, -l) 64<br \/>\nmax memory size         (kbytes, -m) unlimited<br \/>\nopen files                      (-n) 1024<br \/>\npipe size            (512 bytes, -p) 8<br \/>\nPOSIX message queues     (bytes, -q) 819200<br \/>\nreal-time priority              (-r) 0<br \/>\nstack size              (kbytes, -s) 10240<br \/>\ncpu time               (seconds, -t) unlimited<br \/>\nmax user processes              (-u) 1024<br \/>\nvirtual memory          (kbytes, -v) unlimited<br \/>\nfile locks                      (-x) unlimited<br \/>\n<\/code><br \/>\nThe fix on RedHat\/CentOS is to edit the file <code>\/etc\/security\/limits.conf<\/code> and these lines, adjusting the limits based on your system capacity and needs.<br \/>\n<code><br \/>\n* soft nofile 10240<br \/>\n* soft nproc 10240<br \/>\n<\/code><br \/>\nRestarting Apache and Re-running the tests resulted in a huge increase in performance, increasing the capacity of the server to around 600 concurrent users.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3957\" title=\"Fixed Ulimit hits\/sec\" src=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2012\/11\/Screen-Shot-2012-11-30-at-5.47.33-PM.png\" alt=\"\" width=\"500\" height=\"347\" \/><\/p>\n","protected":false},"excerpt":{"rendered":"<p>As strange as it seems, when you start up the standard RedHat or CentOS release, it is not configured for running Apache2 with any sort of performance! In fact, even on a large server you&#8217;ll be lucky to handle 100 concurrent users on even simple web pages. So many websites have very few visitors so often its not noticeable, but even if you adjust all of the other apache2 settings, if you don&#8217;t bother to adjust the ulimits, the site will be handicapped by really bad performance.<\/p>\n<p>Web Performance Consulting<\/p>\n<p>  &hellip; <a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/2012\/12\/setting-apache2-ulimit-for-maximum-prefork-performance\/\">Continue reading &raquo;<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[34,8],"tags":[],"class_list":["post-3939","post","type-post","status-publish","format-standard","hentry","category-apache-httpd","category-load-testing"],"_links":{"self":[{"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/posts\/3939","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\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/comments?post=3939"}],"version-history":[{"count":31,"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/posts\/3939\/revisions"}],"predecessor-version":[{"id":3974,"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/posts\/3939\/revisions\/3974"}],"wp:attachment":[{"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/media?parent=3939"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/categories?post=3939"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/tags?post=3939"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}