Billing is the most underestimated feature in SaaS development. On the surface, it seems straightforward: charge customers money on a recurring basis. In practice, it is a web of edge cases, proration calculations, failed payments, plan changes, tax obligations, and audit requirements that can consume months of engineering time if you do not approach it systematically.
We have implemented billing systems across a dozen SaaS products. Each one taught us something new about how pricing models translate into code. Here are the five patterns we see most often, along with the engineering considerations your pricing page does not mention.
Seat-based billing charges per user per month. It is the most common B2B SaaS model because it is easy for customers to understand and predictable for revenue forecasting. Slack, Figma, and most collaboration tools use some variation of this pattern.
The engineering complexity hides in the transitions. What happens when a customer adds a seat mid-cycle? You need proration logic — charging only for the remaining days in the billing period. What about removing a seat? Most implementations credit the unused portion toward the next invoice. What if an admin adds and removes the same seat three times in one billing period? Your billing system needs to handle all of these cases correctly.
// Seat proration calculation
function calculateSeatProration(
pricePerSeat: number,
daysRemaining: number,
totalDaysInPeriod: number
): number {
// Daily rate for one seat
const dailyRate = pricePerSeat / totalDaysInPeriod;
// Charge only for remaining days
return Math.round(dailyRate * daysRemaining * 100) / 100;
}Our recommendation: use Stripe Subscriptions with quantity-based line items. Stripe handles proration automatically, but you still need to sync seat counts between your application and Stripe whenever users are added or removed. Build a reconciliation job that runs daily to catch any drift.
Usage-based billing charges customers for what they consume — API calls, storage, compute minutes, messages sent. AWS, Twilio, and Vercel use this model. It aligns cost with value, which customers appreciate, but it makes revenue less predictable and engineering significantly more complex.
The core challenge is metering. You need to accurately track every billable event in real-time, aggregate it by customer and billing period, and make that data available for invoice generation. This requires a dedicated metering pipeline — typically an event stream (Kafka or Redis Streams) feeding into a time-series or aggregation store.
For most SaaS products, pure usage-based billing is overkill. Consider combining it with a base subscription (see hybrid model below) to maintain revenue predictability while still aligning price with value.
Tiered pricing offers three to four predefined plans (typically Free, Starter, Pro, Enterprise) with increasing feature sets and limits. It is the most common model because it balances simplicity for customers with predictability for the business. Notion, Linear, and most B2B tools use this approach.
The engineering work centers on feature gating — controlling which features and limits apply to each tier. This sounds simple, but it touches every part of the application. API rate limits, storage quotas, number of projects, access to specific modules, support response times — all need to be configurable per plan.
// Feature gating with plan-based limits
interface PlanLimits {
maxProjects: number;
maxStorageMB: number;
maxTeamMembers: number;
features: Set<string>;
}
const PLAN_LIMITS: Record<string, PlanLimits> = {
free: { maxProjects: 3, maxStorageMB: 100, maxTeamMembers: 1, features: new Set(['basic']) },
starter: { maxProjects: 10, maxStorageMB: 1000, maxTeamMembers: 5, features: new Set(['basic', 'api', 'export']) },
pro: { maxProjects: -1, maxStorageMB: 10000, maxTeamMembers: 25, features: new Set(['basic', 'api', 'export', 'sso', 'audit']) },
};
function canAccessFeature(plan: string, feature: string): boolean {
return PLAN_LIMITS[plan]?.features.has(feature) ?? false;
}Design your feature gating system to be data-driven, not hard-coded. Store plan definitions and limits in a configuration that can be updated without deploying code. When you launch a new pricing tier or adjust limits — and you will — it should be a config change, not a code change.
Hybrid billing combines a base subscription with usage-based charges on top. Customers pay a fixed monthly fee that includes a certain amount of usage, then pay overage rates beyond that. This is increasingly popular because it gives customers cost predictability while still capturing value from heavy users.
Implementing hybrid billing means combining the complexity of both seat-based and usage-based models. You need subscription management for the base plan plus a metering pipeline for usage tracking. The invoice needs to clearly show the base charge and any overages.
The trickiest part is the threshold calculation. When a customer is approaching their included usage limit, you need to alert them — both for good UX and to avoid surprise charges. This requires near-real-time usage aggregation and a notification system that fires at configurable thresholds (80%, 90%, 100% of included usage).
The best billing systems are invisible to customers who stay within their plan and transparent to those who exceed it. Surprise charges destroy trust faster than any product bug.
Freemium gives users a permanently free tier with limited functionality, hoping to convert a percentage to paid plans. Dropbox, Spotify, and Slack popularized this model. The engineering challenge is not billing (free is easy) — it is the conversion funnel and the cost of serving free users.
You need to instrument every interaction point where free users hit limits. When a user tries to create their fourth project on a three-project free plan, the experience should be smooth — a clear upgrade prompt that explains what they get, not an error message. These "upgrade moments" are your primary conversion mechanism, so they need to be well-designed and tracked.
On the infrastructure side, free users can represent 90% or more of your user base while contributing zero revenue. Design your infrastructure so free tier usage is as cheap as possible. Use aggressive caching, lower storage limits, and consider serving free users from a separate, cost-optimized infrastructure pool.
Regardless of which billing model you choose, a few engineering principles apply universally.
Billing is a core system that affects revenue, customer experience, and regulatory compliance. Invest in getting it right early. The cost of fixing billing bugs — incorrect charges, missing invoices, failed subscription renewals — goes beyond engineering time. It costs customer trust.
Tagged:

The definitive guide to web development in Karlsruhe. Learn what to look for in a development partner, which technologies matter, and how to maximise your digital investment in South.

Businesses in Magdeburg face unique e-commerce challenges — from local payment preferences to Saxony-Anhalt logistics. Learn how BizBrew builds high-converting online shops tailored to the East market.
Want to discuss these ideas for your project?
Get in touch