# `ExResilience.Backoff`
[🔗](https://github.com/joshrotenberg/ex_resilience/blob/v0.4.0/lib/ex_resilience/backoff.ex#L1)

Backoff strategy implementations for retry delays.

Supports fixed, linear, and exponential strategies with optional jitter.

## Strategies

  * `:fixed` -- constant delay between attempts.
  * `:linear` -- delay increases linearly: `base * attempt`.
  * `:exponential` -- delay doubles each attempt: `base * 2^(attempt - 1)`.

## Jitter

Jitter adds randomness to avoid thundering herd effects. When enabled,
the actual delay is a random value between 0 and the computed delay.

## Examples

    iex> ExResilience.Backoff.delay(:fixed, 100, 1)
    100

    iex> ExResilience.Backoff.delay(:fixed, 100, 5)
    100

    iex> ExResilience.Backoff.delay(:linear, 100, 3)
    300

    iex> ExResilience.Backoff.delay(:exponential, 100, 1)
    100

    iex> ExResilience.Backoff.delay(:exponential, 100, 4)
    800

# `milliseconds`

```elixir
@type milliseconds() :: non_neg_integer()
```

# `strategy`

```elixir
@type strategy() :: :fixed | :linear | :exponential
```

# `delay`

```elixir
@spec delay(strategy(), milliseconds(), pos_integer()) :: milliseconds()
```

Computes the delay in milliseconds for the given strategy and attempt number.

`attempt` is 1-based.

## Examples

    iex> ExResilience.Backoff.delay(:exponential, 50, 3)
    200

# `delay_capped`

```elixir
@spec delay_capped(strategy(), milliseconds(), pos_integer(), milliseconds()) ::
  milliseconds()
```

Computes delay with an optional max cap.

The delay is clamped to `max_ms` if it would exceed it.

## Examples

    iex> ExResilience.Backoff.delay_capped(:exponential, 100, 10, 5_000)
    5000

# `delay_with_jitter`

```elixir
@spec delay_with_jitter(strategy(), milliseconds(), pos_integer()) :: milliseconds()
```

Computes delay with jitter applied.

Returns a random value in `[0, delay]`. Uses `:rand.uniform/1` internally,
so seed your PRNG if you need deterministic results.

## Examples

    iex> delay = ExResilience.Backoff.delay_with_jitter(:fixed, 100, 1)
    iex> delay >= 0 and delay <= 100
    true

---

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