diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8ddce6a91793263de45b6086f95ddc59545cec1b..4f11cc69a3b611b412bd0895fe8332e3bb957613 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,7 @@ FEATURES:
 * Added a `--enable-request-id` option to inject a request id into the upstream request [#PR392](https://github.com/gambol99/keycloak-proxy/pull/392)
 * Added the ability for the proxy to generate self-signed certificates for use via the `--enable-self-signed-tls` [#PR394](https://github.com/gambol99/keycloak-proxy/pull/394)
 * Added support for token with multiple audiences in the claims [#PR401](https://github.com/gambol99/keycloak-proxy/pull/401)
+* Added `--max-idle-connections` and `--max-idle-connections-per-host` settings to support tuning the http connection pool size for performance needs [#PR405](https://github.com/gambol99/keycloak-proxy/pull/405)
 
 BREAK CHANGES
 * Added the http-cookie-only option as default true [#PR397](https://github.com/gambol99/keycloak-proxy/pull/397)
diff --git a/README.md b/README.md
index 2bf7ffaf94619aa43be7329c6ca0710f37ba7c7e..c22c0b0f5e0c245c482b3a76099ea14e6ac053c8 100644
--- a/README.md
+++ b/README.md
@@ -124,6 +124,8 @@ GLOBAL OPTIONS:
    --upstream-response-header-timeout value  the timeout placed on the response header for upstream (default: 10s)
    --upstream-expect-continue-timeout value  the timeout placed on the expect continue for upstream (default: 10s)
    --verbose                                 switch on debug / verbose logging (default: false)
+   --max-idle-connections                    max idle upstream / keycloak connections to keep alive, ready for reuse (default: 100)
+   --max-idle-connections-per-host           limits the number of idle connections maintained per host (default: 50)
    --enabled-proxy-protocol                  enable proxy protocol (default: false)
    --server-read-timeout value               the server read timeout on the http server (default: 10s)
    --server-write-timeout value              the server write timeout on the http server (default: 10s)
diff --git a/config.go b/config.go
index 217524fdf362dcef10c7d507c486e1413c9e4f51..6418b5ad39248388706fafce15f34e9aa739ab44 100644
--- a/config.go
+++ b/config.go
@@ -46,6 +46,8 @@ func newDefaultConfig() *Config {
 		Headers:                     make(map[string]string),
 		LetsEncryptCacheDir:         "./cache/",
 		MatchClaims:                 make(map[string]string),
+		MaxIdleConns:                100,
+		MaxIdleConnsPerHost:         50,
 		OAuthURI:                    "/oauth",
 		OpenIDProviderTimeout:       30 * time.Second,
 		PreserveHost:                false,
@@ -84,6 +86,12 @@ func (r *Config) isValid() error {
 	if r.Listen == "" {
 		return errors.New("you have not specified the listening interface")
 	}
+	if r.MaxIdleConns <= 0 {
+		return errors.New("max-idle-connections must be a number > 0")
+	}
+	if r.MaxIdleConnsPerHost < 0 || r.MaxIdleConnsPerHost > r.MaxIdleConns {
+		return errors.New("maxi-idle-connections-per-host must be a number > 0 and <= max-idle-connections")
+	}
 	if r.TLSCertificate != "" && r.TLSPrivateKey == "" {
 		return errors.New("you have not provided a private key")
 	}
diff --git a/config_test.go b/config_test.go
index 19704c5e41f4b903eedd5fca850e1053cdb8c0e9..523429183340a33604aeabdeca4a7a9640ad412e 100644
--- a/config_test.go
+++ b/config_test.go
@@ -63,8 +63,44 @@ func TestIsConfig(t *testing.T) {
 				RedirectionURL: "http://120.0.0.1",
 				Upstream:       "http://120.0.0.1",
 			},
+		},
+		{
+			Config: &Config{
+				Listen:              ":8080",
+				DiscoveryURL:        "http://127.0.0.1:8080",
+				ClientID:            "client",
+				ClientSecret:        "client",
+				RedirectionURL:      "http://120.0.0.1",
+				Upstream:            "http://120.0.0.1",
+				MaxIdleConns:        100,
+				MaxIdleConnsPerHost: 50,
+			},
 			Ok: true,
 		},
+		{
+			Config: &Config{
+				Listen:              ":8080",
+				DiscoveryURL:        "http://127.0.0.1:8080",
+				ClientID:            "client",
+				ClientSecret:        "client",
+				RedirectionURL:      "http://120.0.0.1",
+				Upstream:            "http://120.0.0.1",
+				MaxIdleConns:        0,
+				MaxIdleConnsPerHost: 0,
+			},
+		},
+		{
+			Config: &Config{
+				Listen:              ":8080",
+				DiscoveryURL:        "http://127.0.0.1:8080",
+				ClientID:            "client",
+				ClientSecret:        "client",
+				RedirectionURL:      "http://120.0.0.1",
+				Upstream:            "http://120.0.0.1",
+				MaxIdleConns:        100,
+				MaxIdleConnsPerHost: 200,
+			},
+		},
 		{
 			Config: &Config{
 				Listen:         ":8080",
@@ -76,6 +112,8 @@ func TestIsConfig(t *testing.T) {
 				MatchClaims: map[string]string{
 					"test": "&&&[",
 				},
+				MaxIdleConns:        100,
+				MaxIdleConnsPerHost: 50,
 			},
 		},
 		{
@@ -83,57 +121,69 @@ func TestIsConfig(t *testing.T) {
 				Listen:                ":8080",
 				SkipTokenVerification: true,
 				Upstream:              "http://120.0.0.1",
+				MaxIdleConns:          100,
+				MaxIdleConnsPerHost:   50,
 			},
 			Ok: true,
 		},
 		{
 			Config: &Config{
-				DiscoveryURL:   "http://127.0.0.1:8080",
-				ClientID:       "client",
-				ClientSecret:   "client",
-				RedirectionURL: "http://120.0.0.1",
-				Upstream:       "http://120.0.0.1",
+				DiscoveryURL:        "http://127.0.0.1:8080",
+				ClientID:            "client",
+				ClientSecret:        "client",
+				RedirectionURL:      "http://120.0.0.1",
+				Upstream:            "http://120.0.0.1",
+				MaxIdleConns:        100,
+				MaxIdleConnsPerHost: 50,
 			},
 		},
 		{
 			Config: &Config{
-				Listen:         ":8080",
-				DiscoveryURL:   "http://127.0.0.1:8080",
-				ClientID:       "client",
-				ClientSecret:   "client",
-				RedirectionURL: "http://120.0.0.1",
+				Listen:              ":8080",
+				DiscoveryURL:        "http://127.0.0.1:8080",
+				ClientID:            "client",
+				ClientSecret:        "client",
+				RedirectionURL:      "http://120.0.0.1",
+				MaxIdleConns:        100,
+				MaxIdleConnsPerHost: 50,
 			},
 		},
 		{
 			Config: &Config{
-				Listen:         ":8080",
-				DiscoveryURL:   "http://127.0.0.1:8080",
-				ClientID:       "client",
-				ClientSecret:   "client",
-				RedirectionURL: "http://120.0.0.1",
-				Upstream:       "this should fail",
+				Listen:              ":8080",
+				DiscoveryURL:        "http://127.0.0.1:8080",
+				ClientID:            "client",
+				ClientSecret:        "client",
+				RedirectionURL:      "http://120.0.0.1",
+				Upstream:            "this should fail",
+				MaxIdleConns:        100,
+				MaxIdleConnsPerHost: 50,
 			},
 		},
 		{
 			Config: &Config{
-				Listen:         ":8080",
-				DiscoveryURL:   "http://127.0.0.1:8080",
-				ClientID:       "client",
-				ClientSecret:   "client",
-				RedirectionURL: "http://120.0.0.1",
-				Upstream:       "this should fail",
-				SecureCookie:   true,
+				Listen:              ":8080",
+				DiscoveryURL:        "http://127.0.0.1:8080",
+				ClientID:            "client",
+				ClientSecret:        "client",
+				RedirectionURL:      "http://120.0.0.1",
+				Upstream:            "this should fail",
+				SecureCookie:        true,
+				MaxIdleConns:        100,
+				MaxIdleConnsPerHost: 50,
 			},
 		},
 		{
 			Config: &Config{
-				Listen:         ":8080",
-				DiscoveryURL:   "http://127.0.0.1:8080",
-				ClientID:       "client",
-				ClientSecret:   "client",
-				RedirectionURL: "https://120.0.0.1",
-				Upstream:       "this should fail",
-				SecureCookie:   true,
+				Listen:              ":8080",
+				DiscoveryURL:        "http://127.0.0.1:8080",
+				ClientID:            "client",
+				ClientSecret:        "client",
+				RedirectionURL:      "https://120.0.0.1",
+				Upstream:            "this should fail",
+				SecureCookie:        true,
+				MaxIdleConns:        100,
+				MaxIdleConnsPerHost: 50,
 			},
 			Ok: true,
 		},
diff --git a/doc.go b/doc.go
index 9c64ace45d968762c10231cdfba55fbac4d8bd2a..16f27f5a97c1f7bb6b1bb90b741596f5c6fb1b26 100644
--- a/doc.go
+++ b/doc.go
@@ -312,6 +312,12 @@ type Config struct {
 	Verbose bool `json:"verbose" yaml:"verbose" usage:"switch on debug / verbose logging"`
 	// EnableProxyProtocol controls the proxy protocol
 	EnableProxyProtocol bool `json:"enabled-proxy-protocol" yaml:"enabled-proxy-protocol" usage:"enable proxy protocol"`
+
+	// MaxIdleConns is the max idle connections to keep alive, ready for reuse
+	MaxIdleConns int `json:"max-idle-connections" yaml:"max-idle-connections" usage:"max idle upstream / keycloak connections to keep alive, ready for reuse"`
+	// MaxIdleConnsPerHost limits the number of idle connections maintained per host
+	MaxIdleConnsPerHost int `json:"max-idle-connections-per-host" yaml:"max-idle-connections-per-host" usage:"limits the number of idle connections maintained per host"`
+
 	// ServerReadTimeout is the read timeout on the http server
 	ServerReadTimeout time.Duration `json:"server-read-timeout" yaml:"server-read-timeout" usage:"the server read timeout on the http server"`
 	// ServerWriteTimeout is the write timeout on the http server
diff --git a/server.go b/server.go
index 7f0c1739dabdf83e6110269dc06ee4398e1dbfcd..b6fa409572421a07d09f240abef0e1387945410e 100644
--- a/server.go
+++ b/server.go
@@ -613,6 +613,8 @@ func (r *oauthProxy) createUpstreamProxy(upstream *url.URL) error {
 		ResponseHeaderTimeout: r.config.UpstreamResponseHeaderTimeout,
 		TLSClientConfig:       tlsConfig,
 		TLSHandshakeTimeout:   r.config.UpstreamTLSHandshakeTimeout,
+		MaxIdleConns:          r.config.MaxIdleConns,
+		MaxIdleConnsPerHost:   r.config.MaxIdleConnsPerHost,
 	}
 
 	return nil