title: WCF throughput lower than expected
body: <p>I apologize for the post length, but there are lots of things that can cause my situation and I've tried to include all of the setting changes I've made based on other posts.  In short, My WCF service seems to be throttled to 3 or 4 concurrent client requests at a time.  If I set the application pool Maximum Worker Processes higher (around 10) or set the service behavior ConcurrencyMode to Multiple, I get much better throughput (several times faster). However, these seem like work-arounds to the real issue, bringing with them their own issues.  Am I mistaken, or should IIS be able to bring up many instances (dozens or more) of my WCF service inside one worker process to handle the load? I just know I'm missing a setting somewhere, but I cannot find it.  </p>
  
  <p><strong>Edit:</strong> In trying out the suggestions so far, I realized my math was off for throughput.  With the ForEach loop, I am getting an estimated concurrent processing on the server in the low 20s (per task duration * number of tasks / total run time).  This still seems low for the actual work being done (sleep 10 seconds), but no longer ridiculously low.  </p>
  
  <p><strong>Second Edit:</strong> I marked @Pablo's comment as the answer because his answer plus a link of his gave me the information to significantly boost performance (I think about 3 fold).  However, I would like to pose the follow-up question-  What is a reasonable expectation for processing concurrent requests in WCF / IIS?  Assuming CPU, memory, and IO are not bottlenecks, what is a practical limit / expectation (per CPU) for handling requests?  What I'm looking for is a rule-of-thumb that tells me that I'm probably not going to get any more big boosts without adding CPUs (or worker processes).  Thanks again.</p>
  
  <p>(On Windows 2008 Server, hosted by IIS, 1 processor)<br>
  WCF Service Config (Abbreviated):</p>
  
  <pre><code>&lt;?xml version="1.0"?&gt;
  &lt;configuration&gt;
    &lt;configSections&gt;
    &lt;system.serviceModel&gt;
      &lt;serviceHostingEnvironment multipleSiteBindingsEnabled="true"/&gt;
      &lt;services&gt;
        &lt;service name="FMHIRWCFSvc.IRService" behaviorConfiguration="IRServiceBehavior"&gt;
          &lt;endpoint address="" binding="basicHttpBinding" bindingConfiguration="Binding1" contract="FMHIRWCFSvc.IIRService" /&gt;
        &lt;/service&gt;
      &lt;/services&gt;
      &lt;bindings&gt;
        &lt;basicHttpBinding&gt;
          &lt;binding name="Binding1" maxReceivedMessageSize="104857600"&gt;
            &lt;readerQuotas maxArrayLength="104857600"/&gt;
            &lt;security mode="Transport"&gt;
              &lt;transport clientCredentialType="None"/&gt;
            &lt;/security&gt;
          &lt;/binding&gt;
        &lt;/basicHttpBinding&gt;
      &lt;/bindings&gt;
      &lt;behaviors&gt;
        &lt;serviceBehaviors&gt;
          &lt;behavior name="IRServiceBehavior"&gt;
            &lt;serviceMetadata httpsGetEnabled="true"/&gt;
            &lt;serviceDebug includeExceptionDetailInFaults="true"/&gt;
            &lt;serviceThrottling
                maxConcurrentCalls = "500"
                maxConcurrentSessions = "500"
                maxConcurrentInstances = "500"
              /&gt;
          &lt;/behavior&gt;
        &lt;/serviceBehaviors&gt;
      &lt;/behaviors&gt;
    &lt;/system.serviceModel&gt;
    &lt;applicationSettings&gt;
      &lt;FMHIRWCFSvc.Properties.Settings&gt;
        &lt;setting name="FMHIRWCFSvc_ir_dev_websvc_IRWebService40" serializeAs="String"&gt;
          &lt;value&gt;http://ir-dev-websvc/imageright.webservice/IRWebService40.asmx&lt;/value&gt;
        &lt;/setting&gt;
      &lt;/FMHIRWCFSvc.Properties.Settings&gt;
    &lt;/applicationSettings&gt;
    &lt;system.net&gt;
      &lt;connectionManagement&gt;
        &lt;add address="*" maxconnection="500"/&gt;
      &lt;/connectionManagement&gt;
    &lt;/system.net&gt;
  &lt;/configuration&gt;
  </code></pre>
  
  <p>Client Config (Abbreviated):</p>
  
  <pre><code>&lt;?xml version="1.0"?&gt;
  &lt;configuration&gt;
    &lt;startup&gt;&lt;supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/&gt;&lt;/startup&gt;
    &lt;system.serviceModel&gt;
      &lt;bindings&gt;
        &lt;basicHttpBinding&gt;
          &lt;binding name="BasicHttpBinding_IIRService" closeTimeout="00:01:00"
            openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
            allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
            maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
            messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
            useDefaultWebProxy="true"&gt;
            &lt;readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
              maxBytesPerRead="4096" maxNameTableCharCount="16384" /&gt;
            &lt;security mode="TransportCredentialOnly"&gt;
              &lt;transport clientCredentialType="Windows" /&gt;
            &lt;/security&gt;
          &lt;/binding&gt;
        &lt;/basicHttpBinding&gt;
      &lt;/bindings&gt;
      &lt;client&gt;
        &lt;endpoint address="https://{myserveraddress}/FMHIRWCFSvc/IRService.svc"
          binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IIRService"
          contract="wcf_local.IIRService" name="BasicHttpBinding_IIRService" /&gt;
      &lt;/client&gt;
    &lt;/system.serviceModel&gt;
    &lt;system.net&gt;
      &lt;connectionManagement&gt;
        &lt;add address="*" maxconnection="500"/&gt;
      &lt;/connectionManagement&gt;
    &lt;/system.net&gt;
  &lt;/configuration&gt;
  </code></pre>
  
  <p>Client Method Call:</p>
  
  <pre><code>static void WCFTesting()
  {
      ConcurrentQueue&lt;Exception&gt; exceptionList = new ConcurrentQueue&lt;Exception&gt;();
      int[] taskList = new int[250];
      Parallel.ForEach(taskList, theTask =&gt; 
      {
          try
          {
              // Create the WCF client
              BasicHttpBinding binding = new BasicHttpBinding {
                  Security = { Mode = BasicHttpSecurityMode.Transport },
                  SendTimeout = TimeSpan.FromSeconds(20)
              };
              EndpointAddress endpointAddress = new EndpointAddress("https://{myserveraddress}/FMHIRWCFSvc/IRService.svc");
              IRServiceClient wcfClient = new IRServiceClient(binding, endpointAddress);
  
              // Call wcf service method that sleeps 10 seconds and returns
              wcfClient.TestCall();
          }
          catch (Exception exception) {
              // Store off exceptions for later processing
              exceptionList.Enqueue(exception);
          }
      });
  }
  </code></pre>
  
  <p>WCF Service Code:</p>
  
  <pre><code>[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
  ...
  public string TestCall()
  {
      Thread.Sleep(10000);
      return null;
  }
  </code></pre>
  
  <p>Thanks for any insight or suggestions!</p>