# `BullMQ.Backoff`
[🔗](https://github.com/taskforcesh/bullmq/blob/v2.2.3/lib/bullmq/backoff.ex#L1)

Backoff strategies for job retries.

BullMQ supports various backoff strategies to control the delay between
retry attempts when jobs fail.

## Built-in Strategies

  * `:fixed` - Fixed delay between retries
  * `:exponential` - Exponentially increasing delay

## Configuration

    # Fixed backoff - 5 second delay between retries
    BullMQ.Queue.add("my_queue", "job", %{},
      connection: :redis,
      attempts: 3,
      backoff: %{type: :fixed, delay: 5_000}
    )

    # Exponential backoff - delays of 1s, 2s, 4s, 8s, etc.
    BullMQ.Queue.add("my_queue", "job", %{},
      connection: :redis,
      attempts: 5,
      backoff: %{type: :exponential, delay: 1_000}
    )

    # Exponential with jitter
    BullMQ.Queue.add("my_queue", "job", %{},
      connection: :redis,
      attempts: 5,
      backoff: %{type: :exponential, delay: 1_000, jitter: 0.2}
    )

## Custom Strategies

You can register custom backoff strategies:

    # Register a custom strategy
    BullMQ.Backoff.register(:linear, fn attempt, delay, _error, _job ->
      attempt * delay
    end)

    # Use it
    BullMQ.Queue.add("my_queue", "job", %{},
      connection: :redis,
      attempts: 5,
      backoff: %{type: :linear, delay: 1_000}
    )

# `backoff_fn`

```elixir
@type backoff_fn() :: (non_neg_integer(), non_neg_integer(), term(), map() -&gt;
                   non_neg_integer())
```

# `strategy`

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

# `calculate`

```elixir
@spec calculate(strategy(), non_neg_integer(), non_neg_integer(), keyword()) ::
  non_neg_integer()
```

Calculates the backoff delay for a given attempt.

## Parameters

  * `strategy` - Backoff strategy (`:fixed`, `:exponential`, or custom)
  * `attempt` - Current attempt number (1-based)
  * `base_delay` - Base delay in milliseconds
  * `opts` - Additional options (`:jitter`, etc.)
  * `error` - The error that caused the retry (optional)
  * `job` - The job being retried (optional)

## Returns

Returns the delay in milliseconds.

## Examples

    BullMQ.Backoff.calculate(:fixed, 3, 1000)
    #=> 1000

    BullMQ.Backoff.calculate(:exponential, 3, 1000)
    #=> 4000

    BullMQ.Backoff.calculate(:exponential, 3, 1000, jitter: 0.2)
    #=> ~4000 (with +/- 20% randomness)

# `calculate_from_config`

```elixir
@spec calculate_from_config(map(), non_neg_integer(), keyword()) :: non_neg_integer()
```

Calculates backoff from a backoff configuration map.

## Examples

    config = %{type: :exponential, delay: 1000, jitter: 0.1}
    BullMQ.Backoff.calculate_from_config(config, 3)
    #=> ~4000

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `register`

```elixir
@spec register(atom(), backoff_fn()) :: :ok
```

Registers a custom backoff strategy.

## Parameters

  * `name` - Strategy name (atom)
  * `fun` - Function that calculates delay: `(attempt, base_delay, error, job) -> delay_ms`

## Examples

    BullMQ.Backoff.register(:linear, fn attempt, delay, _error, _job ->
      attempt * delay
    end)

    BullMQ.Backoff.register(:custom, fn attempt, delay, error, job ->
      case error do
        %{retryable: false} -> 0  # Don't retry
        _ -> delay * attempt * 2
      end
    end)

# `start_link`

```elixir
@spec start_link(keyword()) :: Agent.on_start()
```

Starts the backoff strategy registry.

This is automatically started by the BullMQ application.

# `unregister`

```elixir
@spec unregister(atom()) :: :ok
```

Unregisters a custom backoff strategy.

---

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