The thing the other examples can't show: credits that survive a restart.
examples/express-api and examples/nextjs-ai-route both use InMemoryAdapter, so every
reload starts from a full balance. This one stores balances and usage events in ./usage.db
via @uselimit/storage-sqlite, so state carries across
processes.
Build both packages first, then install:
pnpm --filter "@uselimit/*" build
cd examples/sqlite-persistence
pnpm installThen run it more than once:
pnpm start # Starting balance: 100 -> 85
pnpm start # Starting balance: 85 -> 70
pnpm start # Starting balance: 70 -> 55Each run performs three metered operations at 5 credits each, following the
check → operate → consume flow. The recorded usage-event count grows across runs too, since
the events table is the same durable source of truth quotas are derived from.
pnpm reset # delete usage.db (and its -wal / -shm sidecars) to start over-
Seeding happens once. The tenant and its balance are created on the first run only; every later boot finds them already there. That's what your signup flow does in a real app.
-
usage.dbis a real file. Open it with any SQLite client and look atbalancesandusage_events. -
Consumption is atomic. Two processes running this at the same time can't double-spend the same credits — the deduction, the quota check, and the event insert share one transaction.
-
Nothing resets. By the fourth run the
summariesfeature quota (50 credits per month) is spent and requests start coming back refused:✗ second document: refused — Feature quota exceeded for 'summaries' (resets 2026-10-10T…)It stays that way even past that reset date. uselimit doesn't yet advance a tenant's
periodStartor refill balances atresetAt, so the quota window never rolls over —pnpm reset, or refill from your own scheduler. This is the sharpest edge in the library today and it's next on the roadmap.
Requires Node >= 22.13 for node:sqlite. Node 22.x prints an ExperimentalWarning on
first use; Node 24 doesn't.