# Show HN: Hardcount – Self-hosted usage billing for AI products

> Source: <https://github.com/gethardcount/hardcount>
> Published: 2026-11-04 11:19:55+00:00

**Usage billing for AI products, on your own servers.**

Price tokens per model, sell prepaid credit, and see what each customer costs you. Hardcount makes the invoices, and Stripe charges the card. Your billing data stays in your own Postgres.

An open-source alternative to Stripe Billing and Lago: no Stripe Billing fee, no paid edition, and light enough to run yourself. [Why Hardcount →](#why-hardcount)

One month of AI usage for one customer, from the [demo](#quick-start) in test mode: one invoice line per model and token type, $5.73 due. Your margin on it is 51.9% (Sonnet 67.1%, Haiku 20.0%), shown only to you. **▶ [Watch the 65-second walkthrough](https://gethardcount.com/#looks)**, narrated, with captions.

Try Hardcount on your own computer. It runs in test mode, where no real money moves.

You need git and Docker 24 or newer with the Compose plugin. On Windows, run it inside WSL.

**1. Start Hardcount**

```
git clone --branch v0.9.2 https://github.com/gethardcount/hardcount.git
cd hardcount/deploy/compose
./quickstart.sh
```

**You see:** "Hardcount is running.", then your dashboard address, email, password and a test API key. The password is shown only once; the script also saves all four in `deploy/compose/quickstart-credentials.json`.

Open `http://localhost:8080` and sign in. Hardcount opens in test mode, and it is empty.

**2. Run the demo**

```
./quickstart.sh demo
```

The demo sets up AI token prices, creates a customer and sends token usage the way a LiteLLM proxy would. Then it moves the customer's test clock (a pretend clock for test customers) to the end of the month, and Hardcount makes the invoice, its PDF and the margin report shown above.

**You see:** nine steps, each ending in a green ✓, then links to the invoice and the customer. Home still reads $0, because its totals leave out test-clock customers; use the links instead. [Each demo step, and where to click](https://github.com/gethardcount/hardcount/blob/main/docs/quick-start.md)

**3. Stop or remove it**

`./quickstart.sh stop` keeps your data. `./quickstart.sh destroy` deletes it, and cannot be undone. If port 8080 is taken, start with `HARDCOUNT_PORT=9000 ./quickstart.sh`.

**Next:** [send your own usage and get a first invoice](https://github.com/gethardcount/hardcount/blob/main/docs/first-invoice.md) · [run it for real on one VM](https://github.com/gethardcount/hardcount/blob/main/docs/production-one-vm.md) · [change Hardcount itself](https://github.com/gethardcount/hardcount/blob/main/CONTRIBUTING.md#development-setup)

``` php
flowchart LR
    A["Your app or LiteLLM"] -->|"usage events"| B["Hardcount<br/>counts and prices"]
    B -->|"month ends"| C["Invoice + PDF"]
    C -->|"saved card"| D["Stripe charge"]
    D -.->|"card declined"| E["Retries and emails"]
```

Your app tells Hardcount what each customer used. Once the customer and its prices exist, one usage event looks like this:

```
curl -X POST http://localhost:8080/v1/usage-events \
  -H "Authorization: Bearer $HARDCOUNT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"event_name": "tokens",
       "external_customer_id": "acme",
       "quantity": 1200,
       "dimensions": {"model": "claude-sonnet-4.5", "token_type": "input"},
       "idempotency_key": "req-42:input"}'
```

`external_customer_id` is your own ID for the customer. The `dimensions` pick the price: here, Sonnet 4.5 input tokens. If you send the same `idempotency_key` again, Hardcount counts the event once. Already run a [LiteLLM](https://github.com/gethardcount/hardcount/blob/main/docs/integrations/litellm.md) proxy? It sends these events for you. [Your first invoice, step by step](https://github.com/gethardcount/hardcount/blob/main/docs/first-invoice.md)

The gaps Hardcount is built for:

| The gap | What Hardcount does | 
|---|---|
| **Stripe Billing takes a cut:** 0.7% of billing volume on its pay-as-you-go plan, and its basic usage billing can't price each model and token type on one meter. | **No Stripe Billing fee.** Stripe still charges the card. One meter prices every model and token type. | 
| **Key parts sit behind a paid licence,** such as automatic failed-payment retries and invoice previews in Lago. | **One free edition.** MIT, with no paid edition. | 
| **Some are heavy to run:** Flexprice's default setup runs nine services, including Kafka and ClickHouse. | **One Go program, Postgres and Redis.** The ready-made Compose setup runs five small containers. | 
| **No way to fast-forward time** to test a billing change. | **Test clocks:** move a test customer forward a month and see the invoice before any real customer gets it. | 
| **A customer can cost you more than they pay,** because AI costs move with usage. | **Margin per customer and per model,** from the provider cost Hardcount records on each usage event as it arrives. OpenMeter and Flexprice report cost too. | 

Stripe still charges its normal card fee, and Stripe Tax's fee if you use it. Every claim above has a source in [Why Hardcount exists](https://github.com/gethardcount/hardcount/blob/main/docs/why-hardcount.md), and [How it compares](https://github.com/gethardcount/hardcount/blob/main/docs/comparison.md) lists where the other projects are ahead.

**Pre-1.0.** Hardcount is young: one maintainer, Stripe and cards only, no SDKs yet, no production users yet. Until 1.0.0, a minor release can break the API, and a patch release can change something you rely on ([versioning before 1.0](https://github.com/gethardcount/hardcount/blob/main/docs/versioning.md)).

**A good fit if:**

- **You charge by usage,** most of all an AI product that prices per token, by model and token type.
- **You want billing on your own servers.** Usage and invoice records stay in your own Postgres. Stripe sees each charge, and the invoice lines too if you use Stripe Tax.
- **You are a small or mid-size team.** One engineer can run it, on one server or several.
- **Your volume is up to about a million usage events a day.** A €6.49-a-month server took that rate for 20 minutes with no errors (measured on v0.8.0). Plan 15 to 18 GB of database disk a month at that volume.[How we measured](https://github.com/gethardcount/hardcount/blob/main/docs/scale.md)

**Not a fit if you need:**

- **Simple per-seat pricing paid by card.** Stripe Billing already does that well.
- **Automatic charging through a processor other than Stripe.** Stripe is the only one built in today.[Tell us which one you need](https://github.com/gethardcount/hardcount/issues) .
- **A marketplace that splits payouts** between sellers (Stripe Connect). Hardcount bills your own customers.
- **Revenue recognition or accounting reports.** Export the data to your own warehouse.
- **Quotes or multi-phase contracts** for sales-led deals.

- **Pricing:** per-unit, graduated and package prices; rates per model and token type on one meter; a base fee plus usage on one invoice; prepaid credit that later usage draws down.[AI pricing](https://github.com/gethardcount/hardcount/blob/main/docs/ai-pricing.md)
- **Billing you can trust:** Hardcount never bills the same period twice, because the database refuses a second invoice for it. Every usage line on an invoice links to the events behind it.[How Hardcount keeps a bill right](https://github.com/gethardcount/hardcount/blob/main/docs/ENGINEERING.md)
- **Getting paid:** cards through Stripe, with automatic retries and emails when a payment fails. Customers can also pay another way, such as a bank transfer, and you mark the invoice paid.[Payment failure handling](https://github.com/gethardcount/hardcount/blob/main/docs/payments.md)
- **Running it:** one Go program with its background jobs inside, Postgres and Redis. No telemetry and no licence check.[Self-host](https://github.com/gethardcount/hardcount/blob/main/docs/self-host.md)

Every feature: [What Hardcount does](https://github.com/gethardcount/hardcount/blob/main/docs/features.md).

[`docs/README.md`](https://github.com/gethardcount/hardcount/blob/main/docs/README.md) lists every doc by what you want to do: decide if Hardcount fits, try it, connect your product, run it in production, or contribute. Good places to start:

- [How Hardcount works](https://github.com/gethardcount/hardcount/blob/main/docs/how-hardcount-works.md) : from a usage event to a paid invoice, step by step
- [How it compares](https://github.com/gethardcount/hardcount/blob/main/docs/comparison.md) with Lago, OpenMeter, Flexprice and Kill Bill
- [Roadmap](https://github.com/gethardcount/hardcount/blob/main/docs/roadmap.md) ·[Changelog](https://github.com/gethardcount/hardcount/blob/main/CHANGELOG.md)

- **Questions, or evaluating a deployment:**[GitHub Discussions](https://github.com/gethardcount/hardcount/discussions)
- **Bugs:**[Issues](https://github.com/gethardcount/hardcount/issues) . Money-path bugs are triaged first.
- **Security:**[`SECURITY.md`](https://github.com/gethardcount/hardcount/blob/main/SECURITY.md) . Report privately, not in a public issue.
- **Contributing:**[`CONTRIBUTING.md`](https://github.com/gethardcount/hardcount/blob/main/CONTRIBUTING.md) .
