5. Hard, soft, and observe
What should happen when a customer reaches their limit? It depends on the feature, so each limit has a mode:
hard(the default) denies the call.softallows it and reports the part past the limit as overage, which you bill.observenever denies. It only records the usage, which is useful for tracking a feature before you price it, or for trying a new limit without blocking anyone.
The engine tells you what happened through events. Here's the same plan with all three modes, and a handler that prints the interesting events:
import { Limitr } from '@formata/limitr';
const limitr = await Limitr.new(`
policy: {
credits: {
// $0.50 per export past the limit
export: { label: 'Export', price: { amount: 0.50 } }
}
plans: {
pro: {
default: true
entitlements: {
exports_hard: { limit: { credit: 'export', mode: 'hard', value: 2 } }
exports_soft: { limit: { credit: 'export', mode: 'soft', value: 2 } }
exports_observe: { limit: { credit: 'export', mode: 'observe', value: 2 } }
}
}
}
}`);
await limitr.ensureCustomer('ada');
limitr.addHandler('log', (name, value) => {
const { overage, overage_price, meter } = JSON.parse(value as string);
if (name === 'meter-overage') {
console.log(` ${name}: ${overage} over, bill $${overage_price}`);
}
if (name === 'meter-limit') {
console.log(` ${name}: denied at ${meter.value} of ${meter.limit}`);
}
});
for (const entitlement of ['exports_hard', 'exports_soft', 'exports_observe']) {
console.log(entitlement);
for (let i = 1; i <= 3; i++) {
console.log(` export ${i}:`, await limitr.allow('ada', entitlement, 1));
}
}
It prints:
exports_hard
export 1: true
export 2: true
meter-limit: denied at 2 of 2
export 3: false
exports_soft
export 1: true
export 2: true
meter-overage: 1 over, bill $0.5
export 3: true
exports_observe
export 1: true
export 2: true
export 3: true
- The hard limit denies the third export and sends
meter-limit. - The soft limit allows it and sends
meter-overagewith how much was over and what to bill (overage_price, from the credit's price). That's the event to bill from. - The observe limit allows everything and sends
meter-changed, like any other recorded usage.
Handlers get every event as a name and a JSON string. They run during the call that sent them, and the call doesn't wait for async handlers, so keep handlers quick and catch their errors. The full list of events and their payloads is in the events reference.
Next: Pricing and margins