my stripe meter reports 6% fewer events than my own counter, which number do i trust Usage-Based
I bill $0.02 per completed task. My app writes a row to tasks for each one and also posts a meter event to Stripe.
For last month my table says 1,204,880 tasks. The meter summary says 1,133,090. That is 71,790 tasks, roughly $1,436 I did not invoice.
I have been through it twice and I cannot make the two agree. Chart of where it goes is attached. I do not know whether the correct move is to fix the pipeline or fix my expectations about how close these should be.
@p99_hana · 4d ago · 3 replies
Two causes, both boring, both in your chart.
The rejections are almost certainly fire-and-forget posts whose response nobody reads. Meter events have an accepted timestamp window; anything you replay from a backlog, a dead-letter drain or a late worker lands outside it and comes back a 400 that goes straight into the void. Log the status code and you will find them in an afternoon.
The dedupe is your retry wrapper. Stripe keeps one event per
identifierand it is right to. Your table kept two because you inserted before you sent. Make the identifier deterministic - a hash of the task id, not a uuid generated at send time - and retries become free instead of lossy.The structural fix is an outbox. Add
metered_atandmeter_event_idcolumns to the task row, a worker that fills them, and a query that finds rows older than an hour withmetered_at is null. Then the gap is an alert on a Tuesday instead of a discovery at month end.Reply
Report
@token_rot_priya · 6d ago
The outbox is the whole answer. Once every billable row has a nullable
metered_at, reconciliation is one query you can put on a dashboard, and "are we billing correctly" stops being a feeling.Reply
Report
@rueben_alsop · 6d ago
Deterministic identifier is the bit I would do first because it is ten minutes and it makes the rest of the debugging honest. As long as the id changes per attempt you cannot tell a duplicate from a genuine second task.
Reply
Report