     plug Tesla.Middleware.Retry,
       delay: 500,
       max_retries: 10,
+      max_delay: 4_000,
       should_retry: fn
         {:ok, %{status: status}} when status in [400, 500] -> true
         {:ok, _} -> false

  ```

  ### Options
  - `:delay`        - number of milliseconds to wait before retrying (defaults to 1000)
  - `:max_retries`  - maximum number of retries (defaults to 5)
  - `:should_retry` - function to determine if request should be retried
  """

  @defaults [
    delay: 1000,
    max_retries: 5
  ]

  @doc false
  def call(env, next, opts) do
    opts = opts || []
    delay = Keyword.get(opts, :delay, @defaults[:delay])
    max_retries = Keyword.get(opts, :max_retries, @defaults[:max_retries])
    should_retry = Keyword.get(opts, :should_retry, &match?({:error, _}, &1))

    retry(env, next, delay, max_retries, should_retry)
  end

  defp retry(env, next, _delay, retries, _should_retry) when retries <= 1 do
    Tesla.run(env, next)
  end

  defp retry(env, next, delay, retries, should_retry) do
    res = Tesla.run(env, next)

    if should_retry.(res) do
      :timer.sleep(delay)
      retry(env, next, delay, retries - 1, should_retry)
    else
      res
    end
  end
end

  @behaviour Tesla.Middleware

  @moduledoc """
  Retry using exponential backoff and full jitter. This middleware only retries in the
  case of connection errors (`nxdomain`, `connrefused` etc). Application error
  checking for retry can be customized through `:should_retry` option by
  providing a function in returning a boolean.

  ## Backoff algorithm

  The backoff algorithm optimizes for tight bounds on completing a request successfully.
  It does this by first calculating an exponential backoff factor based on the
  number of retries that have been performed. It then multiplies this factor against the
  base delay. The total maximum delay is found by taking the minimum of either the calculated delay
  or the maximum delay specified. This creates an upper bound on the maximum delay
  we can see.

  In order to find the actual delay value we take a random number between 0 and
  the maximum delay based on a uniform distribution. This randomness ensures that
  our retried requests don't "harmonize" making it harder for the downstream
  service to heal.

  ### Example
  ```
