Malachi.RateLimiter (malachi v0.8.13)

View Source

Token bucket rate limiter using ETS for high-performance limits. Tracks requests per IP/user across different actions.

Schema

The ETS table stores three types of entries:

  • {{identifier, action}, {count, last_refill_ms, window_start_ms}} - Token buckets
  • {{:blocked, identifier, action}, count} - Blocked request counters

Actions

  • :auth - Authentication attempts (tracked by IP)
  • :publish - Message publishing (tracked by username)
  • :subscribe - Queue subscriptions (tracked by username)

Configuration

Set via environment variables or runtime config:

  • rate_limit_enabled - Enable/disable rate limiting (default: true)
  • auth_rate_limit - Max auth attempts per window (default: 10)
  • auth_rate_window_ms - Auth window duration (default: 60000)
  • publish_rate_limit - Max publish per window (default: 1000)
  • publish_rate_window_ms - Publish window duration (default: 1000)
  • subscribe_rate_limit - Max subscribe per window (default: 100)
  • subscribe_rate_window_ms - Subscribe window duration (default: 60000)
  • rate_limit_cleanup_interval_ms - Cleanup interval (default: 300000)

Summary

Functions

Check if request is within rate limits.

Returns a specification to start this module under a supervisor.

Get statistics about rate limiting.

Get top N blocked identifiers for an action.

Reset bucket for specific identifier and action.

Starts the rate limiter GenServer.

Functions

check_limit(identifier, action, config)

Check if request is within rate limits.

Returns :ok if allowed, or {:error, :rate_limit_exceeded, retry_after_ms} if blocked.

Parameters

  • identifier - IP address (string) for auth, username (atom/string) for publish/subscribe
  • action - Action atom (:auth, :publish, :subscribe)
  • config - Map with :limit (max requests) and :window_ms (time window)

Examples

check_limit("192.168.1.1", :auth, %{limit: 10, window_ms: 60_000})
#=> :ok

check_limit("user1", :publish, %{limit: 1000, window_ms: 1000})
#=> {:error, :rate_limit_exceeded, 850}

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

get_stats()

Get statistics about rate limiting.

Returns map with total buckets and blocked request counts.

get_top_blocked(action, limit \\ 20)

Get top N blocked identifiers for an action.

Returns list of {identifier, blocked_count} tuples sorted by count descending.

Examples

get_top_blocked(:auth, 10)
#=> [{"192.168.1.100", 523}, {"10.0.0.50", 312}, ...]

reset_bucket(identifier, action)

Reset bucket for specific identifier and action.

Used for testing or manual intervention.

start_link(opts)

Starts the rate limiter GenServer.