Investigate customer usage discrepancies before renewal by confirming the counting unit, then delivery acceptance, meter timing, and the billed quantity.
Key takeaways
- Identify the reporting entity before comparing figures.
- Record the user identifier and activity definition. By default, Mixpanel counts unique users by distinct_id, according to Mixpanel. An “active user” is defined by both the activity and frequency of the activity, according to Mixpanel.
- Separate captured events from group properties. Usage is based on captured identified events, even if they don't include group properties, according to PostHog.
- Inspect delivery acceptance beyond response codes. Segment returns a 200 response but rejects the event when the number of batched events exceeds the limit, according to Twilio.
- Distinguish clock drift from acceptance windows. The 5-minute window is for clock drift between your server and Stripe systems, while the 35-day window determines whether Stripe accepts a meter event, according to Stripe.
Customer usage discrepancies: four steps to investigate
Conflicting usage figures often stem from misaligned reporting units. Establish the counting entity immediately. PostHog group analytics aggregates events by entities like organizations or companies instead of individual users, according to PostHog. This distinction separates account-level metrics from user-level activity.
Identify the reporting entity before investigating event delivery. A report counting organizations differs fundamentally from one counting distinct users. Verify which unit your renewal report uses. If the report aggregates by companies, compare it against user-level data only after confirming the conversion logic.
Record the specific identifier used for aggregation. This prevents mixing company counts with individual user counts. The investigation must start with this definition. Without it, subsequent checks on delivery and billing lack a consistent baseline.
Start by confirming whether your report counts entities or users. Proceed only after the counting unit is documented.
Step one: separate account counts, user counts and captured events
Start by identifying which entity each report counts. In PostHog, group analytics aggregates events by entities like organizations or companies instead of individual users, according to PostHog. If your renewal report pulls from this feature, the denominator is the organization, not the person. Contrast this with Mixpanel, where the default unique user count relies on distinct_id, according to Mixpanel. Mixing these bases creates immediate discrepancies: one report counts companies, the other counts individual identifiers.
Before comparing totals, record the specific user identifier in use. If your team has overridden this, note the custom identifier. The definition of "active" also varies. In Mixpanel, an active user is defined by both the activity, such as a document created event, and the frequency of that activity, such as performing the event at least one time, according to Mixpanel. A report that counts any event can still meet a frequency rule of at least one time.
Finally, separate captured events from group properties. PostHog usage is based on captured identified events, even if they do not include group properties, according to PostHog. To align your reports, create a simple worksheet for the renewal account. List each report source, the counting entity (organization, distinct_id, or event), and the activity definition. This prevents conflating a company-level aggregation with a user-level count. When the definitions differ, the numbers will not match, and the discrepancy is a definition issue, not a data loss issue.
Record the identifier and definition for each report before moving to delivery checks. This baseline clarifies which numbers should align and which are expected to differ due to scope.
Step two: check delivery acceptance before trusting response codes
A 200 response code does not prove that every event was accepted by the destination system. You must inspect request sizes and batch limits to identify events that were rejected despite a successful HTTP status. According to Twilio, there is a maximum of 32 KB for one normal API request. If your individual requests exceed this size, the system may not process them as expected. For larger data sets, the HTTP Tracking API accepts batch requests up to 500 KB according to Twilio. Verify that your batch payloads stay within this limit.
Segment returns a 200 response for all API requests except errors caused by large payloads and JSON errors, which return 400 responses, according to Twilio. This means a 200 status can accompany rejected events. To debug events that return 200 responses but aren't accepted by Segment, use the Segment Debugger according to Twilio. The documentation notes that Segment returns a 200 response but rejects the event when the number of batched events exceeds the limit according to Twilio. This specific rejection behavior occurs even when the HTTP status indicates success.
If you are setting up the HTTP API yourself, ensure all events have unique messageId values with fewer than 100 characters according to Twilio. Record the messageId format and length constraints for your specific implementation. Compare the documented limits against your actual request logs to find discrepancies. If you find events with 200 responses that are missing from your analytics, check the debugger for rejection reasons. Do not assume that a successful HTTP status means the data is available for reporting. Verify the acceptance status of each batch individually. This inspection step separates true delivery failures from system-level rejections that hide behind success codes.
See usage data limits.
Steps three and four: inspect meter timing and billed quantities
When reconciling usage figures, distinguish between clock drift allowances and event acceptance windows. The 5-minute window is for clock drift between your server and Stripe systems, according to Stripe. The 35-day window determines whether Stripe accepts a meter event, according to Stripe. These two windows serve different functions in the billing process. One addresses minor timing discrepancies between systems, while the other sets the boundary for event validity.
Check dimension limits to identify rejected events. For each customer on a meter, Stripe accepts up to 100 unique combinations across all events, according to Stripe. For each meter, Stripe accepts up to 10,000 unique combinations for each hour that Stripe receives meter events, according to Stripe. Events that introduce a new dimension combination after either limit is reached are invalid and appear in v1.billing.meter.error_report_triggered with the meter_event_dimension_count_too_high error code, according to Stripe.
To find evidence of these rejections, select v1.billing.meter.error_report_triggered and v1.billing.meter.no_meter_found from the list of events, according to Stripe.
Finally, reconcile negative usage reporting. If the overall cycle usage is negative, Stripe reports the invoice line item usage quantity as 0, according to Stripe. This rule applies to the invoice line item specifically. When reviewing billing quantities, check for this zero-value reporting to understand how negative totals are handled in the final invoice.
Record the specific meter error events and dimension combination counts for the account in question. Compare meter_event_dimension_count_too_high against the documented dimension-combination limits.
Usage discrepancy reference table by publisher
The table below maps each publisher to its documented counting, delivery, and metering rules. Use it to verify which specific limits apply to your conflicting reports.
| Publisher | Counting rule |
|---|---|
| PostHog | Group analytics aggregates events by entities like organizations or companies instead of individual users, according to PostHog. Usage is based on captured identified events, even if they don't include group properties, according to PostHog. |
| Mixpanel | By default, Mixpanel counts unique users by distinct_id, according to Mixpanel. An “active user” is defined by both the activity and frequency of the activity, according to Mixpanel. |
| Publisher | Delivery rule |
|---|---|
| Twilio | There is a maximum of 32 KB for one normal API request, according to Twilio. Segment's HTTP Tracking API accepts batch requests up to 500 KB, according to Twilio. Segment returns a 200 response but rejects the event when the number of batched events exceeds the limit, according to Twilio. Ensure all events have unique messageId values with fewer than 100 characters, according to Twilio. |
| Publisher | Meter rule |
|---|---|
| Stripe | The 5-minute window is for clock drift between your server and Stripe systems, according to Stripe. The 35-day window determines whether Stripe accepts a meter event, according to Stripe. For each meter, Stripe accepts up to 10,000 unique combinations for each hour that Stripe receives meter events, according to Stripe. For each customer on a meter, Stripe accepts up to 100 unique combinations across all events, according to Stripe. Events that introduce a new dimension combination after either limit is reached are invalid and appear in v1.billing.meter.error_report_triggered with the meter_event_dimension_count_too_high error code, according to Stripe. If the overall cycle usage is negative, Stripe reports the invoice line item usage quantity as 0, according to Stripe. |
Illustrative example: two totals on one account
Picture one renewal account. One report shows 100 events and the other shows 40. A user count of 4 can sit beside a company count of 1 when 4 users each do the activity 1 time. A batch of 20 can keep 15 and turn 5 away. A meter can then keep 10. These round figures are illustrative only. They show why you check the counting unit, then delivery, then meter timing.
Keep counting definitions, delivery evidence and meter errors on file
Record the counting identifier and activity definition for each report before asking the data owner to inspect delivery or meter errors.
Start with one renewal account that shows conflicting usage figures. Write down which entity or user identifier each report uses. Note the activity definition that counts an event as usage. Keep these definitions next to the raw event logs.
Save the delivery evidence from the data pipeline. Record the request size and batch limits for the events in question. Note the response codes and any rejected events that still returned a success status. Keep the unique message identifiers for each event.
Store the meter timing details from the billing system. Note the acceptance windows and dimension limits for the meter. Record v1.billing.meter.error_report_triggered and v1.billing.meter.no_meter_found events. Keep the billed quantities for the period.
See billing frequency.
FAQ: conflicting usage figures before renewal
How do I investigate customer usage discrepancies before renewal?
Begin by identifying whether the report aggregates entities or individual users, as these counting units differ fundamentally. After separating the counting basis, inspect delivery acceptance and meter timing to locate where figures diverge.
Does this investigation apply if my reports use Mixpanel distinct_id and PostHog company groups?
Yes. Mixpanel defaults to distinct_id, and PostHog group analytics aggregates by organizations or companies. You must record the specific identifier and activity definition for each report before comparing the figures.
Can Segment return a successful response while rejecting an event?
Yes, a 200 response can accompany rejected events when the number of batched events exceeds the limit. To debug events that return 200 responses but aren't accepted by Segment, use the Segment Debugger, according to Twilio.
What is the difference between Stripe's five-minute and 35-day windows?
The five-minute window handles clock drift, while the 35-day window determines whether the meter event is accepted, according to Stripe.
How does Stripe report negative usage across a billing cycle?
This behavior applies specifically to the billing cycle calculation for that meter.
Sources
Limits of this post
This post is general operational information, not legal advice about notice periods or renewal clauses. It does not promise that any method keeps a customer. A review model checked the facts once, and that check can miss errors, so open the sources before you act.