Skip to content

feat(batcher): Add global flush trigger based on summed size estimates - #7144

Merged
alexander-alderman-webb merged 14 commits into
masterfrom
webb/batcher/max-size-before-flush
Aug 10, 2026
Merged

feat(batcher): Add global flush trigger based on summed size estimates#7144
alexander-alderman-webb merged 14 commits into
masterfrom
webb/batcher/max-size-before-flush

Conversation

@alexander-alderman-webb

@alexander-alderman-webb alexander-alderman-webb commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Description

Add a global size limit to trigger a batcher flush. This mirrors the per-bucket logic.

Adapt the test_weight_based_flushing() test which tests the per-bucket bytes limit to a test which tests the global bytes limit. Also add the test_capture_after_length_based_flushing() to ensure accurate bookkeeping to track the total estimated size of spans in the batcher.

Issues

Closes #7137

Reminders

@alexander-alderman-webb
alexander-alderman-webb marked this pull request as ready for review August 10, 2026 07:12
@alexander-alderman-webb
alexander-alderman-webb requested a review from a team as a code owner August 10, 2026 07:12
Comment thread tests/tracing/test_span_batcher.py
@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Codecov Results 📊

99536 passed | ⏭️ 6623 skipped | Total: 106159 | Pass Rate: 93.76% | Execution Time: 348m 56s

📊 Comparison with Base Branch

Metric Change
Total Tests 📈 +30
Passed Tests 📈 +30
Failed Tests
Skipped Tests

All tests are passing successfully.

✅ Patch coverage is 88.89%. Project has 2500 uncovered lines.
❌ Project coverage is 90.01%. Comparing base (base) to head (head).

Files with missing lines (1)
File Patch % Lines
sentry_sdk/_span_batcher.py 88.89% ⚠️ 1 Missing
Coverage diff
@@            Coverage Diff             @@
##          main       #PR       +/-##
==========================================
- Coverage    90.02%    90.01%    -0.01%
==========================================
  Files          193       193         —
  Lines        25014     25020        +6
  Branches      9032      9032         —
==========================================
+ Hits         22516     22520        +4
- Misses        2498      2500        +2
- Partials      1435      1436        +1

Generated by Codecov Action

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit f6acf15. Configure here.

Comment thread tests/tracing/test_span_batcher.py
Comment thread sentry_sdk/_span_batcher.py
Comment thread tests/tracing/test_span_batcher.py
Base automatically changed from webb/batcher/max-spans-before-drop to master August 10, 2026 08:25
@alexander-alderman-webb
alexander-alderman-webb enabled auto-merge (squash) August 10, 2026 08:50
@alexander-alderman-webb
alexander-alderman-webb merged commit 2d86bfc into master Aug 10, 2026
140 checks passed
@alexander-alderman-webb
alexander-alderman-webb deleted the webb/batcher/max-size-before-flush branch August 10, 2026 09:02
Comment on lines +344 to +379
monkeypatch.setattr(SpanBatcher, "GLOBAL_MAX_BYTES_BEFORE_FLUSH", 2_000)
# set the time-based flush limit to something huge so that it doesn't
# interfere
monkeypatch.setattr(SpanBatcher, "FLUSH_WAIT_TIME", 100000)

sentry_init(
traces_sample_rate=1.0,
trace_lifecycle="stream",
)

items = capture_items("span")

with sentry_sdk.traces.start_span(name="span"):
pass

sentry_sdk.traces.new_trace()
with sentry_sdk.traces.start_span(name="span"):
pass

time.sleep(0.1)

assert len(items) == 2
assert items[0].payload["name"] == "span"


def test_total_size_reset_after_length_based_flushing(
sentry_init, capture_items, monkeypatch
):
"""Span is not flushed after a flush reduces the combined span size in bytes below the global limit."""
# Limit of 2_000 is just above the size of a bare span.
monkeypatch.setattr(SpanBatcher, "GLOBAL_MAX_BYTES_BEFORE_FLUSH", 2_000)
# set the time-based flush limit to something huge so that it doesn't
# interfere
monkeypatch.setattr(SpanBatcher, "FLUSH_WAIT_TIME", 100000)

sentry_init(

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.

Global byte limit tests hardcode span size assumption without dynamic measurement

Hardcoding GLOBAL_MAX_BYTES_BEFORE_FLUSH = 2_000 relies on a specific bare span size that varies with runtime environment; the test should dynamically compute span size like the adjacent test_weight_based_flushing_by_attribute_size.

Evidence
  • SpanBatcher._estimate_size() computes size from runtime attributes such as sys.argv length, installed integrations, and span metadata, making a bare span's size environment-dependent.
  • The neighboring test_weight_based_flushing_by_attribute_size avoids this exact fragility by calling SpanBatcher._estimate_size(bare_span._to_json()) before setting the flush limit.
  • Both test_global_length_based_flushing (line 344) and test_total_size_reset_after_length_based_flushing (line 379) assume a span size between 1,000 and 2,000 bytes. If the actual estimate falls outside this range, the global flush will not trigger as expected and the assertions will fail.

Identified by Warden · find-bugs · GYU-MGF

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add global span batcher limits

2 participants