Configuration

HTTP client settings are split into different sections

  • pekko.http.client: basic client settings
  • pekko.http.host-connection-pool: pool settings

Basic Client Settings

These settings influence the basic library behavior for each HTTP connection. When changed in the application’s application.conf they globally affect the default client behavior.

Basic client settings can be overridden in multiple ways:

sourceclient {
  # The default value of the `User-Agent` header to produce if no
  # explicit `User-Agent`-header was included in a request.
  # If this value is the empty string and no header was included in
  # the request, no `User-Agent` header will be rendered at all.
  user-agent-header = pekko-http/${pekko.http.version}

  # The time period within which the TCP connecting process must be completed.
  connecting-timeout = 10s

  # The time after which an idle connection will be automatically closed.
  # Set to `infinite` to completely disable idle timeouts.
  idle-timeout = 60 s

  # The initial size of the buffer to render the request headers in.
  # Can be used for fine-tuning request rendering performance but probably
  # doesn't have to be fiddled with in most applications.
  request-header-size-hint = 512

  # Socket options to set for the listening socket. If a setting is left
  # undefined, it will use whatever the default on the system is.
  socket-options {
    so-receive-buffer-size = undefined
    so-send-buffer-size = undefined
    so-reuse-address = undefined
    so-traffic-class = undefined
    tcp-keep-alive = undefined
    tcp-oob-inline = undefined
    tcp-no-delay = undefined
  }

  # Client https proxy options. When using ClientTransport.httpsProxy() with or without credentials,
  # host/port must be either passed explicitly or set here. If a host is not set, the proxy will not be used.
  proxy {
    https {
      host = ""
      port = 443
    }
  }

  # Modify to tweak parsing settings on the client-side only.
  parsing {
    # no overrides by default, see `pekko.http.parsing` for default values

    # Default maximum content length which should not be exceeded by incoming response entities.
    # Can be changed at runtime (to a higher or lower value) via the `HttpEntity::withSizeLimit` method.
    # Note that it is not necessarily a problem to set this to a high value as all stream operations
    # are always properly backpressured.
    #
    # On the client-side, this limit is disabled by default because a client controls the requests it runs.
    #
    # Set to `infinite` to completely disable entity length checks. (Even then you can still apply one
    # programmatically via `withSizeLimit`.)
    max-content-length = infinite
  }

  # Enables/disables the logging of unencrypted HTTP traffic to and from the HTTP
  # client for debugging reasons.
  #
  # Note: Use with care. Logging of unencrypted data traffic may expose secret data.
  #
  # Incoming and outgoing traffic will be logged in hexdump format. To enable logging,
  # specify the number of bytes to log per chunk of data (the actual chunking depends
  # on implementation details and networking conditions and should be treated as
  # arbitrary).
  #
  # For logging on the server side, see pekko.http.server.log-unencrypted-network-bytes.
  #
  # `off` : no log messages are produced
  # Int   : determines how many bytes should be logged per data chunk
  log-unencrypted-network-bytes = off

  websocket {
    # periodic keep alive may be implemented using by sending Ping frames
    # upon which the other side is expected to reply with a Pong frame,
    # or by sending a Pong frame, which serves as unidirectional heartbeat.
    # Valid values:
    #   ping - default, for bi-directional ping/pong keep-alive heartbeating
    #   pong - for uni-directional pong keep-alive heartbeating
    #
    # See https://tools.ietf.org/html/rfc6455#section-5.5.2
    # and https://tools.ietf.org/html/rfc6455#section-5.5.3 for more information
    periodic-keep-alive-mode = ping

    # Interval for sending periodic keep-alives
    # The frame sent will be the one configured in pekko.http.server.websocket.periodic-keep-alive-mode
    # `infinite` by default, or a duration that is the max idle interval after which an keep-alive frame should be sent
    periodic-keep-alive-max-idle = infinite

    # Enable verbose debug logging for all ingoing and outgoing frames
    log-frames = false
  }

  # Cancellation in the HTTP streams is delayed by this duration to prevent race conditions between cancellation
  # and stream completion / failure. In most cases, the value chosen here should make no difference because
  # HTTP streams are loops where completion and failures should propagate immediately and make the handling of
  # cancellations redundant.
  #
  # In most cases, there should be no reason to change this setting.
  #
  # Set to 0 to disable the delay.
  stream-cancellation-delay = 100 millis
}

