7.5.0 - 2026-09-02
- Fix race in Atomic
TokenBucketandLeakyBucketwhere a newly created bucket was published in ETS before its atomic was initialized, so a concurrent hit could read an uninitialized bucket. Withrefill_rate: 0this lost a hit. The atomic is now initialized before it is inserted. (#202) - Fix
TokenBucketETS backend discarding the sub-token refill remainder on every allowed hit. Callers hitting faster than one token period never refilled, and callers paced at exactly the refill rate slowly starved. The stored clock now advances only by the time whose tokens were credited, so the remainder carries into the next hit. (#197) - Fix
TokenBucketETS backend returning a flat{:deny, 1000}; it now returns the real time in milliseconds until the bucket holds enough tokens to pay the cost, consistent with the other algorithms. Behaviour change: denied callers that sleep on this value will now retry much sooner (e.g. 19ms atrefill_rate: 55instead of 1000ms). Code that converts it to aretry-afterheader should round up and floor at 1 second; the tutorial examples were updated accordingly. (#198) - Add
mix hammer.installIgniter task (mix igniter.install hammer) that generates aMyApp.RateLimitmodule and adds it to the supervision tree. Supports--backend ets|atomic|redis;redisalso adds thehammer_backend_redisdependency. Igniter is an optional dependency. (#157)
7.4.1 - 2026-08-28
- Fix
TokenBucketETS backend refill using whole-second resolution, which capped sustained throughput atcapacitytokens/sec whenrefill_rate > capacity. Refill now uses millisecond resolution. (#192)
7.4.0 - 2026-05-19
- Add
:fix_window_per_keyalgorithm for ETS and Atomic backends — a fixed-window variant whose window is anchored to first hit per key instead of a globally-aligned wall-clock epoch. Same one-entry-per-key memory profile as:fix_window. The 2x boundary burst is still possible per key, but boundaries are no longer globally synchronized. (#181)
7.3.0 - 2026-03-31
- Add
expires_at/2API for fix_window algorithm (#178) - Add
before_cleancallback on bucket expiry (#177) - Fix timestamp unit mismatch in
TokenBucketandLeakyBucketclean/1(#176) - Fix race condition between
insert_newandlookupin ETShit/5(#175)
7.2.0 - 2026-02-03
- Fix race condition in
TokenBucketandLeakyBucketatomics backends by using compare-and-swap (CAS) with packed 64-bit values (#169) - Drop Elixir 1.14 support (#169)
- Add Elixir 1.19 / OTP 28 support (#169)
- Rename internal
:algorithmoption to:algorithm_modulein Atomic backend for clarity (#170)
7.1.0 - 2025-07-18
- Fix key type inconsistency in backend implementations - all backends now accept
term()keys instead ofString.t()(#143) - Add comprehensive test coverage for various key types (atoms, tuples, integers, lists, maps)
- Fix race conditions in atomic backend tests (FixWindow, LeakyBucket, TokenBucket)
- Replace timing-dependent tests with polling-based
eventuallyhelper for better CI reliability - Add documentation warning about Redis backend string key requirement
- Fix typo in
inc/3optional callback documentation (#142)
7.0.1 - 2025-03-04
- Fix race condition in Atomic backends during creation of key.
7.0.0 - 2025-02-06
- Release candidate for 7.0.0. See [./guides/upgrade-v7.md] for upgrade instructions.
7.0.0-rc.4 - 2025-01-06
- Fix Token bucket to respect custom cost
7.0.0-rc.3 - 2024-12-18
- Fix regression to support other backends
7.0.0-rc.2 - 2024-12-17
- Fix type specs for ETS backends
- Adds Atomic backends and possible algorithms
- Added
:algorithmoption to the Atomic backend with support for::fix_window(default) - Fixed time window rate limiting:leaky_bucket- Constant rate limiting with burst capacity:token_bucket- Token-based rate limiting with burst capacity
- Add benchmarks file and run them with
bench
7.0.0-rc.1 - 2024-12-13
- Improved API a little more. Should be compatibe with previous RC
- Made ETS backend more flexible with
:algorithmoption - Added
:key_older_thanoption to the ETS backend
- Made ETS backend more flexible with
- Added
:algorithmoption to the ETS backend with support for::fix_window(default) - Fixed time window rate limiting:sliding_window- Sliding time window for smoother rate limiting:leaky_bucket- Constant rate limiting with burst capacity:token_bucket- Token-based rate limiting with burst capacity
7.0.0-rc.0 - 2024-12-13
- Breaking change. Completely new API. Consider upgrading if you are experiencing performance or usability problems with Hammer v6. See [./guides/upgrade-v7.md] for upgrade instructions. https://github.com/ExHammer/hammer/pull/104
- Hammer.Plug has been removed. See documentation for using Hammer as a plug in Phoenix.
6.2.1 - 2024-02-23
- Fix issue in OTP 26 and Elixir 1.15 by not using to_existing_atom in configuration
Changed
6.2.0 - 2024-01-31
- Ensure Elixir version is ~> 1.13 https://github.com/ExHammer/hammer/pull/79.
6.1.0 - 2022-06-13
Changed
- Updgrade dependency packages
- Merged https://github.com/ExHammer/hammer/pull/41 resulting in ETC without GenServer (and therefore better performance)
- Merged https://github.com/ExHammer/hammer/pull/46 remove additional whitespace
- Updated Docs based on https://github.com/ExHammer/hammer/pull/45
- Adds CREDITS.md
6.0.0 - 2018-10-12
Changed
- Change the
ETSbackend to throw an error if eitherexpiry_msorcleanup_interval_msconfig values are missing. This should have been fixed ages ago. - Default
:pool_max_overflowchanged to0. It's a better default, given that some users have seen weird errors when using a higher overflow. In general, capacity should be increased by using a higher:pool_sizeinstead - Changed how the ETS backend does cleanups of data, should be more performant.
5.0.0 - 2018-05-18
Added
- A new
check_rate_incfunction, which allows the caller to specify the integer with which to increment the bucket by. This is useful for limiting APIs which have some notion of "cost" per call.
4.0.0 - 2018-04-23
Changed
- Use a worker-pool for the backend (via poolboy), this avoids bottle-necking all traffic through a single hammer process, thus improving throughput for the system overall
Added
- New configuration options for backends:
:pool_size, determines the number of workers in the pool (default 4):pool_max_overflow, maximum extra workers to be spawned when the system is under pressure (default 4)
- Multiple instances of the same backend! You can now have two ETS backends, fifteen Redis's, whatever you want
3.0.0 - 2018-02-20
Changed
- Require elixir >= 1.6
- Use a more sane supervision tree structure
2.1.0 2017-11-25
Changed
- Add option to use more than one backend
- Add option to suppress all logging
2.0.0 - 2017-09-24
Changed
- New, simpler API
- No longer need to start backend processes manually
- Call
Hammer.check_ratedirectly, rather thanuseing a macro
- Hammer is now an OTP application, configured via
Mix.Config
1.0.0 - 2017-08-22
Added
- Formalise backend API in
Hammer.Backendbehaviour
0.2.1 - 2017-08-10
Changed
- Minor fixes