A bit of a divergence away from Azure today. I had two questions I wanted to answer before running comparison of performance in Azure.

I received some requests for some down-loadable source. It can be downloaded here: NetTcpBindingExample

How fast can WCF go? How about ~29,000 requests per second?

Ah, the eternal question… The benefit of finding the answer is that it puts some sanity checks in place whenever we are planning our architecture. If a business user wants to have two million transactions processed in a minute can you do this with WCF? What about 1 hour? What about 24 hours? Somewhere in there is a “yes we can do this”, but alas, unless you read on you wont know where to start…

Further if you don’t know the absolute fastest WCF can perform how do you know if you are running ‘slow’ or ‘good’. What about how many servers you may need? Baselines are great tools… read on…

WCF Binding Comparisons

Below charts show the comparison of basicHttpBinding, binaryHttpBinding, and netTcpBinding.

One Way Operations with Basic String (Calls Made Per Second)
Compare2

Large Object Operation with Complex Object (Calls Made Per Second)
Compare

By far the best channel is netTcpBinding for performance – both for large objects and one-way operations. You’ll note the benefit of binaryHttpBinding over basicHttpBinding is not apparent when dealing with small objects. This makes sense considering the network savings aren’t in play for our simple string operation.

The Service Tested

To answer “the fastest” question and to do sanity checks the below was the service interface created.

[ServiceBehavior(
    ConcurrencyMode=ConcurrencyMode.Multiple,
    InstanceContextMode=InstanceContextMode.Single,
    AddressFilterMode=AddressFilterMode.Any)]
public class HelloWorldService : IHelloWorldService
{
    public void MockOneWayOperation(string name)
    {
          // do absolutely nothing
    }

    public CompositeType MockTwoWayOperation(CompositeType composite)
    {
        return composite;
    }
}

You will note that this service does absolutely nothing. We took out database calls, or any other dependency… Its the simplest and most pure service ever… you can’t make a faster service so it’s good in that it eliminates any external dependency (save network).

It is recommended that you always call Channel.Open()

On top of just the binding chosen you have one more thing to worry about (well two to be exact). If you are calling a WCF service please be sure to call yourclient.open(); explicitly before actually calling a service operation.

Calling svc.Open() on netTcpBinding helps, please do it… your mom will thank you
netTcpBinding_Small

Calling svc.Open() on WCF BasicHttpBinding helps a lot as you can see below
BasicHttpBinding_Small

Configuration of net.tcp when running in port sharing mode:
http://msdn.microsoft.com/en-us/library/aa702669.aspx

Note: When running your WCF services in netTcpBinding using port sharing the configuration of the netTcpBinding is ignored. You must change these settings as described in the above MSDN document to get maximum throughput.

My performance isn’t that good?! What voodoo are you using?!

Please be sure when running your tests you answer NO to both these questions:

Is your web.config in debug mode?
Is your test client running in debug?

Running with any of the above is a recipe for disappointment. As an example of how much of a disappointment you are in for, the below chart shows the potential performance hit you will take if you have either the server or the client in debug (or both).

Keep in mind this is the same high performance netTcpBinding!

The only thing I am doing here is running the service in debug and the client tester (VS Unit Test) in debug.

Note the extreme difference in performance when client is running in debug
debug

When measuring performance please be sure your WCF service is not running in debug (web.config) and your client is not running in debug. If you are using a Visual Studio Unit Test for quick performance evaluation be sure to run the unit test as “Run Selection”, not “Debug Selection”.

Measurements

table

As you can see the running debug+debug without server GC on the fastest WCF binding will cause you to be running 29x slower than you would otherwise expect.

Maximum Performance WCF netTcpBinding Configuration…

No security, no reliable sessions, max serialization, max listen backlog.

  <system.serviceModel>
    <services>
      <service name="NetTcpBindingExample.HelloWorldService">
        <endpoint
            binding="netTcpBinding"
            bindingConfiguration="ultra"
            contract="NetTcpBindingExample.IHelloWorldService"/>
      </service>
    </services>
    <bindings>
      <netTcpBinding>
        <binding name="ultra"
                 maxBufferPoolSize="2147483647"
                 maxBufferSize="2147483647"
                 maxConnections="2147483647"
                 maxReceivedMessageSize="2147483647"
                 portSharingEnabled="false"
                 transactionFlow="false"
                 listenBacklog="2147483647">
          <security mode="None">
            <message clientCredentialType="None"/>
            <transport protectionLevel="None" clientCredentialType="None"/>
          </security>
          <reliableSession enabled="false"/>
        </binding>
      </netTcpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
  <system.web>
    <compilation debug="false"/>
  </system.web>
  <runtime>
    <gcServer enabled="true"/>
  </runtime>
 

15 Responses to High Performance WCF Services : netTcpBinding

  1. Alik Levin says:

    very nice! i love the flow and the details. it goes to my personal KB under WCF/Perf ;)

  2. [...] This post was mentioned on Twitter by Solidsoft. Solidsoft said: Terrance A. Snyder: It is important to note that when running your wcf services in net.tcp you're configuratio… http://bit.ly/b4vTq0 #WCF [...]

  3. James Wilson says:

    Excellent article! Your conclusions are well documented and the article is very down-to-earth and easy to understand. Well done.

  4. Tom Boring says:

    Great article! Jim (Wilson) had always told us (the folk he USED to work with) how fast netTCP was, but he never proved it. Of course, we trusted him…but then he left to work for some other company.

    • Sorry to hear about the loss of a valuable member. Always come prepared to back things up with metrics and for management types always show the classic bar chart of performance. Reduce the decision down to one slide and make it obvious what to do.

  5. k9 says:

    nice article , I try to use the same netTcpBinding “ultra” for the client side proxy configuration and I had some errors relates to out of memory issues .

  6. Very clear, I am going to use it.

  7. Konstantin says:

    Hi, Terrance!
    I wonder, what was the hardware you used to perform that benchmarks?

    Did you used a gigabit network between client and server? How many CPU codes were in the server?

    Thanks in advance.

    • A simple Dual-core LGA995. Windows 2003 Server. Tests were run locally so client and server were running on same to remove network from equation. This was merely a test for “the fastest possible” on a CPU side. Of course smaller objects being transmitted would also mean that the binary would also be more efficient.

      Thats the great thing about WCF, you can have both on at the same time (at least in Windows 2003 R2) so for internal communications use binary and external using SOAP/XML.

  8. Gustavo says:

    Hi Terrance, this is an interesting article. However I have a question, in the test you seem to be reusing the client in all the requests, and in real life, I would be creating a new client everytime I need to call the service. Do you know how creating a new client per request would impact the performance/numbers?
    Thanks

  9. [...] excellent article on WCF performance, from Terrance A. Snyder, shows the performance of various binding options in [...]

  10. Maxim says:

    Hi,

    Great article!

    About the .Open() – Do you mean to call it on the ChannelFactory or on the Client proxy?

    Do you have an idea what the .Open() method does?

Leave a Reply

Your email address will not be published. Required fields are marked *

*


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Set your Twitter account name in your settings to use the TwitterBar Section.