title: java httpclient 4.x performance guide to resolve issue
body: <p>There was nice article <a href="http://hc.apache.org/httpclient-3.x/performance.html" rel="nofollow">http://hc.apache.org/httpclient-3.x/performance.html</a> related to http performance, pooling, e.t.c.
  Can't find the same for the latest 4.x version. Did anyone see it? I met perf issues under heavy load and would like to resolve them.
  I'm using 4.1 version.
  Here is profiler output:</p>
  
  <pre><code>26% org.apache.http.impl.client.CloseableHttpClient.execute(multiple parameter matches) :26,107,40
  26% org.apache.http.impl.client.CloseableHttpClient.execute(org.apache.http.client.methods.HttpUriRequest, org.apache.http.protocol.HttpContext) :82,46
  26% org.apache.http.impl.client.AbstractHttpClient.doExecute(org.apache.http.HttpHost, org.apache.http.HttpRequest, org.apache.http.protocol.HttpContext) :882,818
  26% org.apache.http.impl.client.AbstractHttpClient.createHttpContext() :301
  26% org.apache.http.impl.client.AbstractHttpClient.getConnectionManager() :484
  26% org.apache.http.impl.client.AbstractHttpClient.createClientConnectionManager() :321
  26% org.apache.http.impl.conn.SchemeRegistryFactory.createDefault() :52
  26% org.apache.http.conn.ssl.SSLSocketFactory.getSocketFactory() :168
  26% org.apache.http.conn.ssl.SSLContexts.createDefault() :58
  26% javax.net.ssl.SSLContext.init(javax.net.ssl.KeyManager[], javax.net.ssl.TrustManager[], java.security.SecureRandom) :283
  26% sun.security.ssl.SSLContextImpl.engineInit(javax.net.ssl.KeyManager[], javax.net.ssl.TrustManager[], java.security.SecureRandom) :83,92
  26% javax.net.ssl.TrustManagerFactory.init(java.security.KeyStore) :250
  26% sun.security.ssl.TrustManagerFactoryImpl.engineInit(java.security.KeyStore) :51
  26% sun.security.ssl.TrustManagerFactoryImpl.getCacertsKeyStore(java.lang.String) :221
  26% java.security.KeyStore.load(java.io.InputStream, char[]) :1214
  26% sun.security.provider.JavaKeyStore$JKS.engineLoad(java.io.InputStream, char[]) :55
  26% sun.security.provider.JavaKeyStore.engineLoad(java.io.InputStream, char[]) :723,747
  26% java.security.cert.CertificateFactory.generateCertificate(java.io.InputStream) :339
  26% sun.security.provider.X509Factory.engineGenerateCertificate(java.io.InputStream) :93
  26% sun.security.provider.X509Factory.getFromCache(sun.security.util.Cache, byte[]) :203
  </code></pre>
  
  <p>I have 4 methods sending some data via HTTP using httpclient and each of these methods consume 25% of total time. The rest processing takes millis. Looks like I'm using httpclient in a wrong way.</p>
  
  <p>EDIT:
  See oleg answers + read that <a href="https://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html" rel="nofollow">https://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html</a>
  answers all realated questions</p>
  
  <p>Main parts are:
  Nice way to build pooling manager</p>
  
  <pre><code>PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
  // Increase max total connection to 200
  cm.setMaxTotal(200);
  // Increase default max connection per route to 20
  cm.setDefaultMaxPerRoute(20);
  // Increase max connections for localhost:80 to 50
  HttpHost localhost = new HttpHost("locahost", 80);
  cm.setMaxPerRoute(new HttpRoute(localhost), 50);
  
  CloseableHttpClient httpClient = HttpClients.custom()
          .setConnectionManager(cm)
          .build();
  </code></pre>
  
  <p>A way to use HttpClient concurrently</p>
  
  <pre><code>//While HttpClient instances are thread safe and can be shared
  //between multiple threads of execution, it is highly recommended that 
  //each thread maintains its own dedicated instance of HttpContext .
  
  
  static class GetThread extends Thread {
  
      private final CloseableHttpClient httpClient;
      private final HttpContext context;
      private final HttpGet httpget;
  
      public GetThread(CloseableHttpClient httpClient, HttpGet httpget) {
          this.httpClient = httpClient;
          this.context = HttpClientContext.create();
          this.httpget = httpget;
      }
  
      @Override
      public void run() {
          try {
              CloseableHttpResponse response = httpClient.execute(
                      httpget, context);
              try {
                  HttpEntity entity = response.getEntity();
              } finally {
                  response.close();
              }
          } catch (ClientProtocolException ex) {
              // Handle protocol errors
          } catch (IOException ex) {
              // Handle I/O errors
          }
      }
  
  }
  </code></pre>