# `Hammer.ETS`
[🔗](https://github.com/ExHammer/hammer/blob/v7.4.0/lib/hammer/ets.ex#L1)

An ETS backend for Hammer.

To use the ETS backend, you need to start the process that creates and cleans the ETS table. The table is named after the module.

    defmodule MyApp.RateLimit do
      use Hammer, backend: :ets
    end

    MyApp.RateLimit.start_link(clean_period: :timer.minutes(1))

    # Allow 10 requests per second
    MyApp.RateLimit.hit("user_123", 1000, 10)

Runtime configuration:
- `:clean_period` - (in milliseconds) period to clean up expired entries, defaults to 1 minute
- `:key_older_than` - (in milliseconds) maximum age for entries before they are cleaned up, defaults to 1 hour
- `:algorithm` - the rate limiting algorithm to use, one of: `:fix_window`, `:fix_window_per_key`, `:sliding_window`, `:leaky_bucket`, `:token_bucket`. Defaults to `:fix_window`
- `:before_clean` - optional callback invoked with expired entries before they are deleted.
  Accepts a function `(algorithm :: atom(), entries :: [map()]) -> any()` or an MFA tuple
  `{module, function, extra_args}`. Each entry is a map with `:key`, `:value`, and `:expired_at` (ms).
  If the callback raises, entries are still deleted and a warning is logged.

    MyApp.RateLimit.start_link(
      clean_period: :timer.minutes(1),
      before_clean: fn algorithm, entries ->
        Enum.each(entries, fn entry ->
          MyApp.Telemetry.emit_expired(algorithm, entry)
        end)
      end
    )

The ETS backend supports the following algorithms:
  - `:fix_window` - Fixed window rate limiting (default)
    Simple counting within fixed time windows. See [Hammer.ETS.FixWindow](Hammer.ETS.FixWindow.html) for more details.

- `:fix_window_per_key` - Per-key fixed window rate limiting
  Like `:fix_window`, but each key's window is anchored to its first hit rather than a
  globally-aligned wall-clock boundary. See [Hammer.ETS.FixWindowPerKey](Hammer.ETS.FixWindowPerKey.html) for more details.

- `:leaky_bucket` - Leaky bucket rate limiting
  Smooth rate limiting with a fixed rate of tokens. See [Hammer.ETS.LeakyBucket](Hammer.ETS.LeakyBucket.html) for more details.

- `:token_bucket` - Token bucket rate limiting
  Flexible rate limiting with bursting capability. See [Hammer.ETS.TokenBucket](Hammer.ETS.TokenBucket.html) for more details.

# `config`

```elixir
@type config() :: %{
  table: atom(),
  table_opts: list(),
  clean_period: pos_integer(),
  key_older_than: pos_integer(),
  algorithm: module(),
  before_clean: Hammer.CleanUtils.before_clean() | nil
}
```

# `start_option`

```elixir
@type start_option() ::
  {:clean_period, pos_integer()}
  | {:table, atom()}
  | {:algorithm, module()}
  | {:key_older_than, pos_integer()}
  | {:before_clean, Hammer.CleanUtils.before_clean()}
  | GenServer.option()
```

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `now`

```elixir
@spec now() :: pos_integer()
```

# `start_link`

```elixir
@spec start_link([start_option()]) :: GenServer.on_start()
```

Starts the process that creates and cleans the ETS table.

Accepts the following options:
  - `:clean_period` - How often to run the cleanup process (in milliseconds). Defaults to 1 minute.
  - `:key_older_than` - Optional maximum age for bucket entries (in milliseconds). Defaults to 24 hours.
    Entries older than this will be removed during cleanup.
  - `:before_clean` - Optional callback invoked with expired entries before deletion.
    Accepts a function `(algorithm :: atom(), entries :: [map()]) -> any()` or an MFA tuple
    `{module, function, extra_args}`. Each entry is a map with `:key`, `:value`, and `:expired_at` (ms).
    If the callback raises, entries are still deleted and a warning is logged.
  - optional `:debug`, `:spawn_opts`, and `:hibernate_after` GenServer options

# `update_counter`

---

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