Timeouts

Apache Pekko HTTP comes with a variety of built-in timeout mechanisms to protect your servers from malicious attacks or programming mistakes. Some of these are simply configuration options (which may be overridden in code) while others are left to the streaming APIs and are easily implementable as patterns in user-code directly.

Common timeouts

Connection-level idle timeout

The idle-timeout is a setting which sets the maximum inactivity time of a given connection. If no data is sent or received on a connection for over idle-timeout time, the connection will be automatically closed.

This setting should be used as a last-resort safeguard to prevent unused or stuck connections from consuming resources for an indefinite time.

The setting works the same way for server and client connections and it is configurable independently using the following keys:

pekko.http.server.idle-timeout
pekko.http.client.idle-timeout
pekko.http.host-connection-pool.client.idle-timeout

Server timeouts

Request timeout

Request timeouts are a mechanism that limits the maximum time it may take to produce an HttpResponseHttpResponse from a route. If that deadline is not met the server will automatically inject a Service Unavailable HTTP response and close the connection to prevent it from leaking and staying around indefinitely (for example if by programming error a Future would never complete, never sending the real response otherwise).

The default HttpResponseHttpResponse that is written when a request timeout is exceeded looks like this:

sourceHttpResponse(StatusCodes.ServiceUnavailable,
  entity = "The server was not able " +
    "to produce a timely response to your request.\r\nPlease try again in a short while!")

A default request timeout is applied globally to all routes and can be configured using the pekko.http.server.request-timeout setting (which defaults to 20 seconds).

The request timeout can be configured at run-time for a given route using the any of the TimeoutDirectives.

Bind timeout

The bind timeout is the time period within which the TCP binding process must be completed (using any of the Http().bind* methods). It can be configured using the pekko.http.server.bind-timeout setting.

Linger timeout

The linger timeout is the time period the HTTP server implementation will keep a connection open after all data has been delivered to the network layer. This setting is similar to the SO_LINGER socket option but does not only include the OS-level socket but also covers the Appache Pekko IO and Streams network stack. The setting is an extra precaution that prevents clients from keeping open a connection that is already considered completed from the server side.

If the network level buffers (including the Appache Pekko IO and Streams networking stack buffers) contains more data than can be transferred to the client in the given time when the server-side considers to be finished with this connection, the client may encounter a connection reset.

Set to infinite to disable automatic connection closure (which will risk to leak connections).

Client timeouts

Connecting timeout

The connecting timeout is the time period within which the TCP connecting process must be completed. Tweaking it should rarely be required, but it allows erroring out the connection in case a connection is unable to be established for a given amount of time.

It can be configured using the pekko.http.client.connecting-timeout setting.

Client pool timeouts

Keep-alive timeout

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).

Connection Lifetime timeout

This timeout configures a maximum amount of time, while the connection can be kept open. This is useful, when you reach the server through a load balancer and client reconnecting helps the process of rebalancing between service instances.

It can be configured using the pekko.http.host-connection-pool.max-connection-lifetime setting.

Pool Idle timeout

A connection pool to a target host will be shut down after the timeout given as pekko.http.host-connection-pool.idle-timeout. This frees resources like open but idle pool connections and management structures.

If the application connects to only a limited set of target hosts over its lifetime and resource usage for the pool is of no concern, the idle-timeout can be completely disabled by setting it to infinite.

A pool will be automatically reestablished when a new request comes in for a target host.