patterntypescriptMajor
Usage Metering: Event-driven metering pipeline for accurate billing
Viewed 0 times
meteringusagebillingqueueasynceventsrevenue
Problem
Counting API calls for billing inside the request handler adds latency and creates a tight coupling between billing logic and request processing. Billing system outages can impact API availability.
Solution
Emit usage events asynchronously to a queue (Kafka, SQS, or even a Redis stream) at the end of each request. A separate metering service consumes events, aggregates them, and writes to the billing system. This decouples billing from the hot path.
Why
Async metering keeps the API request path fast and resilient. If the billing system is down, usage events queue up and are processed when it recovers. The separation also allows replaying events if billing logic changes.
Gotchas
- Ensure at-least-once delivery semantics for usage events — dropped events mean under-billing, which is a revenue loss.
- Include the API key, endpoint, method, response status, and latency in each usage event for granular analysis.
- Metering events should be idempotent — use a requestId as deduplication key.
Code Snippets
Usage event emission after request completion
app.use(async (req, res, next) => {
const start = Date.now()
res.on('finish', () => {
const event = {
requestId: req.requestId,
apiKeyId: req.apiKey?.id,
endpoint: `${req.method} ${req.route?.path}`,
statusCode: res.statusCode,
latencyMs: Date.now() - start,
timestamp: new Date().toISOString()
}
usageQueue.push(event).catch(err => logger.error('Metering event failed', err))
})
next()
})Revisions (0)
No revisions yet.