NetTcpBinding is often assumed to offer the best performance of all WCF bindings. When working on WCF implementations, I often hear from developers argue about the performance benefits that their solution gain by usingnettcp endpoints but rarely see any benchmarks to confirm that assertion for their specific scenario.
After all, it seems very logical that plain TCP should be faster than HTTP and binary encoding should be faster than text encoding. Also, nettcp should be even faster using the Windows Activation Service(WAS) because….well... because WAS sounds is a very robust hosting environment for WCF services.
Not so fast….
There are a couple of aspects about the NetTcpBinding that might surprise you a bit. Whether is true that we could improve the performance of our services by using the NetTcpBinding the details of how to obtain those performance levels are far from trivial.
To prove this argument, we decided to do some benchmarks using our SO-Aware Test Workbench and, we think, the results are pretty illustrative. The purposes of these benchmarks are to compare the performance of a WCF service using the NetTcpBinding under certain load test conditions simulated by the SO-Aware Test Workbench.
For the purposes of our sample, we’ve used the following WCF service.
To keep things simple we picked three fundamental scenarios.
- WCF service using the default NetTcpBinding configuration hosted in WAS
- WCF Services using an optimal NetTcpBinding configuration hosted in WAS
- WCF Service using an optimal NetTcpBinding configuration in a self-hosted environment
Before we start, I have to tell you we (in Tellago Studios) were a bit shocked by the results and I think you are going to be as well :)
WCF service using the default NetTcpBinding configuration hosted in WAS
To model this test, we configured our service in SO-Aware with the default NetTcpBinding configuration and used the SO-Aware Test Workbench to execute a simple load strategy that simulated a 100 concurrent clients interacting with the service for 60 seconds. The results are illustrated below.
As you can see, the response times of the service were around 800 milliseconds are we were able to execute close to 6000 tests.
You might be surprised that the performance results of this configuration are not only discouraging but they are even worse than a similar test using the BasicHttpBinding.
There is a simple explanation to these results. There are various aspects of the default NetTcpBinding that can impact the performance of a service. By default, NetTcpBinding enables certain levels of security add overhead to the message processing pipeline of the WCF runtime. Additionally, the NetTcpBinding also enables the port sharing feature which means that your WCF host won’t have exclusive access to the port and instead might share it with other applications. This might get very interesting if you are hosting your service in a Windows Server 2008 or Windows 7 environment given that there are a number of Windows applications that rely on NetTcpBinding endpoints. Finally, the default values for theListenBacklog and MaxConnections settings are set to 10 which is far from optimal for a large number of clients. TheNetTcpBinding.ListenBacklog property controls the maximum number of queued connection requests that can be pending for a Web service. The NetTcpBinding.MaxConnections property controls the maximum number of connections to be pooled for subsequent reuse on the client and the maximum number of connections allowed to be pending dispatch on the server.
WCF Services using an optimal NetTcpBinding configuration hosted in WAS
In our second scenario, we decided to optimize the NetTcpBinding configuration to address some of the limitation of the previous scenario. For that, we created a new binding configuration in SO-Aware as illustrated below.
At this point, we ran the same load strategy against our service and we obtained the following results.
Surprisingly enough, the performance of this service is not better than what we obtained with the basicHttpBinding.
Again, there is a simple explanation for the results. There is a considerable overhead introduced when hosting a WCF endpoint in WAS using a non-IIS transport like TCP. Most of this overhead is based on the extra communication betweenIIS and WAS in order to dispatch messages to the service.
To illustrate the previous statement we decided to move our service to a self-hosted environment and rerun our load test profile.
Seriously dude?….A console app is going to perform faster than WAS?
WCF Service using an optimal NetTcpBinding configuration in a self-hosted environment
For our last test scenario, we hosted our service in a simple console application to remove the extra layers of communication between WAS and IIS. The results were astonishing as illustrated below.
Are you shocked? I hope you are because we certainly were when we first saw these results :). Obviously, by self-hosting the WCF service we are sacrificing the sophisticated management capabilities of the WAS and AppFabric environments.
In a nutshell, the statement that NetTcpBinding offers you better performance than the basicHttp binding is not exactly as trivial as it seems. The load profiles executed by the SO-Aware Test Workbench clearly illustrate that the configuration and hosting aspects can seriously change the performance of a NetTcpBinding endpoint.