Charge for usage without building a billing system.

Meter Keeper is an open-source usage meter for small SaaS teams that bill through Stripe. Your app sends events; it counts each one exactly once, prices the month, tells your app when a customer is over a limit, and feeds Stripe Billing Meters with retries. You run it in your own account. First, try your pricing against real usage numbers. Everything runs in your browser, so nothing you paste is uploaded.

1. Price a month of usage

CustomerUnitsBillPer 1,000 units

Models: flat (unit), graduated (each tier priced at its own rate), volume (the whole quantity at the rate of the tier it lands in; tiers may carry a flat fee) and package (unit per block of size). Tier limits count units after the included ones. Look at the right-hand column: if your biggest customers pay far less per unit than your smallest, that is the discount you chose.

2. Run the meter yourself

git clone https://github.com/Duncan-Haywood/oss-monorepo && cd oss-monorepo/ventures/meter-keeper
cp meter-config.example.json meter-config.json      # your meters and plans
API_KEY=$(openssl rand -hex 16) ADMIN_KEY=$(openssl rand -hex 16) node server.mjs   # DRY_RUN=true until you change it

curl -X POST localhost:8080/v1/events -H "authorization: Bearer $API_KEY" \
  -d '{"id":"req_8f3a","customer":"acme","meter":"api_calls","value":1}'

Send the same id twice and the second is a harmless duplicate. Read back with GET /v1/usage, /v1/invoice-preview, /v1/projection and /v1/check?customer=acme&meter=api_calls&quantity=1 (does this call fit the plan's limit?). To feed Stripe, create a Billing Meter with the same event name, give the server a restricted key that can write meter events, and set DRY_RUN=false. One-click Render deploy and Docker are in the README.

Questions

Why not use Lago, OpenMeter, Orb or Metronome?

Those are good products and the right choice if you need invoicing, tax and a full billing platform. Meter Keeper does one narrow job for a small team that already bills through Stripe: count usage exactly once, price it, enforce limits, and feed Stripe Billing Meters. It is one dependency-free Node process with a JSON file for state, so there is nothing to operate. If you outgrow it, your events are plain JSON you can replay elsewhere.

What stops an event being counted twice?

Every event carries an id you choose. Sending the same id again is reported as a duplicate and changes nothing, so your client can retry freely after a timeout. The same id is passed to Stripe as the meter event identifier, so a retry from this server cannot double-bill either.

What happens when Stripe is down?

Events are stored first and forwarded after, from a queue. A 5xx or rate-limit answer is retried with a growing delay for up to eight tries. A permanent error, such as a customer with no Stripe id, goes to a visible dead-letter list instead of vanishing. Stripe only accepts events up to 35 days old, so look at the queue at least weekly.

Which pricing models are supported?

Flat per unit, graduated tiers, volume tiers, and package pricing (a price per block of N units), each with free included units, an optional base fee, a monthly minimum and a hard usage limit. The invoice preview is a calculation from the usage this server has seen, not the invoice: your Stripe prices stay the source of truth for what a customer is charged.

Is it safe to put real customer data in?

Store only ids you choose, never names or emails. You run the server, so you are responsible for securing the API key, backing up the state file and following the privacy and tax rules where you and your customers live.