19 guides · 331 minutes · free core, no account

Learn it by building something real.

Every guide here is a working product, built line by line, with the reasoning said out loud. Start with the long one and you will finish with a Phoenix app that counts what customers use, stops them at their plan's limit, shows them the numbers live and puts the overage on a Stripe invoice.

Guides
19
Needed to follow along
$0
Core licence
MIT
Your data stays in
Your DB
Uses Pro 45 min read

Build a metered SaaS, end to end

One long walkthrough: a brand new Phoenix app that counts what customers use, stops them at their plan's limit, shows them the numbers live, takes their money through Stripe and bills what they went over. Every step, nothing skipped.

What you have when you finish

  • A running Phoenix app with three paid plans
  • Usage counted on every request without touching the database
  • A hard limit that is exact on a node when two requests arrive at once, with a bounded cluster overshoot
  • A live usage page that updates itself
  • Stripe checkout, a customer portal, and overage on the invoice
Read it

The words, once

Five kinds of thing a plan can promise.

Picking the wrong one is the mistake that costs the most to undo, and it is always made on day one. This is the whole decision, on one screen.

You write It means check/2 answers Money
feature :pdf_export, true A switch On, or off. :ok, or {:error, :not_entitled} None
feature :seats, 5 A number A figure the plan carries, which you read yourself. :ok None
limit :runs, 50, :hard A wall They are stopped at the line. :ok until 50, then {:error, :limit_exceeded} None
metered :runs, included: 1_000, unit_price: 2 An allowance They may pass the line and are charged for it. Always :ok Billed after 1,000
counter :runs Just counting Measured, never blocked, never billed. Always :ok Never
# nothing declared Not on the plan The plan says nothing about it. From 1.0 that is a refusal by default. {:error, :not_entitled} None

The last row is a setting, undeclared_feature_policy, with four values: :allow answers as though the feature were declared, :warn does the same and logs once per feature per node, :deny refuses, and :raise raises. The default is :warn in the transition release and :deny from 1.0. Counting is outside the policy: an undeclared feature is still tracked, because losing the measurement is not a useful way to punish a typo.

The long version, with the reason each one exists, is in Every word, explained once .

Start from your pricing

How do you want to charge?

There are three shapes. Pick yours and the guide that builds it is one click away. Using two of them at once is fine; they do not interfere.

Tiers with caps

A flat monthly price per tier. Cheap tiers have features switched off and caps that stop. Nobody is ever surprised by an invoice.

A project tool: 2 projects on Free, 50 on Team, 1,000 on Business.

plans.ex
plan :team do
  price 4_900
  feature :seats, 20
  limit :projects, 50, :hard
end
Build this

Allowance and overage

A monthly price that includes a generous amount. Going over still works and lands on the next invoice, so nobody is stopped mid sentence.

An AI writer: $29 includes 1,000 generations, then 2 cents each.

plans.ex
plan :writer do
  price 2_900
  metered :generations, included: 1_000, unit_price: 2
end
Build this

Prepaid credit

No monthly fee. Customers buy credit up front and every request spends some. You are paid before you do the work, and nobody can run up a bill.

A parsing API: $25 of credit, a fraction of a cent per page.

plans.ex
Credits.with_credits(org, estimate, "doc:#{doc.id}", fn ->
  {:ok, text, pages} = Parser.run(doc)
  {:ok, text, pages * 1_500}
end)
Build this

Every guide

In the order they were written to be read.

Start here

One guide that builds the whole thing. If you only read one, read this one.

The main build · 45 min · Start here

Build a metered SaaS, end to end

One long walkthrough: a brand new Phoenix app that counts what customers use, stops them at their plan's limit, shows them the numbers live, takes their money through Stripe and bills what they went over. Every step, nothing skipped.

Uses Pro
The sample · 15 min · Start here

Run the whole thing on your own machine

A complete Phoenix application that meters a fake AI product, runs with no API key and no card, and breaks itself eight different ways on demand so you can read what each failure actually leaves behind.

Free core

The free core

Counting, plans, limits and screens. Everything here works with the MIT package and no card.

The words · 10 min · Beginner

Every word, explained once

Tenant, feature, period, plan, and the five kinds of thing you can put on a plan. Ten minutes here saves you from the one mistake everybody makes: picking the wrong kind.

Free core
Counting · 12 min · Beginner

Count what customers use

The one line you put on your hot path, where the number actually goes, what happens when a server dies mid count, and how to read the totals back for a dashboard or a chart.

Free core
Durable events · 18 min · Intermediate

Record the facts you invoice

The handful of things you bill one by one deserve a row, an identity and a way to change your mind. Recording an event, what a duplicate and a conflict each return, and why a correction is a second fact rather than a smaller number.

Free core
Plans and limits · 15 min · Beginner

Write your plans down, then enforce them

Three tiers in one small module, switches that turn features off, seat counts, and the one function that makes a hard limit exact on a node when two customers click at the same moment.

Free core
Plan versions · 16 min · Intermediate

Change a plan without repricing anybody

