18

I am writing a High Performance ASP.NET Json API with soon > 1000 Request/Second. All my logic and processing is done in an IHttpHandler. I measured via Stopwatch Class and the handler finishes a request in around 0,1 - 0,5 Millisecond.

But it seems IIS and/or other HTTPHandlers (Modules?) are taking away a lot of performance. Can i measure that somehow ? How much overhead will a request produce in IIS when configured for best performance ?

Will removing all those HTTPHandlers help, or are there other tricks to speed it up? I dont need much of the ASP.NET Featureset besides Session (could even workaround that if it give a significant performance boost).

RickAndMSFT
  • 20,912
  • 8
  • 60
  • 78
TobiHeidi
  • 1,201
  • 2
  • 14
  • 23
  • 1
    since it's 'natively' async and can be self-hosted (so you can avoid running in IIS), it seems like it'd be worth looking at the ASP.NET Web API (built-in to MVC4, but also available standalone). I've learned a good bit about it from Henrik's blog @ http://blogs.msdn.com/b/henrikn/ – James Manning Mar 21 '12 at 03:57
  • 2
    FWIW, the phrasing of the question is a little odd to me insofar as it seems to mix latency/bandwidth (to use network terms). The latency to serve a particular request doesn't seem to be that important (outside of end-user experience, but orthogonal to scalability) relative to the ability to serve them efficiently and concurrently. IOW, if every request took 1000ms to service, but you could service 2000 at a time, you'd still be ok with that, right? – James Manning Mar 21 '12 at 04:02
  • Not sure how much it'll apply to the API you're creating, but if there's anything cacheable, make sure to do so. And if you can stay stateless, you can likely use ARR and scale out if needed. – James Manning Mar 21 '12 at 04:04

2 Answers2

13

Measuring performance of a web server is no trivial task. A few things to consider:

  • Find the actual bottleneck. This can be memory, disk access, caching, database access, network latency etc. Use a memory profiler, or other performance profiler to find out.
  • Use WireShark to find the difference between how long the request is on your machine and how long your code runs.
  • Try other configurations. Give ASP.NET more memory. Upgrade the test system. I.e., going from 8GB / 2.5GHz with 600 requests/sec to 16GB / 3.0GHz can yield 6500 requests/sec. Performance growth is often not linear. See this document from Microsoft.
  • Consider adding an extra machine. This can yield up to a 50 or even higher performance upgrade depending on how you configure it. See again that document from MS.
  • Check these hints by Jon Skeet. The comment thread reveals some non-obvious potential bottlenecks as well.

NOTE 1: know your tools. ASP.NET runs each request in its own thread. Thread swapping is faster than process swapping, but it still requires time. If other handlers take time because they are in the request chain, it's beneficial to disable them.

NOTE 2: one of the original side-goals of stackoverflow was to create a site in ASP.NET that had great performance on max 2 servers and could handle > 1Mln visitors per hour. They managed to do that. I believe they wrote some blogposts on it, but I don't remember where they are.

Community
  • 1
  • 1
Abel
  • 56,041
  • 24
  • 146
  • 247
5

This is a very good question. I have noticed the same once you get into the single-millisecond range of response times, ASP.NET overhead starts to be noticable. I can confirm your observation.

What I have done successfully is to find out, which HttpModules are registered (using IIS Manager) and disable all of them which I could possibly get rid of. The standard ASP.NET pipeline has a lot of modules and functionality configured.

If you need ultimate performance, you could of course use a tiny HTTP server library and get rid of almost all overhead that way. This would be so incredibly fast.

usr
  • 168,620
  • 35
  • 240
  • 369
  • Actually, it's not a golden rule that a _tiny_ server can service more requests than a large HTTP server. The opposite is more common. – Abel Mar 20 '12 at 23:18
  • 1
    This is not about tiny and large. It is about the amount of code which runs per request. We can tell from the latency the OP mentioned that there is a lot of code running. Much more than parsing the HTTP headers and using a socket. – usr Mar 20 '12 at 23:19
  • 1
    agree with removing enabled modules. Enable Failed Event Tracing (for 100-999 responses) and look at all the modules called. Then remove all the modules you don't need. - I disagree with the tiny server idea (but I upvoted you anyway :)) – RickAndMSFT Mar 21 '12 at 23:08
  • The tiny server idea really is the last choice one wants to take. – usr Mar 21 '12 at 23:11