Configuring WCF Throttling Behaviors

Most WCF services hosted in a live environment if not configured for handling heavy simultaneous requests give a Denial of Service Error, better known as DoS attacks. To prevent these from happening we have to configure the throttling behavior and some attributes of the ServiceHost.

In this article we try to understand and configure each throttling setting of a WCF service and how it affects the execution of the service.

Building a Service

To test this we build a small sample self hosted WCF service. Refer Data Transfer Using Self Hosted WCF Service for more details on how to host an efficient self hosted WCF service for high volumes of data. Configure the service endpoint for a WSHttpBinding as shown in the code.

Show Code

The operation performed will be a simple Thread.SpinWait() which will keep the CPU busy. This way we simulate some kind of work. You could perform some actual task here if you prefer.

Show Code

Building the Client

Now to simulate a client environment that makes concurrent requests to the service we thread requests as shown below. Create a new channel in each thread to consume the service. This will act as multiple clients consuming the service independently.

Show Code

Also to simulate continuous requests we repeat the calls after each second. This way we generate 10 calls per second.

Configuring the Service

Now to achieve the main objective of this article, setting up the service for handling concurrent requests.

ConcurrencyMode is the most important setting. We need to set this to ConcurrencyMode.Multiple. This configures the ServiceHost to process multiple requests concurrently. By default it is single, meaning all calls will be processed sequentially.

InstanceContextMode is used to specify whether a new instance or object should be created for handling each call to the service. If you want all the calls to be processed using a single object set this as Single. PerCall and PerSession create a new instance or object for each call or for each session respectively. The number of instances created depends upon the throttling values MaxConcurrentCalls for PerCall and MaxConcurrentSessions for PerSession. So set this according to your need.

MaxConcurrentSessions sets the number of concurrent sessions that will be created for a ServiceHost object. This setting is valid only for bindings that support sessions. Keeping the InstanceContextMode as PerSession we can control the number of sessions that are created concurrently. The default value is 10. For more details on sessions in WCF, refer Using Sessions

MaxConcurrentCalls sets the number of calls that a ServiceHost object will accept concurrently. However if MaxConcurrentCalls is set to some value N and MaxConcurrentSessions is set to a value less than N, and then it might cause a bottleneck. As there are more calls than sessions created it will cause some client requests to get queued up, as new sessions cannot be created. So it is advisable to keep the two values MaxConcurrentCalls and MaxConcurrentSessions equal.

MaxConcurrentInstances is more of a derived value. If InstanceContextMode is PerSession then MaxConcurrentInstances will be same as MaxConcurrentSessions. Similrly if InstanceContextMode is PerCall then MaxConcurrentInstances will be same as MaxConcurrentCalls. However this is valid only in case of ConcurrencyMode is set to Multiple.

Calculating Optimal Throttling

Finally just a little tip in order to help you configure your applications services. We will try to find out what should be the optimal setting for MaxConcurrentCalls and MaxConcurrentSessions for handling multiple concurrent calls.

I have used the word concurrent calls quite a lot in this article. So to start off let me clear out what concurrent calls mean. When a service receives a call when some other call is still open, then they can be termed as concurrent calls.

The best setting depends on 2 factors

  1. Number of concurrent calls your service receives.
  2. Execution time for each call.

So in our sample, we receive 10 calls per second and execution time for the service method is 2 seconds. While the service is processing the first call we will receive 19 other calls.

The exact safe setting in this case would be 10 x 2 = 20. In a live scenario you might want to add a 20% buffer to this and make it 24.

Show Code

Another way of setting concurrency mode is by specifying it during class definition as shown below.

Show Code

You can specify throttling using config file by modifying the behavious tag

Show Code

However this is just a suggestion. You may find many better ways to determine this setting.

Download Sample
ThrottlingTest.zip

  1. Hi Rohan!

    This works fine, as far as the Method you call isn’t returning anything… But if the return type isn’t void, the response-times go higher and higher. Do you have any idea why this is happening? Or do you know anything i can do to make it faster? IIS Hosting is no option :(

    Kind regards,
    Halko

  2. Hi Halko,

    Your problem occurs because each client that invokes the service waits for a response or a return value, meaning that the connection is still open as the service method gets executed.
    If the method takes a long time to execute you will have a problem of more concurrent service calls happening. I suspect this is the problem you are facing.
    As I have mentioned in my post the method I have proposed is just a suggestion, you might have to play around with these setting a bit more to fine tune your application. Best of luck.

    • niko78
    • April 16th, 2010 12:10pm

    Hi:
    Don’t host this sample in Windows Form Application, i don’t know why but not work. It must be Console or Windows Service.

    Thanks, it help me to much !!
    Nicolas

    • Parikshit Sehgal
    • August 19th, 2010 5:32pm

    @Halko
    Use async call in that way code need not to wait for response. Hope this resolves your issue.

  1. No trackbacks yet.

Spam protection by WP Captcha-Free