A pricing page takes an afternoon to design and months to implement properly, because every line on it is a rule someone has to enforce. Per-seat pricing needs seat counting that handles mid-cycle changes. Usage pricing needs metering you can defend when a customer disputes a bill. Tiered features need a permission system that stays correct when someone downgrades.
01Metering is a correctness problem, not a counting problem
If you bill on usage, your meter is a financial record. It has to survive process crashes, avoid double-counting on retries, be reconstructable if a downstream system loses data, and be explicable to a customer who thinks the number is wrong.
That means events written durably at the point of use with an idempotency key, aggregated separately, and retained at raw granularity for long enough to answer disputes. Incrementing a counter in the application is not metering, because a retry double-counts and nothing can be reconstructed after the fact.
| Model | Engineering burden | Common failure |
|---|---|---|
| Flat per month | Lowest | Little to go wrong |
| Per seat | Moderate | Mid-cycle changes and proration |
| Usage-based | High | Meter accuracy, disputed invoices |
| Tiered features | Moderate | Downgrade leaves data inaccessible |
| Hybrid seat plus usage | Highest | All of the above at once |
02Enforce limits in one place
Plan limits scattered across the codebase as inline conditionals become inconsistent within a quarter. One place answers whether a tenant may do a thing, and every call site asks it. That also makes limits inspectable, which support will need constantly.
Decide the behaviour at the limit deliberately and per-limit. Hard blocking is right for creating new resources. Soft limits with a warning are better for usage that has already happened, because failing a request the customer has already been charged for is a poor experience on both sides.
03Downgrades are where the edge cases live
Upgrades are easy - more capability, immediate, prorated. Downgrades are the difficult direction. A customer on a plan allowing twenty users downgrades to a plan allowing five, and they currently have twelve. What happens?
Deleting users automatically is unacceptable. Blocking the downgrade is hostile. The usual answer is to allow it, keep the data, and restrict access until they are back under the limit - which means your permission logic must handle 'over limit' as a real state rather than an impossible one.
| Scenario | Bad answer | Better answer |
|---|---|---|
| Over the seat limit | Delete users | Read-only until under the limit |
| Over the storage limit | Delete data | Block new uploads, keep existing |
| Used a premium feature | Delete what they built | Preserve, restrict access to it |
| Mid-cycle downgrade | Immediate loss | Effective at period end, credit if prepaid |
04Grandfathering is a permanent commitment
Changing prices means existing customers on old plans, and those plans must keep working. Every one you preserve is a configuration your code must support indefinitely, and after three price changes you are maintaining plan combinations nobody remembers agreeing to.
Model plans as data with explicit entitlements rather than as an enum with logic attached. That way an old plan is a row with a set of limits, not a branch in the code, and supporting it costs nothing beyond the row.
05Build the internal tooling early
Sales will need to apply a custom discount, extend a trial, grant an exception to a limit, or issue a credit. If those require an engineer and a database query, engineering becomes a permanent part of the sales process and everyone resents it.
An admin interface for plan overrides, with an audit trail of who changed what, pays for itself quickly. It is also the tooling that lets you say yes to a non-standard enterprise deal without a code change, which is frequently the difference between closing it and not.
Topics
Lena Voss
Lead Architect · SyncTrix
Writes about the engineering decisions behind production systems - architecture, delivery and the trade-offs that only show up at scale.
Building something like this?
SyncTrix engineers AI, SaaS, platform and cloud systems for enterprises and high-growth teams. Tell us what you're shipping and we'll scope it with you.
Talk to an engineer