---
title: "Ledger"
tagline: "Billing"
language: "Go"
license: "Apache-2.0"
since: "2026"
canonical: "https://xraph.com/work/ledger"
---

# Ledger

Usage-based billing for SaaS: meter events in batches, check entitlements, price them with graduated, volume, flat or hybrid tiers, and generate invoices with taxes and discounts. Money is integer-only throughout. Entitlement checks are cached and sub-millisecond because they end up on the hot path of every request.

## Install

```bash
go get github.com/xraph/ledger
```

## What it is

Ledger is a usage-based billing engine for Go: meter events, check entitlements, compute invoices, manage plans and subscriptions, and integrate a payment provider.

## What it does

- **Subscriptions**: trials, upgrades, downgrades, cancellations, with proration.
- **Metering**: batched high-throughput ingestion, tested above 100k events per second.
- **Entitlements**: cached authorization checks in under a millisecond, because they end up on the hot path of every request rather than only at checkout.
- **Pricing**: graduated, volume, flat-rate and hybrid models.
- **Invoices**: line items, taxes, discounts, and a coupon system with percentage and fixed-amount validation.

## Two decisions worth calling out

**Money is integer-only.** There is no float anywhere in the codebase. Every rounding decision is explicit and happens at a named place, because the alternative is a reconciliation conversation with a finance team about half a cent.

**Identifiers are TypeIDs**: globally unique, K-sortable, and prefixed, so an id in a support ticket tells you what kind of thing it refers to without a lookup.

Storage is pluggable across PostgreSQL, SQLite, Redis and memory, and Chronicle integration gives the audit trail that billing disputes eventually require.

---

*Unpublished draft. Not peer reviewed and not submitted to a venue.*


## Anatomy

- **Subscriptions**: Plans, terms and changes over time.
- **Metering**: Usage recorded as events, aggregated on read.
- **Entitlements**: What a customer may do, derived from their plan.
- **Invoices**: Generated from the record, not from a running total.

## Constraints and trade-offs

- (decision) Entitlements are derived, never stored. A stored entitlement is a cache that will disagree with billing.
- (constraint) Metering is append-only. Correcting usage is another event, not an edit.
