Skip to content

feat(ingest-metrics): Ensure billing metrics consumer avoids outcome double-billing#117186

Open
klochek wants to merge 2 commits into
masterfrom
christopherklochek/billing_consumer_relay
Open

feat(ingest-metrics): Ensure billing metrics consumer avoids outcome double-billing#117186
klochek wants to merge 2 commits into
masterfrom
christopherklochek/billing_consumer_relay

Conversation

@klochek

@klochek klochek commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

With relay producing billing outcomes here, introduce and check for a new tag ("billing_outcome_accepted") to avoid double-billing.

I checked for prior string existence with:

SELECT string, count(*) 
FROM sentry_{perf,}stringindexer 
WHERE 1=1
    AND string IN (
        'billing_outcome_accepted'
    ) 
GROUP BY string;

Guarded by a new temporary flag organizations:relay-generate-billing-outcome

@klochek klochek requested review from a team as code owners June 9, 2026 15:47
@github-actions github-actions Bot added the Scope: Backend Automatically applied to PRs that change backend components label Jun 9, 2026
Comment on lines +84 to +86
if generic_metric["tags"].get(self.billing_outcome_accepted_tag) == "true":
return {}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The billing metrics consumer unconditionally suppresses outcomes without checking the organizations:relay-generate-billing-outcome feature flag.
Severity: HIGH

Suggested Fix

Before checking the billing_outcome_accepted tag, retrieve the organization associated with the metric. Wrap the suppression logic in a feature flag check, such as if features.has("organizations:relay-generate-billing-outcome", organization):, to ensure it only executes when the feature is enabled for that organization.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: src/sentry/ingest/billing_metrics_consumer.py#L84-L86

Potential issue: The billing metrics consumer at
`src/sentry/ingest/billing_metrics_consumer.py` unconditionally suppresses billing
outcomes if the `billing_outcome_accepted` tag is `"true"`. This logic should only
execute when the `organizations:relay-generate-billing-outcome` feature flag is enabled
for the specific organization. Because the feature flag check is missing, billing
metrics will be incorrectly dropped for organizations where the feature is not yet
active, leading to inaccurate billing data and potential revenue loss.

Did we get this right? 👍 / 👎 to inform future reviews.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's totally fine and we should not check the feature flag.

Logical this is two separate components:

  • Consumer can skip metrics
  • Feature flag to control logic in Relay


manager.add("projects:workflow-engine-performance-detectors", ProjectFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=False)

manager.add("organizations:relay-generate-billing-outcome", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=False)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The feature flag also needs to be exposed to Relay, search for EXPOSABLE_FEATURES

Comment on lines +84 to +86
if generic_metric["tags"].get(self.billing_outcome_accepted_tag) == "true":
return {}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's totally fine and we should not check the feature flag.

Logical this is two separate components:

  • Consumer can skip metrics
  • Feature flag to control logic in Relay

assert next_step.join.call_count == 1


@with_feature("organizations:relay-generate-billing-outcome")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@with_feature("organizations:relay-generate-billing-outcome")

Mentioning the feature here should not be necessary because the consumer-side behavior is determined by the tag, not the feature flag, right? This might also be what confused sentry[bot] in their comment above.

"has_transaction": PREFIX + 281,
"was_transaction": PREFIX + 282,
"is_segment": PREFIX + 283,
"billing_outcome_accepted": PREFIX + 284,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if you already bikeshedded on the name but billing_outcome_emitted would make slightly more sense to me (the outcome is Accepted but the thing relay does is emitting it).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants