Sthora
Reference

Plans and limits

The plan catalogue, what a null limit means, why usage is metered even when nothing is enforced, and the state of billing.

The catalogue

Plans are seeded from a catalogue at boot, so a fresh install has something to run on before anyone has configured anything. An operator can then adjust a customer's ceiling without a redeploy.

PlanPriceServersApplicationsBuild minutesListed
self-hostedFreeUnlimitedUnlimitedUnlimitedNo
starter$9/mo15300Yes
team$29/mo5301,500Yes
scale$99/moUnlimitedUnlimited10,000Yes

self-hosted is not listed because it is what you get by installing, not something to choose in a hosted portal. The paid tiers' prices are this repository's opinion, not a commercial decision anyone has signed off.

Money is stored in integer minor units. Never floats.

A null limit is unlimited, never zero

Every one of self-hosted's limits is null. That is what makes the enforcement code inert on a self-hosted box rather than absent from it — one path through the product, exercised by everyone.

Enforcement

BILLING_ENFORCE_LIMITS=false   # the default
BILLING_DEFAULT_PLAN=self-hosted

Off is the self-hosted case: the machine belongs to the person running it, and a ceiling on their own hardware would be an insult rather than a product.

Usage is metered either way

The flag decides whether a limit refuses something, not whether it is measured. Turning it on does not begin from a blank meter.

An organization with no subscription is treated as being on BILLING_DEFAULT_PLAN, which must match a slug in the seeded catalogue.

Changing a plan

PUT /subscription is operator-gated by decorator. With the manual provider a plan change is a grant — and a member who could grant themselves the largest plan would make every limit decorative.

GET /plans lists the public catalogue. The marketing site's pricing page reads it live, so prices are never a second copy that drifts.

Billing

No payment processor is integrated

Deliberately. The choice between Stripe, Razorpay, and Paddle is a commercial one that is still open, and webhook handling plus a customer mapping written against a guess would be thrown away.

There is a BillingProvider seam with ManualBillingProvider bound to it. The manual provider is a real implementation, not a stub: it is the correct one for a self-hosted install, which has no processor and never will.

Subscription status

A subscription carries one of TRIALING, ACTIVE, PAST_DUE, or CANCELED, so a hosted deployment can express the states a processor would drive. With the manual provider, a subscription is whatever an operator granted.

On this page