# `Oban.Pruner`
[🔗](https://github.com/oban-bg/oban/blob/v2.24.2/lib/oban/pruner.ex#L1)

Periodically delete `completed`, `cancelled`, and `discarded` jobs based on their age.

Pruning is critical for maintaining table size and continued responsive job processing. It
is recommended for all production applications. See also the
[*Operational Maintenance* guide](operational_maintenance.html).

> #### 🌟 Oban Pro's Pruner {: .info}
>
> This plugin is limited to a fixed interval and a single `max_age` check for all jobs. To prune
> on a cron-style schedule, retain jobs by a limit or age, provide override rules for select
> queues/workers/states, and automatically archive select jobs, see
> [`Oban.Pro.Pruner`](https://oban.pro/docs/pro/Oban.Pro.Pruner.html).

## Using the Plugin

The following example demonstrates using the plugin without any configuration, which will prune
jobs older than the default of 60 seconds:

    config :my_app, Oban,
      pruner: Oban.Pruner,
      ...

Override the default options to prune jobs after 1 day:

    config :my_app, Oban,
      pruner: [max_age: {1, :day}],
      ...

## Options

* `:interval` — the time between pruning attempts, as either an integer number of milliseconds
  or an `Oban.Period` tuple like `{30, :seconds}`. The default is `30_000ms`.

* `:limit` — the maximum number of jobs to prune at one time. The default is 10,000 to prevent
  request timeouts. Applications that steadily generate more than 10k jobs a minute should
  increase this value.

* `:max_age` — how long to keep jobs before they may be pruned, as either an integer number of
  seconds or an `Oban.Period` tuple like `{1, :day}`. Defaults to 60s.

## Instrumenting with Telemetry

The `Oban.Pruner` plugin adds the following metadata to the `[:oban, :plugin, :stop]` event:

* `:pruned_jobs` - the jobs that were deleted from the database

When a run can't reach the database the list is empty, the count is zero, and an `:error` is
added to the metadata, as described in `Oban.Telemetry`.

_Note: jobs only include `id`, `queue`, `state` fields._

# `option`

```elixir
@type option() ::
  Oban.Plugin.option()
  | {:interval, Oban.Period.t()}
  | {:limit, pos_integer()}
  | {:max_age, Oban.Period.t()}
```

