Throttling in WCF

When your server is hosted out on the “big bad internet”, you need a way to make sure that you don’t get flooded with client requests. In WCF, our services support throttling as a way of mitigating potential DoS (denial of service) attacks. These throttles can also help you smooth load on your server and help enforce resource allocations. There are three service-level throttles that are controlled by ServiceThrottlingBehavior. These are in addition to any transport-specific throttles imposed by your binding. To fully understand the impact of these throttles you should also understand the threading/instancing characteristics of your service.

  1. MaxConcurrentCalls bounds the total number of simultaneous calls that we will process (default == 16). This is the only normalized throttle we have across all of the outstanding reads that the ServiceModel Dispatcher will perform on any channels it accepts. Each call corresponds to a Message received from the top of the server-side channel stack. If you set this high then you are saying that you have the resources to handle that many calls simultaneously. In practice how many calls will come in also depends on your ConcurrencyMode and InstancingMode.
  2. MaxConcurrentSessions bounds the total number of sessionful channels that we will accept (default == 10). When we hit this throttle then new channels will not be accepted/opened. Note that this throttle is effectively disabled for non-sessionful channels (such as default BasicHttpBinding).

    With TCP and Pipes, we don’t ack the preamble until channel.Open() time. So if you see clients timing out waiting for a “preamble response”, then it’s possible that the target server has reached this throttle. By default your clients will wait a full minute (our default SendTimeout), and then time out with a busy server. Your stack will look something like:

    TestFailed System.TimeoutException: The open operation did not complete within the allotted timeout of 00:01:00. The time allotted to this operation may have been a portion of a longer timeout.
    […]
    at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.SendPreamble(IConnection connection, ArraySegment`1 preamble, TimeoutHelper& timeoutHelper)

    If instead you are timing out under channel.Send (rather than channel.Open), then it’s possible that you are hitting the MaxConcurrentCalls throttle (which kicks in per-message, not per-channel).

  3. MaxConcurrentInstances bounds the total number of instances created. This throttle provides added protection in the case that you have an instance lifetime that is not tied to a call or a session (in which case it would already be bounded by the other two throttles). Orcas durable services are one such scenario.

Net-net: if you are testing your services under load, and your clients start timing out, take a look at your throttling and instancing values. On the flip side, do not just blindly set these to int.MaxValue without fully understanding the potential DoS consequences.

8 Responses to “Throttling in WCF”

  1. Tony Pujals Says:

    Good info; decided to subscribe to your blog. Just wanted to let you know the indicated RSS Indigo link isn’t working, but the following does: http://kennyw.com/category/indigo/rss

  2. Kenny Says:

    Thanks for the head’s up. Bug in wordpress upgrade, should be fixed now.

  3. De standaard waardes van ServiceHost zijn laag! - Jowen Says:

    […] verhoogd. Het is bijvoorbeeld een stuk lastiger om zo een DoS attack op je dak te krijgen (meer info). Dus zet de waarden ook weer niet te […]

  4. Alex Black Says:

    Hi Kenny, is there a way to set a timeout on an operation?

    I’ve got a WCF service, and I’ve set MaxConcurrentCalls to 4. If any individual call takes mroe than 15 seconds, I’d like WCF to kill it. The time I am interested in is once the call has started, and its processing on the server, how long it takes. I’m not interested in how long the client waited for the connection, or how long transmitting the datat took.

    Is there a feature in WCF like that?

    thanks!

    - ALex

  5. Scott Says:

    Kenny,

    I am seeing a weird behavior related to throttling and sessions that I was hoping you could explain to me. I am using the netTcpBinding, with the InstanceContextMode=Single and the ConcurrencyMode=Multiple. I hit the service with 20 simultaneous threads expecting to hit the default MaxConcurrentCalls throttle of 16, but instead I am hitting the MaxConcurrentSessions throttle of 10. Why is that when I am not using PerSession for my InstanceContextMode?

    Thanks for the help,
    -Scott

  6. Kenny Says:

    Alex, we don’t have a built-in feature to WCF like what you are asking for. You could start a timer within your service method though.

    Scott, the reason you are hitting MaxConcurrentSessions is because each TCP channel is a session, and the MaxConcurrentSessions throttle applies to the channels being accepted. It’s independent of InstanceContextMode.

  7. Streaming large content with WCF and deferred execution - Pablo M. Cibraro (aka Cibrax) Says:

    […] In addition, if the service throttling settings are not configured carefully for that service, a large number of requests will practically consume all the available resources (If that happens, the server will stop processing additional requests and you may run into a OutOfMemory exception as well). For more information about Service Throttling, I recommend this Kenny Wolf’s post. […]

  8. Victor Says:

    Hi,
    We are developping a service based application with WCF and experiencing the “MaxConcurrentSessions” issue
    The problem is that in our case calls are asynchronous and the code is generated by the WCF Proxy Generator, any idea about how to safely close the proxy?
    Thanks

    Victor

Leave a Reply