Pool Settings

Pool settings influence the behavior of client connection pools as used with APIs like Http.singleRequest (see request-level and host-level).

This includes the amount of total concurrent connections a pool should open to a target host and other settings. These settings include a (by default empty) section client that can be used to override basic client settings when used in the context of a pool.

Pool settings can be overridden on a per-target-host basis.

sourcehost-connection-pool {
  # The maximum number of parallel connections that a connection pool to a
  # single host endpoint is allowed to establish. Must be greater than zero.
  max-connections = 4

  # The minimum number of parallel connections that a pool should keep alive ("hot").
  # If the number of connections is falling below the given threshold, new ones are being spawned.
  # You can use this setting to build a hot pool of "always on" connections.
  # Default is 0, meaning there might be no active connection at given moment.
  # Keep in mind that `min-connections` should be smaller than `max-connections` or equal
  min-connections = 0

  # The maximum number of times failed requests are attempted again,
  # (if the request can be safely retried) before giving up and returning an error.
  # Set to zero to completely disable request retries.
  max-retries = 5

  # The maximum number of open requests accepted into the pool across all
  # materializations of any of its client flows.
  # Protects against (accidentally) overloading a single pool with too many client flow materializations.
  # Note that with N concurrent materializations the max number of open request in the pool
  # will never exceed N * max-connections * pipelining-limit.
  # Must be a power of 2 and > 0!
  max-open-requests = 32

  # The maximum duration for a connection to be kept alive
  # This amount gets modified by a 10 percent fuzzyness to avoid the simultanous reconnections
  # defaults to 'infinite'
  # Note that this is only implemented in the new host connection pool
  max-connection-lifetime = infinite

  # Client-side pipelining is not currently supported. See https://github.com/apache/pekko-http/issues/32
  pipelining-limit = 1

  # The minimum duration to backoff new connection attempts after the previous connection attempt failed.
  #
  # The pool uses an exponential randomized backoff scheme. After the first failure, the next attempt will only be
  # tried after a random duration between the base connection backoff and twice the base connection backoff. If that
  # attempt fails as well, the next attempt will be delayed by twice that amount. The total delay is capped using the
  # `max-connection-backoff` setting.
  #
  # The backoff applies for the complete pool. I.e. after one failed connection attempt, further connection attempts
  # to that host will backoff for all connections of the pool. After the service recovered, connections will come out
  # of backoff one by one due to the random extra backoff time. This is to avoid overloading just recently recovered
  # services with new connections ("thundering herd").
  #
  # Example: base-connection-backoff = 100ms, max-connection-backoff = 10 seconds
  #   - After 1st failure, backoff somewhere between 100ms and 200ms
  #   - After 2nd, between  200ms and  400ms
  #   - After 3rd, between  200ms and  400ms
  #   - After 4th, between  400ms and  800ms
  #   - After 5th, between  800ms and 1600ms
  #   - After 6th, between 1600ms and 3200ms
  #   - After 7th, between 3200ms and 6400ms
  #   - After 8th, between 5000ms and 10 seconds (max capped by max-connection-backoff, min by half of that)
  #   - After 9th, etc., stays between 5000ms and 10 seconds
  #
  # This setting only applies to the new pool implementation and is ignored for the legacy one.
  base-connection-backoff = 100ms

  # Maximum backoff duration between failed connection attempts. For more information see the above comment for the
  # `base-connection-backoff` setting.
  #
  # This setting only applies to the new pool implementation and is ignored for the legacy one.
  max-connection-backoff = 2 min

  # The time after which an idle connection pool (without pending requests)
  # will automatically terminate itself. Set to `infinite` to completely disable idle timeouts.
  idle-timeout = 30 s

  # HTTP connections are commonly used for multiple requests, that is, they are kept alive between requests. The
  # `pekko.http.host-connection-pool.keep-alive-timeout` setting configures how long a pool keeps a connection alive between
  # requests before it closes the connection (and eventually reestablishes it).
  #
  # A common scenario where this setting is useful is to prevent a race-condition inherent in HTTP: in most cases, a server
  # or reverse-proxy closes a persistent (kept-alive) connection after some time. HTTP does not define a protocol between
  # client and server to negotiate a graceful teardown of an idle persistent connection. Therefore, it can happen that a server decides to
  # close a connection at the same time that a client decides to send a new request. In that case, the request will fail to be processed,
  # but the client cannot determine for which reason the server closed the connection and whether the request was (partly) processed or not.
  # Such a condition can be observed when a request fails with an `UnexpectedConnectionClosureException` or a `StreamTcpException` stating
  # "Connection reset by peer".
  #
  # To prevent this from happening, you can set the timeout to a lower value than the server-side keep-alive timeout
  # (which you either have to know or find out experimentally).
  #
  # Set to `infinite` to allow the connection to remain open indefinitely (or be closed by the more general `idle-timeout`).
  keep-alive-timeout = infinite

  # The pool implementation will fail a connection early and clear the slot if a response entity was not
  # subscribed during the given time period after the response was dispatched. In busy systems the timeout might be
  # too tight if a response is not picked up quick enough after it was dispatched by the pool.
  response-entity-subscription-timeout = 1.second

  # Modify this section to tweak client settings only for host connection pools APIs like `Http().superPool` or
  # `Http().singleRequest`.
  client = {
    # no overrides by default, see `pekko.http.client` for default values
  }

  # Allows overriding settings per host. The setting must be a list in which each entry
  # is an object with a `host-pattern` entry that specifies for which hosts the overrides
  # should take effect. All other entries have the same syntax as entries in the
  # `host-connection-pool` section.
  #
  # The `host-pattern` can have these forms:
  #  * `regex:<pattern>`: the host name is matched against the regular expression pattern
  #  * `glob:<glob-pattern>` or just `<glob-pattern>`: the host is matched against the given
  #    pattern. In the pattern the wildcard `*` stands for zero or more characters and `?`
  #    for any single character
  #
  # In both cases, a pattern that matches `*.` at the beginning, i.e. every subdomain,
  # is expanded to also cover the domain itself (without the leading dot).
  #
  # If patterns from multiple entries in the list are matched, only settings from the
  # first entry found are applied.
  #
  # Example:
  #
  # per-host-override = [
  # {
  #   host-pattern = "pekko.apache.org"
  #   # Use the same entries as in the `host-connection-pool` section
  #   max-connections = 10
  # },
  # {
  #   # `*.apache.org` matches all subdomains like `repo.apache.org` but also `apache.org` itself.
  #   # `pekko.apache.org` is already covered by a previous entry, so these settings here
  #   # will not apply to `pekko.apache.org`.
  #   host-pattern = "*.apache.org"
  #   max-connections = 11
  # }
  # ]
  per-host-override = []

}

