B2B SaaS 2022 Live

Multi-Tenant SaaS Billing Rebuild

Migrated a B2B SaaS platform from flat-rate Stripe billing to usage-based pricing — zero downtime, zero revenue loss during migration.

0
Downtime during migration
340
Active subscriptions migrated
23%
Revenue uplift post-migration
Stack DjangoStripePostgresCeleryRedisAWS

The Problem

A B2B SaaS company had outgrown their flat-rate pricing model. Customers using 10× the average were paying the same as light users — and churning high-value customers who felt underserved. They needed usage-based billing, but had 340 active subscriptions, a complex multi-tenant Django app, and a non-negotiable requirement: no downtime, no billing disruptions.

What I Built

A complete Stripe billing layer rebuild, migrating from stripe.Subscription with flat prices to stripe.Subscription with metered usage items.

The Migration Strategy

The key insight: Stripe supports multiple price items on a single subscription. I used this to run a parallel billing period:

  1. Created new metered price objects for each existing plan
  2. Added the metered price to each existing subscription as an additional item (with quantity 0)
  3. Started capturing usage events to the new metered item in the background
  4. On the customer’s next billing cycle, removed the old flat price and promoted the metered item
  5. Customers never saw a billing interruption

This gave a 30-day migration window where both systems were running. If anything broke, we could revert by removing the metered item.

Usage Tracking

Celery workers capture usage events from the application (API calls, data processed, active seats) and batch-write to Stripe’s Usage Records API every hour. Redis buffers in-progress events to handle API rate limits.

Customer Portal

New billing dashboard built on Stripe’s embedded components + custom React UI showing current usage, projected invoice, and plan limit warnings.

The Hard Part: Idempotency

Usage events must be idempotent. If a Celery worker crashes mid-batch, you can’t double-count usage. I implemented a Postgres-backed idempotency key system: every event has a UUID, and the worker checks against a deduplication table before writing to Stripe.

Results

  • Zero downtime during the 30-day migration window
  • 340 subscriptions migrated without a single billing error
  • 23% revenue uplift in the first quarter (heavy users now paying proportionally)
  • Churn reduction among light users (they now see the value proposition more clearly at lower cost)
Next → Recommendation Engine v1

Want something
like this?

30 minutes, free, no deck. We'll figure out if I'm the right fit for your project.