DEV Community

DCT Technology Pvt. Ltd.
DCT Technology Pvt. Ltd.

Posted on

Designing a Usage-Based Billing System (Stripe-Style)

Most SaaS apps price their features with flat-rate plans.
But what if you could scale your revenue with how your customers actually use your product?

That’s the magic of usage-based billing — and why Stripe, AWS, and Twilio are thriving.

But designing this type of system?
Not so magical.

Let’s dive into how to design a Stripe-style usage-based billing system that’s flexible, scalable, and revenue-smart — without getting overwhelmed by edge cases.

Why Usage-Based Billing Is the Future of SaaS

✅ More revenue from power users
✅ Lower barrier for new users
✅ Aligns value with pricing
✅ Encourages fair use and adoption

Startups are moving to usage-based pricing models because it just makes sense — customers pay for what they use, not what they might use.

If you’re building a platform or API product, this is a must-have.


🧠 Core Concepts Before You Begin

To build this right, understand these key parts:

  • Metered usage tracking
  • Pricing rules per metric (e.g., \$0.01 per API call)
  • Customer-level aggregation
  • Invoicing cycle (monthly, real-time, etc.)
  • Integrations with payment processors (like Stripe Billing)

🛠️ System Design Overview

Your system needs to:

  1. Track usage events in near real-time
  2. Store them efficiently (with timestamp, user ID, resource type, units)
  3. Aggregate usage by billing period
  4. Calculate charges based on defined rates
  5. Generate invoices and send to Stripe

Here’s a simplified example of how your usage event schema might look:

{
  "user_id": "cus_123456",
  "event_type": "api_call",
  "units": 1,
  "timestamp": "2025-07-21T09:34:21Z"
}
Enter fullscreen mode Exit fullscreen mode

⏱️ Tracking Usage in Real-Time

You can use a queue like Kafka or RabbitMQ to push usage events.

Or go lean with event tracking via a REST API.

Here’s a minimal example in Node.js:

app.post('/track', async (req, res) => {
  const { user_id, event_type, units } = req.body;
  await db.collection('usage_events').insertOne({
    user_id,
    event_type,
    units,
    timestamp: new Date()
  });
  res.status(200).send({ success: true });
});
Enter fullscreen mode Exit fullscreen mode

📊 Pricing Models: Flat, Tiered, Volume

Choose the pricing style that fits:

  • Flat-rate: \$0.01 per call
  • Tiered: First 1,000 free → next 9,000 at \$0.01 → above that \$0.005
  • Volume-based: Entire usage priced based on total volume (like AWS)

Here’s a Tiered Billing logic sample in JavaScript:

function calculateCharge(units) {
  if (units <= 1000) return 0;
  else if (units <= 10000) return (units - 1000) * 0.01;
  else return (9000 * 0.01) + ((units - 10000) * 0.005);
}
Enter fullscreen mode Exit fullscreen mode

🔗 For deep dive: Stripe Tiered Pricing Docs


🧾 Aggregating Usage and Generating Invoices

Schedule a daily or hourly aggregation job:

cron: 0 0 * * * /aggregate-usage.sh
Enter fullscreen mode Exit fullscreen mode

Use something like:

const usage = await db.collection('usage_events').aggregate([
  { $match: { user_id: 'cus_123456', event_type: 'api_call' } },
  { $group: { _id: null, total_units: { $sum: "$units" } } }
]);
Enter fullscreen mode Exit fullscreen mode

🔐 Common Pitfalls (and How to Avoid Them)

  • Double-charging users → Deduplicate events
  • Clock drift between services → Always use UTC
  • Overload on database → Batch inserts & async queues
  • Delayed usage data → Consider usage finalization windows

⚙️ Technologies You Might Use

  • Backend: Node.js / Python
  • Queue: Kafka / RabbitMQ / Redis Streams
  • DB: MongoDB / PostgreSQL
  • Billing: Stripe
  • Scheduler: Cron, Airflow, Temporal.io

🔗 Temporal is great for complex workflows: Temporal Billing Workflows


🧩 Bonus: What If I Don’t Want to Build This From Scratch?

There are SaaS tools that do this out-of-the-box:

Great if you're scaling and don’t want to maintain your own infra.


💬 Your Turn

Have you built a metered billing system before?
What tech stack did you use? What mistakes did you make?

👇 Let’s discuss in the comments.

And if you found this helpful…

🔔 Follow [DCT Technology] for more deep-dives on web dev, system design, and SaaS infrastructure.


#webdev #systemdesign #stripe #billing #saas #api #node #javascript #startups #programming #backend #infrastructure #payments #developer #dcttechnology

Top comments (0)