A few months ago on
a project the subject of
load testing came up. We were having some serious issues with
a Web application that would start spewing SQL lock errors under somewhat heavy
load. These sort of errors can be tough
to catch, precisely because they only occur under
load and not during typical development testing.
To replicate this error more reliably we needed
to put
a load on the application and run it for
a while before these SQL errors would flare up. It’s been
a while since I’d looked at
load testing tools, so I spent
a bit of time looking at different tools and frankly didn’t really find anything that was
a good fit.
A lot of tools were either
a pain
to use, didn’t have the basic features I needed, or are extravagantly expensive. In the end I got frustrated enough
to build an initially small custom
load test solution that then morphed into
a more generic library, then gained
a console front end and eventually turned into
a full blown Web
load testing tool that is now called West Wind WebSurge. I got seriously frustrated looking for tools every time I needed some quick and dirty
load testing for an application. If my aim is
to just put an application under heavy enough
load to find
a scalability problem
in code, or
to simply try and push an application
to its limits on the hardware it’s running I shouldn’t have
to have
to struggle
to set up tests. It should be easy enough
to get going
in a few minutes, so that the testing can be set up quickly so that it can be done on
a regular basis without
a lot of hassle. And that was the goal when I started
to build out my initial custom
load tester into
a more widely usable tool. If you’re
in a hurry and you want
to check it out, you can find more information and download links here: West Wind WebSurge Product Page Walk through Video Download link (zip) Install from Chocolatey Source on GitHub For
a more detailed discussion of the why’s and how’s and some background continue reading.
How did I get here? When I started out on this path, I wasn’t planning on building
a tool like this myself – but I got frustrated enough looking at what’s out there
to think that I can do better than what’s available for the most common simple
load testing scenarios. When we ran into the SQL lock problems I mentioned, I started looking around what’s available for Web
load testing solutions that would work for our whole team which consisted of
a few developers and
a couple of IT guys both of which needed
to be able
to run the tests. It had been
a while since I looked at tools and I figured that by now there should be some good solutions out there, but as it turns out I didn’t really find anything that fit our relatively simple needs without costing an arm and
a leg… I spent the better part of
a day installing and trying various
load testing tools and
to be frank most of them were either terrible at what they do, incredibly unfriendly
to use, used some terminology I couldn’t even parse, or were extremely expensive (and I mean
in the ‘sell your liver’ range of expensive). Pick your poison. There are also
a number of online solutions for
load testing and they actually looked more promising, but those wouldn’t work well for our scenario as the application is running inside of
a private VPN with no outside access into the VPN. Most of those online solutions also ended up being very pricey as well – presumably because of the bandwidth required
to test over the open Web can be enormous. When I asked around on Twitter what people were using– I got mostly… crickets. Several people mentioned Visual Studio
Load Test, and most other suggestions pointed
to online solutions. I did get
a bunch of responses though with people asking
to let them know what I found – apparently I’m not alone when it comes
to finding
load testing tools that are effective and easy
to use. As
to Visual Studio, the higher end skus of Visual Studio and the test edition include
a Web
load testing tool, which is quite powerful, but there are
a number of issues with that: First it’s tied
to Visual Studio so it’s not very portable – you need
a VS install. I also find the test setup and terminology used by the VS test runner extremely confusing. Heck, it’s complicated enough that there’s even
a Pluralsight course on using the Visual Studio Web test from Steve Smith. And of course you need
to have one of the high end Visual Studio Skus, and those are mucho Dinero ($$$) – just for the
load testing that’s rarely an option. Some of the tools are ultra extensive and let you run analysis tools on the target serves which is useful, but
in most cases – just plain overkill and only distracts from what I tend
to be ultimately interested in: Reproducing problems that occur at high
load, and finding the upper limits and ‘what if’ scenarios as
load is ramped up increasingly against
a site. Yes it’s useful
to have Web app instrumentation, but often that’s not what you’re interested
in. I still fondly remember early days of Web testing when Microsoft had the WAST (Web Application Stress Tool) tool, which was rather simple – and also somewhat limited – but easily allowed you
to create stress tests very quickly. It had some serious limitations (mainly that it didn’t work with SSL), but the idea behind it was excellent: Create tests quickly and easily and provide
a decent engine
to run it locally with minimal setup. You could get set up and run tests within
a few minutes. Unfortunately, that tool died
a quiet death as so many of Microsoft’s tools that probably were built by an intern and then abandoned, even though there was
a lot of potential and it was actually fairly widely used. Eventually the tools was no longer downloadable and now it simply doesn’t work anymore on higher end hardware. West Wind Web Surge – Making
Load Testing Quick and Easy So I ended up creating West Wind WebSurge out of rebellious frustration… The goal of WebSurge is
to make it drop dead simple
to create
load tests. It’s super easy
to capture sessions either using the built
in capture tool (big props
to Eric Lawrence, Telerik and FiddlerCore which made that piece
a snap), using the full version of Fiddler and exporting sessions, or by manually or programmatically creating text files based on plain HTTP headers
to create requests. I’ve been using this tool for 4 months now on
a regular basis on various projects as
a reality check for performance and scalability and it’s worked extremely well for finding small performance issues. I also use it regularly as
a simple URL tester, as it allows me
to quickly enter
a URL plus headers and content and test that URL and its results along with the ability
to easily save one or more of those URLs.
A few weeks back I made
a walk through video that goes over most of the features of WebSurge
in some detail: Note that the UI has slightly changed since then, so there are some UI improvements. Most notably the test results screen has been updated recently
to a different layout and
to provide more information about each URL
in a session at
a glance. The video and the main WebSurge site has
a lot of info of basic operations. For the rest of this post I’ll talk about
a few deeper aspects that may be of interest while also giving
a glance at
how WebSurge works. Session Capturing As you would expect, WebSurge works with Sessions of Urls that are played back under
load. Here’s what the main Session View looks like: You can create session entries manually by individually adding URLs
to test (on the Request tab on the right) and saving them, or you can capture output from Web Browsers, Windows Desktop applications that call services, your own applications using the built
in Capture tool. With this tool you can capture anything HTTP -SSL requests and content from Web pages, AJAX calls, SOAP or REST services – again anything that uses Windows or .NET HTTP APIs. Behind the scenes the capture tool uses FiddlerCore so basically anything you can capture with Fiddler you can also capture with Web Surge Session capture tool. Alternately you can actually use Fiddler as well, and then export the captured Fiddler trace
to a file, which can then be imported into WebSurge. This is
a nice way
to let somebody capture session without having
to actually install WebSurge or for your customers
to provide an exact playback scenario for
a given set of URLs that cause
a problem perhaps. Note that not all applications work with Fiddler’s proxy unless you configure
a proxy. For example, .NET Web applications that make HTTP calls usually don’t show up
in Fiddler by default. For those .NET applications you can explicitly override proxy settings
to capture those requests
to service calls. The capture tool also has handy optional filters that allow you
to filter by domain,
to help block out noise that you typically don’t want
to include
in your requests. For example, if your pages include links
to CDNs, or Google Analytics or social links you typically don’t want
to include those
in your
load test, so by capturing just from
a specific domain you are guaranteed content from only that one domain. Additionally you can provide url filters
in the configuration file – filters allow
to provide filter strings that if contained
in a url will cause requests
to be ignored. Again this is useful if you don’t filter by domain but you want
to filter out things like static
image, css and script files etc. Often you’re not interested
in the
load characteristics of these static and usually cached resources as they just add noise
to tests and often skew the overall url performance results.
In my testing I tend
to care only about my dynamic requests. SSL Captures require Fiddler Note, that
in order
to capture SSL requests you’ll have
to install the Fiddler’s SSL certificate. The easiest way
to do this is
to install Fiddler and use its SSL configuration options
to get the certificate into the local certificate store. There’s
a document on the Telerik site that provides the exact steps
to get SSL captures
to work with Fiddler and therefore with WebSurge. Session Storage
A group of URLs entered or captured make up
a Session. Sessions can be saved and restored easily as they use
a very simple text format that simply stored on disk. The format is slightly customized HTTP header traces separated by
a separator line. The headers are standard HTTP headers except that the full URL instead of just the domain relative path is stored as part of the 1st HTTP header line for easier parsing. Because it’s just text and uses the same format that Fiddler uses for exports, it’s super easy
to create Sessions by hand manually or under program control writing out
to a simple text file. You can see what this format looks like
in the Capture window figure above – the raw captured format is also what’s stored
to disk and what WebSurge parses from. The only ‘custom’ part of these headers is that 1st line contains the full URL instead of the domain relative path and Host: header. The rest of each header are just plain standard HTTP headers with each individual URL isolated by
a separator line. The format used here also uses what Fiddler produces for exports, so it’s easy
to exchange or view data either
in Fiddler or WebSurge. Urls can also be edited interactively so you can modify the headers easily as well: Again – it’s just plain HTTP headers so anything you can do with HTTP can be added here. Use it for single URL Testing Incidentally I’ve also found this form as an excellent way
to test and replay individual URLs for simple non-load testing purposes. Because you can capture
a single or many URLs and store them on disk, this also provides
a nice HTTP playground where you can record URLs with their headers, and fire them one at
a time or as
a session and see results immediately. It’s actually an easy way for REST presentations and I find the simple UI flow actually easier than using Fiddler natively. Finally you can save one or more URLs as
a session for later retrieval. I’m using this more and more for simple URL checks. Overriding Cookies and Domains Speaking of HTTP headers – you can also overwrite cookies used as part of the options. One thing that happens with modern Web applications is that you have session cookies
in use for authorization. These cookies tend
to expire at some point which would invalidate
a test. Using the Options dialog you can actually override the cookie: which replaces the cookie for all requests with the cookie value specified here. You can capture
a valid cookie from
a manual HTTP request
in your browser and then paste into the cookie field,
to replace the existing Cookie with the new one that is now valid. Likewise you can easily replace the domain so if you captured urls on west-wind.com and now you want
to test on localhost you can do that easily easily as well. You could even do something like capture on store.west-wind.com and then test on localhost/store which would also work. Running
Load Tests Once you’ve created
a Session you can specify the length of the test
in seconds, and specify the number of simultaneous threads
to run each session on. Sessions run through each of the URLs
in the session sequentially by default. One option
in the options list above is that you can also randomize the URLs so each thread runs requests
in a different order. This avoids bunching up URLs initially when tests start as all threads run the same requests simultaneously which can sometimes skew the results of the first few minutes of
a test. While sessions run some progress information is displayed: By default there’s
a live view of requests displayed
in a Console-like window. On the bottom of the window there’s
a running total summary that displays where you’re at
in the test,
how many requests have been processed and what the requests per second count is currently for all requests. Note that for tests that run over
a thousand requests
a second it’s
a good idea
to turn off the console display. While the console display is nice
to see that something is happening and also gives you slight idea what’s happening with actual requests, once
a lot of requests are processed, this UI updating actually adds
a lot of CPU overhead
to the application which may cause the actual
load generated
to be reduced. If you are running
a 1000 requests
a second there’s not much
to see anyway as requests roll by way too fast
to see individual lines anyway. If you look on the options panel, there is
a NoProgressEvents option that disables the console display. Note that the summary display is still updated approximately once
a second so you can always tell that the test is still running. Test Results When the test is done you get
a simple Results display: On the right you get an overall summary as well as breakdown by each URL
in the session. Both success and failures are highlighted so it’s easy
to see what’s breaking
in your
load test. The report can be printed or you can also open the HTML document
in your default Web Browser for printing
to PDF or saving the HTML document
to disk. The list on the right shows you
a partial list of the URLs that were fired so you can look
in detail at the request and response data. The list can be filtered by success and failure requests. Each list is partial only (at the moment) and limited
to a max of 1000 items
in order
to render reasonably quickly. Each item
in the list can be clicked
to see the full request and response data: This particularly useful for errors so you can quickly see and copy what request data was used and
in the case of
a GET request you can also just click the link
to quickly jump
to the page. For non-GET requests you can find the URL
in the Session list, and use the context menu
to Test the URL as configured including any HTTP content data
to send. You get
to see the full HTTP request and response as well as
a link
in the Request header
to go visit the actual page. Not so useful for
a POST as above, but definitely useful for GET requests. Finally you can also get
a few charts. The most useful one is probably the Request per Second chart which can be accessed from the Charts menu or shortcut. Here’s what it looks like: Results can also be exported
to JSON, XML and HTML. Keep
in mind that these files can get very large rather quickly though, so exports can end up taking
a while
to complete. Command Line Interface WebSurge runs with
a small core
load engine and this engine is plugged into the front end application I’ve shown so far. There’s also
a command line interface available
to run WebSurge from the Windows command prompt. Using the command line you can run tests for either an individual URL (similar
to AB.exe for example) or
a full Session file. By default when it runs WebSurgeCli shows progress every second showing total request count, failures and the requests per second for the entire test.
A silent option can turn off this progress display and display only the results. The command line interface can be useful for build integration which allows checking for failures perhaps or hitting
a specific requests per second count etc. It’s also nice
to use this as quick and dirty URL test facility similar
to the way you’d use Apache Bench (ab.exe). Unlike ab.exe though, WebSurgeCli supports SSL and makes it much easier
to create multi-URL tests using either manual editing or the WebSurge UI. Current Status Currently West Wind WebSurge is still
in Beta status. I’m still adding small new features and tweaking the UI
in an attempt
to make it as easy and self-explanatory as possible
to run. Documentation for the UI and specialty features is also still
a work
in progress. I plan on open-sourcing this product, but it won’t be free. There’s
a free version available that provides
a limited number of threads and request URLs
to run.
A relatively low cost license removes the thread and request limitations. Pricing info can be found on the Web site – there’s an introductory price which is $99 at the moment which I think is reasonable compared
to most other for pay solutions out there that are exorbitant by comparison… The reason code is not available yet is – well, the UI portion of the app is
a bit embarrassing
in its current monolithic state. The UI started as
a very simple interface originally that later got
a lot more complex – yeah, that never happens, right? Unless there’s
a lot of interest I don’t foresee re-writing the UI entirely (which would be ideal), but
in the meantime at least some cleanup is required before I dare
to publish it :-). The code will likely be released with version 1.0. I’m very interested
in feedback. Do you think this could be useful
to you and provide value over other tools you may or may not have used before? I hope so – it already has provided
a ton of value for me and the work I do that made the development worthwhile at this point. You can leave
a comment below, or for more extensive discussions you can post
a message on the West Wind Message Board
in the WebSurge section Microsoft MVPs and Insiders get
a free License If you’re
a Microsoft MVP or
a Microsoft Insider you can get
a full license for free. Send me
a link
to your current, official Microsoft profile and I’ll send you
a not-for resale license. Send any messages
to [email protected]. Resources For more info on WebSurge and
to download it
to try it out, use the following links. West Wind WebSurge Home Download West Wind WebSurge Getting Started with West Wind WebSurge Video© Rick Strahl, West Wind Technologies, 2005-2014Posted
in ASP.NET
Tweet
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();