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.
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)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);
});