Hybrid Platform (PaaS)
The dominant pricing pattern for modern platform-as-a-service products: customers pay a flat monthly fee that includes generous allowances of every metered resource, and overage charges kick in only when consumption exceeds the included quantity. The flat fee anchors the relationship and forecastability; the overage protects margin on heavy users and creates a natural upgrade path to the next tier.
Real-world examples. Vercel ($20/mo Pro tier with included bandwidth, builds, and serverless invocations; overage above), Supabase (per-project monthly fee with included database storage, auth users, edge function invocations), Render, PlanetScale, Upstash, Railway, Cloudflare Workers Paid. Common shape: one or two flat tiers with multiple included allowances per tier, real-time visibility into "how much of my allowance have I used", overage billed at the end of the period.
The shape of the problem
Hybrid pricing is harder than either pure flat or pure usage:
- Allowance bookkeeping per metered dimension. A single subscription typically has 5-10 metered dimensions, each with its own included allowance and its own overage rate. Tracking remaining allowance accurately, in real time, across all of them is the core operational challenge.
- Rollover policies. Some platforms let unused allowance roll over to the next period (encourages experimentation); others reset every cycle (encourages predictable forecasting). Both are legitimate; the policy must be expressible per-product, not hard-coded.
- Tier upgrades mid-cycle. When a customer is about to blow past their allowance and upgrades to a higher tier, the upgrade should add the higher tier's allowance prorata, not double-bill the user for the period.
- Overage transparency. Customers expect to see "$X.XX of overage so far this period" updating in real time; finance expects the period's invoice to land predictably at month end.
- Free tier conversion. A free tier with capped allowance is the entry point - and the moment the customer crosses into paid usage is the conversion event finance wants tracked separately.
Kontorion blueprint
| Concern | Kontorion primitive |
|---|---|
| Flat monthly fee | recurring-typed product priced per period |
| Per-dimension included allowance | PlanVersionProduct.allowance on each metered product |
| Real-time allowance state | GET /customers/{id}/subscriptions/{sub_id}/allowance-state |
| Rollover behavior | Plan setting allowance_rollover_default + allowance.rolled_over webhook |
| Overage rates | Standard usage pricing on the same metered products, applies above allowance |
| Tier upgrades mid-cycle | POST /subscriptions/{id}/transition-plan (proration via org-level proration_strategy) |
| Free-to-paid conversion tracking | subscription.plan_changed webhook + analytics |
Build it
1. Define the products
The flat platform fee, plus one product per metered dimension:
Code
2. Build a plan that bundles them with allowances
Code
allowance is the included quantity per cycle. rollover_enabled: true rolls unused allowance into the next period and emits allowance.rolled_over.
3. Set the prices (flat + overage rates)
Code
The allowance on PlanVersionProduct consumes first; the overage price kicks in only above it.
4. Subscribe the customer
Code
The first invoice is $20 flat. Overage charges only appear on invoices for periods when the customer exceeded an allowance.
5. Real-time allowance dashboard
Code
Code
billable_usage is what would be invoiced if the period closed now (overage only). The customer-facing "78% of bandwidth used" widget reads directly from this endpoint.
Variations
- Multi-tier ladder (Hobby / Pro / Team). Create one plan per tier with progressively larger allowances; upgrades are
POST /subscriptions/{id}/transition-plan. Use scheduled changes for "downgrade at end of period." - Pooled allowance across team members. When the platform charges per-team rather than per-developer, the allowance lives at the subscription level (the team) - usage events from all team members aggregate against one bucket.
- Per-environment allowance (prod vs preview). Use keyed prices on the metered products with
price_key_label: "environment"- same product, different rates and allowances per environment. - Annual prepay with bonus allowance. Add a yearly price option with
allowance_multiplier: 1.2so the annual plan includes 20% more allowance per cycle as a perk.
What you don't have to build
- Per-dimension allowance accounting (
PlanVersionProduct.allowancedoes it) - Allowance-then-overage billing math (drawdown happens before tier evaluation)
- Rollover bookkeeping with audit trail (
allowance.rolled_overevent captures the rollover) - Real-time "X% of Y used" portal widget (
/allowance-stateendpoint serves it) - Mid-cycle plan upgrades with proration (handled by
POST /transition-plan) - Free-to-paid conversion analytics (
subscription.plan_changedevent + cohort retention metric)
Next steps
- Plans - allowance and rollover configuration per plan version
- Usage Metering - the event stream that consumes allowance
- Pricing Models - tiered overage pricing patterns
- Analytics - allowance utilization and overage revenue trends