Subscription revenue analytics
A revenue platform for SaaS companies that tracks revenue live from Stripe, says in plain words what's slipping, and wins lost customers back in one click.
Whose need
For a SaaS founder, monthly revenue is the number that matters most, yet most dashboards only display it. When revenue drops, finding out why means digging through tables and looking up customers one by one in Stripe. A large part of the drop isn't customers choosing to leave; it's expired cards, and it slips away unnoticed.
What I built
I designed Holdfast as a product that acts, not a dashboard that reports. It connects to Stripe in one click, imports subscription history and stays live through webhooks. When revenue dips unusually, a notification lands on the phone and the dashboard explains the cause in a single sentence. Failed payments are split by reason, and every customer's plan and payment history sits on one timeline. A win-back campaign of card-update emails, smart retries and reminders starts in one click; end customers update their card on a branded page in seconds, and recovered revenue climbs on the dashboard in real time.
The flow
- The team connects Stripe; Holdfast imports subscription history and computes revenue from events.
- When revenue dips unusually, a notification arrives and the dashboard explains the cause in plain words.
- Failed payments are split by reason; each customer's plan and payment history is on one screen.
- A win-back campaign starts in one click: card-update email, smart retries, reminders.
- End customers update their card on a branded page or pause instead of cancelling; recovered revenue shows up live.
Key decisions
Revenue as a record of events
Every subscription change is stored as an immutable event; monthly revenue, breakdowns and charts are all computed from that log. History can be replayed, and when a calculation rule changes every series can be rebuilt from scratch.
The dashboard names the cause
A baseline that accounts for weekly seasonality catches unusual drops. The alert doesn't say "churn is up"; it says "31 customers didn't renew because their cards expired" and puts the action right next to it. No jargon in the interface, and color only ever means growth or loss.
Every money figure matches Stripe
Webhooks are processed idempotently and can be replayed; revenue calculations are verified against Stripe data in comparison tests. In the multi-tenant setup, each company's data is isolated with Postgres row-level security.
Win-back as a durable workflow
Retries, emails and reminders run as Inngest workflows that span days and survive interruptions. Emails are built with React Email and go out under the company's own brand and domain; end customers see the product they subscribe to, not Holdfast.
Technology
- Next.js 16
- TypeScript
- Stripe API
- Postgres
- ClickHouse
- Inngest
- React Email
- OpenTelemetry
Screens
Related serviceFull-stack apps and automation
Need something similar?
Tell me in a few sentences what you want to build.
Start a project