{"id":1850,"date":"2011-01-24T15:04:55","date_gmt":"2011-01-24T19:04:55","guid":{"rendered":"http:\/\/www.webperformance.com\/load_testing\/blog\/?p=1850"},"modified":"2011-01-24T15:04:55","modified_gmt":"2011-01-24T19:04:55","slug":"load-testing-back-to-basics-avoiding-the-keepalivetimeout-race-condition","status":"publish","type":"post","link":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/2011\/01\/load-testing-back-to-basics-avoiding-the-keepalivetimeout-race-condition\/","title":{"rendered":"Load Testing Back to Basics: Avoiding the KeepAliveTimeout Race Condition"},"content":{"rendered":"<p>You&#8217;ve recorded your test case, configured your datasets, and run your replays.\u00a0 You start up the load test and &#8230; you see numerous errors like this:<\/p>\n<blockquote><p>&#8220;The connection with the server was unexpectedly closed before starting the response.&#8221;<\/p><\/blockquote>\n<p>What&#8217;s going on?\u00a0 Well, one common reason for this error is a connection-related race condition between Load Tester and the web server due to the server&#8217;s configured persistent connection timeout.<\/p>\n<p>Persistent connections are an HTTP mechanism for minimizing network connection overhead between the browser and the web server.\u00a0 If the client has the Connection request header set to Keep-Alive, and the server responds with the Keep-Alive server header, the connections will be maintained to allow the browser to pipeline through more requests at a later time.\u00a0 However, the web server cannot allow the browser to monopolize these connections forever.\u00a0 After a certain point, the server is permitted to cut the connection; normally, this\u00a0 occurs after a certain period of browser inactivity.\u00a0 This timeout is controlled in Apache 2.2 via the KeepAliveTimeout directive, which defaults to five seconds, and in IIS 7 via the connectionTimeout option under the &#8220;limits&#8221; directive, which defaults to two minutes.<\/p>\n<p>The race condition is created when the page think time in Load Tester is set to a value that overlaps the KeepAliveTimeout or connectionTimeout setting: for example, when KeepAliveTimeout is set to ten seconds and the page think time is set to ten seconds.\u00a0 When the think time expires, the load engine begins to pipeline additional requests through the open connections.\u00a0 However, at the same time, the server is shutting down the connection.\u00a0 If the request arrives in time, the server will respond to it, and reset the persistent connection timeout.\u00a0 However, if the request does not arrive in time, the server finishes closing the connection and sends a TCP FIN packet to the client to finalize the connection tear-down.\u00a0 From the perspective of the load engine, the server has closed a connection that has a request in progress, and that&#8217;s why Load Tester reports an error.<\/p>\n<p>This sort of problem occurs routinely in a browser, but is transparent to the user; the browser simply opens a new connection, repeats the request, and moves on.\u00a0 However, Load Tester has no way to know if this behavior is normal or not &#8211; other conditions such as firewall connection timeouts can also generate this situation &#8211; so we must report the error.<\/p>\n<p>In Load Tester you can also create this problem in a load configuration by setting the think time variation range to a value that causes some think times to overlap the persistent connection timeout.\u00a0 For example, if your think time is ten seconds and the KeepAliveTimeout or connectionTimeout is set to twelve seconds, setting the think time range value to 75-150% will overlap the timeout.\u00a0 Thus, the subset of pages with think times that fall around twelve seconds will see the connection errors as requests fail to make it to the server before the connection is closed.<\/p>\n<p>To avoid these errors, you should set KeepAliveTimeout or connectionTimeout to a value that is outside the think time range.\u00a0 If you feel that you must test with the timeout values as-is, you should alter your think times and\/or user count to retain the same load levels while avoiding the problem.\u00a0 Given typical internet latencies, offsetting the think time even by one second either way can minimize the connection errors.<\/p>\n<p>Happy Testing!<\/p>\n<p>Matt Drew<br \/>\nWeb Performance Test Engineer<\/p>\n","protected":false},"excerpt":{"rendered":"<p>You&#8217;ve recorded your test case, configured your datasets, and run your replays.\u00a0 You start up the load test and &#8230; you see numerous errors like this:<br \/>\n&#8220;The connection with the server was unexpectedly closed before starting the response.&#8221;<br \/>\nWhat&#8217;s going on?\u00a0 Well, one common reason for this error is a connection-related race condition between Load Tester and the web server due to the server&#8217;s configured persistent connection timeout.<br \/>\nPersistent connections are an HTTP mechanism for minimizing network connection overhead between the browser and the web server.\u00a0 If the client has the Connection request header set to Keep-Alive, and the server responds with the &hellip; <a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/2011\/01\/load-testing-back-to-basics-avoiding-the-keepalivetimeout-race-condition\/\">Continue reading &raquo;<\/a><\/p>\n","protected":false},"author":7,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[34,35,8],"tags":[23,116,113,112,237,115,114,18],"class_list":["post-1850","post","type-post","status-publish","format-standard","hentry","category-apache-httpd","category-aspnet","category-load-testing","tag-apache","tag-connectiontimeout","tag-iis","tag-keepalivetimeout","tag-load-testing","tag-race-condition","tag-think-time","tag-web-performance"],"_links":{"self":[{"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/posts\/1850","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\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/comments?post=1850"}],"version-history":[{"count":4,"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/posts\/1850\/revisions"}],"predecessor-version":[{"id":1854,"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/posts\/1850\/revisions\/1854"}],"wp:attachment":[{"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/media?parent=1850"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/categories?post=1850"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/tags?post=1850"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}