Per Host Overrides

Settings can be overridden on a per-host basis by creating a list of host-patterns together with overridden settings in the pekko.http.host-connection-pool.per-host-override setting.

Note that only the first matching entry is selected and used even if multiple entries would match.

source# Allows overriding settings per host. The setting must be a list in which each entry
# is an object with a `host-pattern` entry that specifies for which hosts the overrides
# should take effect. All other entries have the same syntax as entries in the
# `host-connection-pool` section.
#
# The `host-pattern` can have these forms:
#  * `regex:<pattern>`: the host name is matched against the regular expression pattern
#  * `glob:<glob-pattern>` or just `<glob-pattern>`: the host is matched against the given
#    pattern. In the pattern the wildcard `*` stands for zero or more characters and `?`
#    for any single character
#
# In both cases, a pattern that matches `*.` at the beginning, i.e. every subdomain,
# is expanded to also cover the domain itself (without the leading dot).
#
# If patterns from multiple entries in the list are matched, only settings from the
# first entry found are applied.
#
# Example:
#
# per-host-override = [
# {
#   host-pattern = "pekko.apache.org"
#   # Use the same entries as in the `host-connection-pool` section
#   max-connections = 10
# },
# {
#   # `*.apache.org` matches all subdomains like `repo.apache.org` but also `apache.org` itself.
#   # `pekko.apache.org` is already covered by a previous entry, so these settings here
#   # will not apply to `pekko.apache.org`.
#   host-pattern = "*.apache.org"
#   max-connections = 11
# }
# ]
per-host-override = []

Precedence of settings

When using pool APIs, settings take precedence like this (highest precedence first):

  • client settings in first per-host-override entry whose host-pattern matches the given target host
  • settings in pekko.http.host-connection-pool.client
  • settings in pekko.http.client