Iris Go vs .NET Core Kestrel in terms of HTTP performance
A Fair benchmark between Iris Golang and Kestrel .NET Core (C#).
Hello!
This article is the second in a row of the “Go vs .Net Core in terms of HTTP performance” series, you should really read the first article, if you didn’t already.
Prepare yourself a cup of coffee, or tea, whatever enjoys you the most!
About feedback
At this section I’ll try to give you a general idea about a part(the bad side) of the previous article’s reactions however you may don’t care at all or you’re not in the mood, therefore you may want to skip that and go straight to the “Benchmarking” section.
At our previous article we compared the performance of the MVC features of both Iris web framework and .NET Core by testing a simple application (to avoid arguments like “you could use a faster json encoder” and things like these).
The article got pretty amazing reactions. Most of the comments were very nice and polite either agree or disagree with them. There were some people with a smell of negativity on their comments but those were expected and welcomed as well.
I always try to be responsible so I respond to most of your questions that were relative to the article avoiding duplication. If you don’t see my respond below your comment yet then search about relative questions, I’m sure you’ll find my answer sitting there waiting for you.
Some of the .NET Developers contacted with me via twitter telling that this wasn’t real .NET Core because I used MVC and not Kestrel, does that mean that C# developers should avoid .NET Core’s MVC features? I didn’t understand. It was clear by the benchmark titles and the code itself that we were doing a comparison between the MVC versions of both Iris and .NET Core, Iris has a “lower level“ too but we didn’t use that.
I knew that my article will have an impact on .NET world. I’d receive a lot of rude comments lately, the funny part is that the people who posted the most unacceptable comments are working for big companies, I mean that they are in a certain age who can understand the human contact but actually they never learnt the basics of human communication, politeness.
I don’t really feel that right, I mean by publishing their (already public) comments is the right decision but one way or another we should all condemn them as soon as possible.
At the other hand I have really no problem at all, hate speech was and will never touch me at all because I don’t have that thing inside me — by-design :p . I’m not taking those as personal attacks neither terrifies me, but this doesn’t mean that I should tolerate them, tacitly.
For example that guy claims that he works at Microsoft but I can’t believe that someone with “high education” can possible write something like that:
No, they didn’t stop there, you will be surprised about the Democratic consciousness that this comment promoting!
Beside the fact of the miss arguments and the slanderous comments , the first guy, Ali Malekpour posted his argument nicely so I think of it seriously, he actually gave me this idea: to write benchmarks for the “low-level” web side of those two worlds, Go and .NET Core and so here we are :)
Benchmarking
This time we will compare the speed of the “low-level” .NET Core’s server implementation named Kestrel and Iris’ “low-level” handlers, we will test two simple applications, the first will be almost the same as our previous application but written using handlers and the second test will contain a single route which sets and gets a session value(string) based on a key(string) and returns that session value to the client.
Hardware
- Processor: Intel(R) Core(TM) i7–4710HQ CPU @ 2.50GHz 2.50GHz
- RAM: 8.00 GB
Software
- OS: Microsoft Windows [Version 10.0.15063], power plan is “High performance”
- HTTP Benchmark Tool: https://github.com/codesenberg/bombardier, latest version 1.1
- .NET Core: https://www.microsoft.com/net/core, latest version 2.0
- Iris: https://github.com/kataras/iris, latest version 8.3 built with go1.8.3
First application
Spawn 1000000 requests
with 125
different “threads”, targeting to a dynamic registered route path, responds with a simple “value”
text.
.NET Core (Kestrel)
Source Code
Start the .NET Core Kestrel web server
$ cd netcore
$ dotnet run -c Release
Hosting environment: Production
Content root path: C:\mygopath\src\github.com\kataras\iris\_benchmarks\netcore
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.
Target and run the HTTP benchmark tool
$ bombardier -c 125 -n 1000000 http://localhost:5000/api/values/5
Bombarding http://localhost:5000/api/values/5 with 1000000 requests using 125 connections
1000000 / 1000000 [======================================================================================] 100.00% 10s
Done!
Statistics Avg Stdev Max
Reqs/sec 97884.57 8699.94 110509
Latency 1.28ms 682.63us 61.04ms
HTTP codes:
1xx - 0, 2xx - 1000000, 3xx - 0, 4xx - 0, 5xx - 0
others - 0
Throughput: 17.73MB/s
Iris
Source Code
Start the Iris Go web server
$ cd iris
$ go run main.go
Now listening on: http://localhost:5000
Application started. Press CTRL+C to shut down.
Target and run the HTTP benchmark tool
$ bombardier -c 125 -n 1000000 http://localhost:5000/api/values/5
Bombarding http://localhost:5000/api/values/5 with 1000000 requests using 125 connections
1000000 / 1000000 [=======================================================] 100.00% 8s
Done!
Statistics Avg Stdev Max
Reqs/sec 117917.79 4437.04 125614
Latency 1.06ms 278.12us 19.03ms
HTTP codes:
1xx - 0, 2xx - 1000000, 3xx - 0, 4xx - 0, 5xx - 0
others - 0
Throughput: 21.93MB/s
Summary
- Time to complete the
1000000 requests
— smaller is better. - Reqs/sec — bigger is better.
- Latency — smaller is better
- Throughput — bigger is better.
- LOC (Lines Of Code) — smaller is better.
.NET Core (Kestrel) Application written using 63 code of lines ran for 10 seconds serving 97884.57 requests per second with 17.73MB/s within 1.28ms latency in average and 61.04ms max.
Iris Application written using 14 code of lines ran for 8 seconds serving 117917.79 requests per second with 21.93MB/s within 1.06ms latency in average and 19.03ms max.
Second Application (Sessions)
Spawn 5000000 requests
with 125 different “threads”
targeting a static request path, sets and gets a session based on the name “key”
,value as string”value"
and write(or return, you choose) that session value to the response stream.
.NET Core (Kestrel) with Sessions
Source Code
Start the .NET Core Kestrel web server
$ cd netcore-sessions
$ dotnet run -c Release
Hosting environment: Production
Content root path: C:\mygopath\src\github.com\kataras\iris\_benchmarks\netcore-sessions
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.
Target and run the HTTP benchmark tool
$ bombardier -c 125 -n 5000000 http://localhost:5000/setget
Bombarding http://localhost:5000/setget with 5000000 requests using 125 connections
5000000 / 5000000 [====================================================================================] 100.00% 2m40s
Done!
Statistics Avg Stdev Max
Reqs/sec 31844.77 13856.19 253746
Latency 4.02ms 15.57ms 0.96s
HTTP codes:
1xx - 0, 2xx - 5000000, 3xx - 0, 4xx - 0, 5xx - 0
others - 0
Throughput: 14.51MB/s
Iris with Sessions
Source Code
Start the Iris Go web server
$ cd iris-sessions
$ go run main.go
Now listening on: http://localhost:5000
Application started. Press CTRL+C to shut down.
Target and run the HTTP benchmark tool
$ bombardier -c 125 -n 5000000 http://localhost:5000/setget
Bombarding http://localhost:5000/setget with 5000000 requests using 125 connections
5000000 / 5000000 [====================================================================================] 100.00% 1m15s
Done!
Statistics Avg Stdev Max
Reqs/sec 66749.70 32110.67 110445
Latency 1.88ms 9.13ms 1.94s
HTTP codes:
1xx - 0, 2xx - 5000000, 3xx - 0, 4xx - 0, 5xx - 0
others - 0
Throughput: 20.65MB/s
Summary
- Time to complete the
5000000 requests
— smaller is better. - Reqs/sec — bigger is better.
- Latency — smaller is better
- Throughput — bigger is better.
.NET Core with Sessions Application ran for 2 minutes and 40 seconds serving 31844.77 requests per second with 14.51MB/s within 4.02ms latency in average and 0.96s max.
Iris with Sessions Application ran for 1 minute and 15 seconds serving 66749.70 requests per second with 20.65MB/s within 1.88ms latency in average and 1.94s max.
Epilogue
We really have to admit that Kestrel runs pretty fast compared to its MVC side, congrats to the open-source project’s contributors and Microsoft for started and supporting that!
Like the previous article, this one has its own screenshots taken from my computer and the same code snippets you saw here are also exist in gists and the github repository, click to the links to be navigated.
I would love to see more testers so download the source code and run the benchmarks from your machine, share the results with the rest of us.
If you want to reach me for a subject to discuss I’m always open for new opportunities and new people to meet, inside my twitter profile you’ll find all my contact information!
Thank you for the personal time you gave to read this article, spread it to the outside world as you did with the previous one.
Will see you at my next article and… as always, have fun!
I like the visual effects when I click the clap button more than once, do you? It’s simple: just click the clap button. If you feel strongly, click it more (or just hold it down).