Trimming the Fat Off of HTTP Endpoints
If you wanted to launch a REST based API today, what technology would you use? For most the answer would be Web API. Have you ever thought about what Web API consists of though? I mean, do you know how much code a request has to go through until it reaches your controller method?
While designing an API recently I forwent Web API and tried to get as low-level as possible in hopes that my service would be faster. I read an interesting tutorial on how this could be done in Azure using OWIN self hosting capabilities, but, for no good reason I am not a fan of OWIN. I get the sense that there is still a lot of other people’s code between the incoming request and my code. In my quest to get as low-level as possible I stumbled upon the HttpListener class which is essentially a wrapper for HTTP.sys. Surely this is as low-level as I can get without getting too carried away.
So, which method out of these three will serve HTTP requests the fastest: Web API, OWIN Self Host, or HttpListener? My hypothesis is that HttpListener will be because it the most low-level. The tests for each method will consist of returning the current date and time. There will be no input (no post data or query string) and the result will be returned serialized as JSON. JSON.NET will be used for serialization in each of the projects for consistency. You can get faster performance by using Jil but we’ll leave it alone for this run. I want the out-of-the-box Web API project to be the baseline because that’s what most people are using. The Web API project will be hosted in IIS while the others will be hosted by a Console app. A fourth project will be created which makes 1000 HTTP requests to each host and records the results. The requests will be made from the same machine the servers are running on to eliminate network latency.
Here is my solution with source code for the servers and tester if you’d like to try it for yourself – WebServerComparison.zip
Here are my results: (all times are in seconds)
Web API | OWIN | HttpListener | |
---|---|---|---|
Run 1 | 0.8059442 | 0.6924348 | 0.2742231 |
Run 2 | 0.6600578 | 0.3289284 | 0.1906594 |
Run 3 | 0.640202 | 0.3297216 | 0.1872897 |
Run 4 | 0.6189885 | 0.3406656 | 0.1953822 |
Run 5 | 0.6118996 | 0.3280714 | 0.1898794 |
Avg | 0.66741842 | 0.40396436 | 0.20748676 |
As with anything there are some trade-offs. With IIS you get a lot of management features that you would never get by running your own web server. It also has a lot more security and is more robust. It will log requests and handle errors for you. Writing your own web server will give you faster responses but you’ll have to spend time solving problems that IIS has already solved. The trade-off is yours to decide upon. In the case of RulePlex or other extreme performance needy services I think it’s better to go with the faster option.
The OWN self hosting option is neither the fastest nor does it give you any management features. It does mean you can setup your server in more of a Web API way and gives you some added security, but, I don’t think this middle-of-the-road option is worth much. You either want the performance or you want the management. Right?
Other notes
If you have an API that is used by your web app’s front-end via ajax requests and both are on the same domain you should pay attention to the cookies being sent in the request. If possible host the API on a different domain to avoid the cookies from being sent with the request.
Compression may also play a factor in larger requests. My next post will explore compression options.