What happens to the customers already on a plan when you edit its definition, how a fingerprint catches you doing it by accident, and how to move one customer on purpose with a preview you can put in an email first.

Free core
Screens · 14 min · Beginner

Put the numbers on screen

One call fills a dashboard card. One subscribe makes it live. Plus the two rules that keep a usage page honest, and the charts that need no gap handling.

Free core
Phoenix · 14 min · Intermediate

The Phoenix seams: a plug, a hook and four components

A plug that refuses a request with the right status and your own body, a LiveView hook that keeps a page live and switches tenant without leaking a subscription, the four components and the one rule that decides whether a usage bar ever moves, and the installer flags.

Free core

Getting paid

The two pricing shapes, and the Stripe wiring that turns a number into an invoice.

Allowance and overage · 14 min · Intermediate

Give an allowance, charge for going over

The pricing shape where 1,000 are included and the 1,001st still works and costs two cents. How to count it, how to show it honestly, and how it becomes a line on a Stripe invoice.

Free core
Prepaid credit · 20 min · Intermediate

Sell credit up front, spend it per request

A real money ledger: grants, holds, settlements, refunds and free trial credit that expires. The pricing shape for anything priced per unit, like AI tokens or API calls.

Free core
Lots and allowances · 20 min · Intermediate

Lots, debt and credit that arrives every month

A balance made of lots answers the questions one number cannot: which money expires first, which money a refund takes back, and whether a customer who owes you can spend the credit you gave them. Plus allowances that arrive once per period and roll over by a capped amount.

Free core
Subscriptions · 16 min · Intermediate

Take the money: Stripe subscriptions

The round trip. A customer clicks Upgrade, pays at Stripe, and comes back with the plan already live. Later they cancel, and the plan goes away on its own.

Uses Pro
Usage reporting · 16 min · Advanced

Get overage onto the invoice

What to build in the Stripe dashboard, what to schedule in your app, and what the reporter does when a send times out and nobody knows whether Stripe got it.

Uses Pro
Outbox · 20 min · Advanced

The outbox, and the item nobody can explain

Every export is a row in your own database before it is a network call. The seven states, the lease that is two mechanisms and only one clock, the key that makes a retry safe, and what a person does with an outcome nobody knows.

Uses Pro
Top ups · 14 min · Advanced

Let customers top up, and top them up automatically

Selling prepaid credit through Stripe Checkout, charging a saved card when the balance runs low, and handling the two events everybody forgets: refunds and chargebacks.

Uses Pro

Running it

Clusters, durability, alarms and tests. The part you want done before the first real customer.

Operations · 18 min · Advanced

Running it: the scheduled work, and stopping it

Six optional workers, what each does, and how to pause one at three in the morning without a deploy. Why nothing here is promised a single run and why that is fine. Credit holds nobody closed, retention that refuses to delete your ledger, and rebuilding a projection from the event log.

Free core
Going live · 18 min · Advanced

Ship it: the production checklist

Running across more than one server, deciding what may never be lost, the metrics worth an alarm at 3am, the audit log, and tests that can actually fail.

Uses Pro
The upgrade · 16 min · Advanced

Upgrading to 1.0

Going from 0.4.0 straight to 1.0: what 1.0 starts refusing, the two settings that keep 0.4 answers while you read the logs, the schema steps that have an order, the wallet migration that has no rollback, and the four things that do not change at all.

Free core

While you read

Put the dependency in now.

The core is MIT, on Hex, and needs no account. Pro is a drop-in add-on for the Stripe half, and every plan starts with a free trial, so nothing in these guides is gated behind a card.

mix.exs
def deps do
  [
    {:aurora_meter, "~> 1.0"},
    # optional, for Stripe billing
    {:aurora_meter_pro, "~> 1.2", repo: "aurorameter"}
  ]
end

Before you start

Fair questions.

Something still unclear? Ask us and the answer usually becomes a guide.

Do I need to pay for anything to follow these guides?
No. The Aurora Meter core is a free MIT package on Hex with no account and no expiry, and it covers counting, plans, limits and screens. Only the Stripe guides need Aurora Meter Pro, which has a 14 day free trial.
Is Aurora Meter a hosted service?
No. It is a dependency in your application. Your usage data stays in your own Postgres database, there is no sidecar to run and no third party to call on the hot path.
Where should I start?
Build a metered SaaS, end to end. It goes from a new Phoenix app to a paid invoice in one sitting and touches every part of the library. The other guides then take one job each in more depth.
How fast is the counting?
An increment is an atomic operation on an in-memory table, measured at roughly 5.5 million increments a second on the bundled benchmark. Totals are written to Postgres every five seconds by a background worker, so nothing touches the database on the request path.
Can I use it with more than one server?
Yes. Every node counts into its own memory and writes deltas, so nodes add up rather than overwrite each other, and the row in Postgres is the cluster total. It needs the distributed PubSub you already run for LiveView.
What if I only need part of it?
Take the part you need. Counting, plan entitlements and billing are three separate jobs in the library and none of them requires the others. Plenty of products use the plan gate and never meter anything.