Resilience covers areas such as retries, circuit breaking and rate limiting.

sttp client doesn’t have the above built-in, as these concepts are usually best handled on a higher level. Sending a request (that is, invoking myRequest.send(backend)), can be viewed as a:

  • () => Response[T] function for synchronous backends

  • () => Future[Response[T]] for Future-based asynchronous backends

  • IO[Response[T]]/Task[Response[T]] process description

All of these are lazily evaluated, and can be repeated. Such a representation allows to integrate the send() side-effect with a stack-dependent resilience tool. There’s a number of libraries that implement the above mentioned resilience functionalities, hence there’s no sense for sttp client to reimplement any of those. That’s simply not the scope of this library.

Still, the input for a particular resilience model might involve both the result (either an exception, or a response) and the original description of the request being sent. E.g. retries can depend on the request method; circuit-breaking can depend on the host, to which the request is sent; same for rate limiting.


Here’s an incomplete list of libraries which can be used to manage retries in various Scala stacks:

sttp client contains a default implementation of a predicate, which allows deciding if a request is retriable: if the body can be sent multiple times, and if the HTTP method is idempotent. This predicate is available as RetryWhen.Default and has type (Request[_, _], Either[Throwable, Response[_]]) => Boolean.

See also the retrying using ZIO example, as well as an example of a very simple retrying backend wrapper.

Backend-specific retries

Some backends have built-in retry mechanisms:

  • akka-http

  • OkHttp (see the builder’s retryOnConnectionFailure method)

  • async-http-client (deprecated): by default, the backend will attempt 5 retries in case an IOException is thrown during the connection. This can be changed by specifying the org.asynchttpclient.maxRequestRetry config option, or by providing custom configuration using when creating the backend (setMaxRequestRetry).

Circuit breaking

Rate limiting

Java libraries