1) Protocol and serialization format

    There are many blog and MSDN articles that discuss the serialization format and protocols that are applicable in different scenarios. In general binary serialization formats provide better latency and smaller payload sizes than their XML equivalents. And 'WCF native' bindings such as NetNamedPipeBinding and NetTcpBinding have lower communication overhead than interoperable bindings such as BasicHttpBinding. For communication with platform services we've found the following are optimal choices:

 

Recommendation:

Calls to WCF services running on localhost: NetNamedPipeBinding

Calls to WCF services running on remote machines:BinaryHttpBinding

 

2) Channel factory caching

    WCF client proxies use Channels (System.ServiceMode.InnerChannel) for communication with a remote service. A channel is created using channel factory. The creation of channel factory is an expensive operation and contributes significant overhead for calls made using a proxy. As a result WCF attempts to cache the ChannelFactory object for communication. Channel factory caching significantly reduces the overhead of WCF calls. The caching can be accidentally/unwittingly disabled if certain constructors are used for creating the proxy.

 

 Recommendations:

a) Always create WCF proxies using either the default constructor or a constructor that takes the endpointconfigurationname as parameter.

b) Don’t use the constructors of the proxy that takes Binding as an argument.

c) Don’t access the public properties ChannelFactory, Endpoint, and ClientCredentials of the proxy.

 

In experiments with the stand alone logging service client showed that avoiding the constructor that takes binding argument improves perf by almost an order of magnitude! The latency for BinaryHttp configuration dropped from 11 ms to 1 ms.

 

 

3) Reuse client proxies in a IIS thread

To further reduce the communication overheads of  a WCF client proxy sharing of proxies is recommended. Sharing a proxy object for multiple requests eliminates the connection establishment overhead. However, our performance experiments with concurrent clients sharing of proxies between multiple IIS threads can lead to contention and greatly increase the latency for calls. Restricting the sharing of proxies to calls made by a single thread eliminates this overhead. Since IIS uses a thread pool, a thread local proxy will easily get reused for requests that are assigned to same the worker thread.

 

Recommendation:

For services that are hosted in IIS, share client proxies per worker thread that are used to call other remote services.