.Net Tips — Using custom ServiceThrottlingAttribute to specify WCF service throttling behaviour

If you have cre­at­ed a WCF ser­vice in the past then I assume you’re aware that WCF is very heav­i­ly con­fig­u­ra­tion-dri­ven and that you can spec­i­fy the ser­vice behav­iour includ­ing the throt­tling para­me­ters (Max­Con­cur­rent­Calls, Max­Con­cur­rentIn­stances, Max­Con­cur­rentSes­sions) in the con­fig file.
But to spec­i­fy the type of ser­vice (Per­Call, PerS­es­sion or Sin­gle­ton) you need to apply the Ser­vice­Be­hav­iour attribute to your type.
Now, wouldn’t it be nice if you can spec­i­fy the ser­vice throt­tling behav­iour as an attribute as well rather than hav­ing to rely on con­fig files?
I can see the rea­son­ing behind putting these in the con­fig file so you don’t have to recom­pile and redis­trib­ute when­ev­er you wish­es to change the throt­tling behav­iour, but there are cer­tain edge cas­es where it war­rants the use of such attribute. For instance, my WCF ser­vices are depen­den­cy inject­ed through a cus­tom wrap­per and I want dif­fer­ent throt­tling behav­iour for each ser­vice rather than a car­pet throt­tling behav­iour which applies to all my ser­vices.


Whilst there’s no built-in Ser­viceThrot­tlin­gAt­tribute in the frame­work, you can eas­i­ly write one your­self. Here’s one I wrote the oth­er day based on Ralph Squillace’s code sam­ple here:
I made some mod­i­fi­ca­tion so you don’t HAVE TO spec­i­fy the val­ue for each type of throt­tling and will use the default val­ues where pos­si­ble.
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public sealed class ServiceThrottlingAttribute : Attribute, IServiceBehavior
    public int MaxConcurrentCalls { get; set; }
    public int MaxConcurrentInstances { get; set; }
    public int MaxConcurrentSessions { get; set; }
    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        var currentThrottle = serviceDescription.Behaviors.Find<ServiceThrottlingBehavior>();
        if (currentThrottle == null)

    private ServiceThrottlingBehavior GetConfiguredServiceThrottlingBehaviour()
        var behaviour = new ServiceThrottlingBehavior();
        if (MaxConcurrentCalls > 0)
            behaviour.MaxConcurrentCalls = MaxConcurrentCalls;
        if (MaxConcurrentInstances > 0)
            behaviour.MaxConcurrentInstances = MaxConcurrentInstances;
        if (MaxConcurrentSessions > 0)
            behaviour.MaxConcurrentSessions = MaxConcurrentSessions;

        return behaviour;


Before you go ahead and cre­ate your­self an ultra-scal­able ser­vice by set­ting the max con­cur­rent calls/sessions/instances val­ues to be very high you need to be aware what the per­for­mance impli­ca­tions are.

First, you need to know that WCF is con­fig­ured to be safe from DOS attacks out of the box and the default con­fig­u­ra­tions for ser­vice throt­tling behav­iour is very con­ser­v­a­tive:

  1. Max­Con­cur­rent­Calls - default is 16, rep­re­sents the max num­ber of mes­sages that can active­ly be processed.
  2. Max­Con­cur­rentIn­stances - default is 26. For a “PerS­es­sion” ser­vice this rep­re­sents the max num­ber of ses­sion; for a “Per­Call” ser­vice this rep­re­sents the max num­ber of con­cur­rent calls; for a “Sin­gle­ton” ser­vice this is mean­ing­less.
  3. Max­Con­cur­rentSes­sions - default is 10, rep­re­sents the max num­ber of ses­sions a ser­vice can accept at one time and only affects ses­sion-enabled chan­nels. Increase this to allow more than 10 con­cur­rent ses­sions.
Pre­ven­tion of DOS attacks aside, each con­cur­rent request your ser­vice is pro­cess­ing also requires at least a new thread to car­ry out the task. Whilst I don’t know whether WCF uses the frame­work Thread­Pool (which also has fur­ther per­for­mance impli­ca­tions, see here), there is a bal­ance between the num­ber of con­cur­rent threads and how much time the CPU spends on con­text switch­ing between the dif­fer­ent threads. Too many con­cur­rent threads and the per­for­mance starts to suf­fer as well as the response times, too few con­cur­rent threads and the CPU is under utilised, the response times suf­fer and more requests are timed out as they wait in the queue.
Accord­ing to Dan Rigsby’s blog post on throt­tling WCF ser­vices (see ref­er­ences sec­tion below), the rec­om­men­da­tions for each type of ser­vice is as fol­lows:


If your Instance­Con­text is set to “Per­Call” you should set max­Con­cur­rentSes­sions and max­Con­cur­rent­Calls to the same val­ue since each call is its own ses­sion.  You should tar­get this val­ue to be at least 25–30.  How­ev­er you shouldn’t need to go high­er than 64.

If your Instance­Con­text is set to “PerS­es­sion” you should set max­Con­cur­rent­Calls to be at least 25–30.  Your max­Con­cur­rentSes­sions should be the num­ber of users you want to have con­cur­rent­ly con­nect­ed.

If your Instance­Con­text is set to “Sin­gle” you should use the same set­tings as “PerS­es­sion”, but the max­Con­cur­rentSes­sions will only apply if ses­sion sup­port is active (this is set with the Ses­sion­Mode attribute on the Ser­vice­Con­trac­tAt­tribute).


Dan Rigsby’s blog post on thort­tling WCF ser­vices

Liked this post? Why not support me on Patreon and help me get rid of the ads!