The :retries plugin allows requests to be retried when errors happen.


You can set how many times a request can be retried by passing the max_retries option (or method), which by default is 3 times:

session = HTTPX.plugin(:retries)

# or
session.get(URL, max_retries: 10)


In case you need to wait before retrying again, you can use the :retry_after option, which receives the time to wait in seconds (or milliseconds, i.e. 0.5 == 500ms) after which you retry, or alternatively, a callable which receives the last failed request and returns the time to wait (in handy if you want to do exponential backoff):

session = HTTPX.plugin(:retries, retry_after: 2)

session.get(URL, retry_after: 3)
# or, for own exponential back-off
retries = 0
session.get(URL, retry_after: ->(*) { (retries += 1) * 2 })


When using the :retry_after option, some jitter will be applied to it, thereby not making the retry interval necessarily exact, but applying enough “randomness” in order to make it more resilient to “thundering herd” events.

If you would like to insert your own “jitter” calculation algorithm, you can use this option with a proc:

session = HTTPX.plugin(:retries, retry_after: 2, retry_jitter: ->(interval) { interval + rand }) # ...

(In case you would like to turn off jitter calculation altogether, you can set the following env var: HTTPX_NO_JITTER=1).


Request only get retried in a few situations.

In order for you to change the conditions under which a retry happens, you can use the :retry_on option, a callable which receives the failed response, to determine whether the request should be retried.

session = HTTPX.plugin(:retries, retry_on: ->(res) { res.error.is_a?(TimeoutError) })

session.get(URL, body: "body") # only retries if it times out...


By default, only idempotent requests are retried (GET, PUT…). If you also want, p. ex. POST requests to be retried on, you can pass this option:

session = HTTPX.plugin(:retries), body: "body", retry_on: ->(res) { res.error.is_a?(TimeoutError) }) # won't retry, because it's a POST request

# instead

session = HTTPX.plugin(:retries, retry_change_requests: true), body: "body", retry_on: ->(res) { res.error.is_a?(TimeoutError) }) # now it can be retried!


The request object has a method, #retries, which returns the number of times the request has been retried.


Unless you’re using the :retry_on option, requests will be retried only when connection type errors happen, like network errors (IOError…), TLS errors (OpenSSL::SSL::SSLError…) or timeout errors. A 500 HTTP response will, therefore, be considered a valid response.

Next: Cookies