← All guides

Meter usage and cap it

Define a meter, record usage, and block once a user hits their cap.

A meter tracks a per-user counter (e.g. questions, exports) with a period of month, lifetime, or credit. Create one for your app, then reference its slug from a plan's limits to set a cap.

1. Record usage

import { useRecordUsage } from "@vibemonetize/react";

function AskQuestionButton() {
  const recordUsage = useRecordUsage("questions");
  return <button onClick={() => { askQuestion(); recordUsage(); }}>Ask</button>;
}

This fires a fire-and-forget POST /v1/usage-events and optimistically decrements the cached meter so any useMeter/<UsageBadge> updates immediately. The server reconciles on the next entitlement-token refresh — it's always the source of truth.

2. Show remaining usage

import { UsageBadge, useMeter } from "@vibemonetize/react";

<UsageBadge meter="questions" />

// or build custom UI:
const { cap, used, remaining, resetsAt } = useMeter("questions");

3. Block once the cap is hit

import { Paywall, CheckoutButton } from "@vibemonetize/react";

<Paywall meter="questions" fallback={<CheckoutButton planId="01H...">Upgrade for more questions</CheckoutButton>}>
  <AskQuestionButton />
</Paywall>

<Paywall meter="..."> is first-class "block at cap" — it's built on useMeterGate, which is blocked: true once remaining is a known number <= 0, and fails open (not blocked) while loading or whenever the remaining count isn't known yet.

Server-side enforcement

@vibemonetize/server's meterUsage is the server-side equivalent of useRecordUsage — fire-and-forget, retries with backoff, then swallows failures so a metering hiccup never breaks the request it's attached to.