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

Hammer is a rate-limiting library for Elixir.

It provides a simple way for creating rate limiters, and comes with a built-in ETS backend.

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

    # Start the rate limiter, in case of ETS it will create the ETS table and schedule cleanups
    MyApp.RateLimit.start_link(clean_period: :timer.minutes(10))

    # Check the rate limit allowing 10 requests per second
    MyApp.RateLimit.hit("some-key", _scale = :timer.seconds(1), _limit = 10)

# `count`

```elixir
@type count() :: pos_integer()
```

# `increment`

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

# `key`

```elixir
@type key() :: term()
```

# `limit`

```elixir
@type limit() :: pos_integer()
```

# `scale`

```elixir
@type scale() :: pos_integer()
```

# `expires_at`
*optional* 

```elixir
@callback expires_at(key(), scale()) :: non_neg_integer()
```

Optional callback for getting the expiration time of the current window for a key.

Returns the expiration timestamp in milliseconds, or `0` if the key has no active window.
Only available for the `:fix_window` algorithm.

# `get`
*optional* 

```elixir
@callback get(key(), scale()) :: count()
```

Optional callback for getting the counter value for a key.

Returns the current counter value.

# `hit`

```elixir
@callback hit(key(), scale(), limit()) :: {:allow, count()} | {:deny, timeout()}
```

Checks if a key is allowed to perform an action, and increment the counter.

Same as `hit/4` with `increment` set to 1.

**Note on key types**: While this library accepts any term as a key, some 
backends may have restrictions. The Redis backend requires keys to be strings
or binary types, as it needs to serialize them for storage. The ETS and Atomic
backends support any term type.

# `hit`
*optional* 

```elixir
@callback hit(key(), scale(), limit(), increment()) ::
  {:allow, count()} | {:deny, timeout()}
```

Optional callback to check if a key is allowed to perform an action, and increment the counter.

Returns `{:allow, count}` if the action is allowed, or `{:deny, timeout}` if the action is denied.

This is the only required callback.

# `inc`
*optional* 

```elixir
@callback inc(key(), scale()) :: count()
```

Same as `inc/3` with `increment` set to 1.

# `inc`
*optional* 

```elixir
@callback inc(key(), scale(), increment()) :: count()
```

Optional callback for incrementing a counter value for a key without performing limit check.

Returns the new counter value.

# `set`
*optional* 

```elixir
@callback set(key(), scale(), count()) :: count()
```

Optional callback for setting the counter value for a key.

Returns the new counter value.

# `__using__`
*macro* 

Use the Hammer library in a module to create a rate limiter.

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

---

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