# `WaitForIt.Backoff`
[🔗](https://github.com/jvoegele/wait_for_it/blob/2.2.1/lib/wait_for_it/backoff.ex#L1)

Backoff strategies for the `:interval` option of the waiting macros.

By default, WaitForIt polls at a constant interval. When waiting on an external or struggling
dependency, it is often better to back off — to poll less frequently as time goes on — so that
the dependency is not hammered. The `:interval` option accepts either a constant number of
milliseconds or a 1-arity function that receives the attempt number (starting at `1`) and
returns the number of milliseconds to wait before the next evaluation. The functions in this
module build such interval functions.

The configured timeout still bounds the total wait: the actual sleep before each evaluation is
the smaller of the backoff value and the time remaining before the deadline.

## Examples

    import WaitForIt

    # Exponential backoff starting at 50ms, doubling each attempt, capped at 1s, with jitter.
    wait(Repo.get(Post, id),
      timeout: :timer.seconds(30),
      interval: WaitForIt.Backoff.exponential(start: 50, max: 1_000, jitter: 0.1))

# `interval_fun`

```elixir
@type interval_fun() :: (pos_integer() -&gt; non_neg_integer())
```

A function that maps an attempt number (starting at `1`) to a delay in milliseconds.

# `constant`

```elixir
@spec constant(non_neg_integer()) :: interval_fun()
```

Returns an interval function that always waits the same number of `milliseconds`.

This is equivalent to passing the integer directly as the `:interval` option, and exists for
symmetry and readability.

# `exponential`

```elixir
@spec exponential(keyword()) :: interval_fun()
```

Returns an interval function implementing exponential backoff.

The delay for a given attempt is `start * factor ^ (attempt - 1)`, capped at `max`, with
optional random jitter applied.

## Options

  * `:start` - the delay (in milliseconds) for the first attempt (default: `50`)
  * `:max` - the maximum delay (in milliseconds); delays are capped at this value (default: `2_000`)
  * `:factor` - the multiplier applied for each successive attempt (default: `2`)
  * `:jitter` - a fraction in the range `0.0..1.0` controlling random jitter; a value of `0.1`
    varies each delay by up to ±10% (default: `0.0`, i.e. no jitter)

## Examples

    iex> backoff = WaitForIt.Backoff.exponential(start: 100, factor: 2, max: 1000)
    iex> Enum.map(1..5, backoff)
    [100, 200, 400, 800, 1000]

---

*Consult [api-reference.md](api-reference.md) for complete listing*
