Plan-Based Limiting

Define different rate limits for different user tiers (Free, Pro, Enterprise).

Halt makes it easy to implement multi-tenant rate limiting where each tenant has a specific plan.

Built-in plan presets

Halt ships ready-made tiers so you don't have to define them by hand available identically in Python and TypeScript: PLAN_FREE, PLAN_STARTER, PLAN_PRO, PLAN_BUSINESS, and PLAN_ENTERPRISE. Resolve one by name with get_plan_policy / getPlanPolicy.

Pythonpython
from halt import RateLimiter, presets

# A specific tier…
policy = presets.PLAN_PRO

# …or resolve dynamically by name
policy = presets.get_plan_policy("pro")

limiter = RateLimiter(store=store, policy=policy)
TypeScripttypescript
import { RateLimiter, presets, getPlanPolicy } from 'halt-rate';

// A specific tier…
const policy = presets.PLAN_PRO;

// …or resolve dynamically by name
const dynamic = getPlanPolicy('pro');

const limiter = new RateLimiter({ store, policy });

presets.PLAN_TIERS exposes the full set if you want to iterate or build a pricing-aware resolver. Each preset now sets Policy.plan to its tier slug (free / starter / pro / business / enterprise), so telemetry events and OTel metrics get tagged with the plan automatically see Observability.

Defining custom plans

Set plan on a custom policy and Halt propagates it through every telemetry event. When unset, the policy name is used as a fallback.

const PLANS = {
  FREE: {
    name: 'free',
    plan: 'free',          // tag for telemetry / OTel metrics
    limit: 100,
    window: 3600,
    burst: 120
  },
  PRO: {
    name: 'pro',
    plan: 'pro',
    limit: 10000,
    window: 3600,
    burst: 12000
  },
  ENTERPRISE: {
    name: 'enterprise',
    plan: 'enterprise',
    limit: 100000,
    window: 3600,
    burst: 120000
  }
};

Dynamic Policy Selection

You can select the policy dynamically based on the user's subscription.

app.use(async (req, res, next) => {
  const user = req.user;
  const policy = PLANS[user.plan] || PLANS.FREE;
  
  const limiter = new RateLimiter({
    store,
    policy,
    keyPrefix: `plan:${user.plan}`
  });
  
  await haltMiddleware(limiter)(req, res, next);
});