Skip to content

fix(performance): exclude db.cursor spans from N+1 DB detection#118031

Open
ericapisani wants to merge 3 commits into
masterfrom
fix/n-plus-one-db-cursor-fetch-exclusion
Open

fix(performance): exclude db.cursor spans from N+1 DB detection#118031
ericapisani wants to merge 3 commits into
masterfrom
fix/n-plus-one-db-cursor-fetch-exclusion

Conversation

@ericapisani

@ericapisani ericapisani commented Jun 18, 2026

Copy link
Copy Markdown
Member

Summary

Cursor iteration in asyncpg (and other DB drivers that support server-side cursors) produces N spans that share the original SQL as their description. Each cursor.fetch() and cursor.__anext__ calls trigger a BaseCursor._exec invocation, which the SDK wraps as a db span — so the detector sees a source span followed by N identical repeating spans and fires a false-positive N+1 alert.

These are sequential calls draining a pre-existing server-side cursor result set, not N independently issued queries. They should be excluded from N+1 detection the same way db.redis and db.connection already are.

Changes

  • n_plus_one_db_span_detector.py: add not op.startswith("db.cursor") to _is_db_op, consistent with existing db.redis and db.connection exclusions.
  • test_n_plus_one_db_span_detector.py: adds tests for the 2 new operation names introduced that start with db.cursor following the pattern of the pg-pool.connect and cached-query tests.

Paired SDK change

The sentry-python asyncpg integration needs to tag cursor fetch spans with op='db.cursor.fetch' instead of the generic 'db' op. That change will be tracked in getsentry/sentry-python.

See getsentry/sentry-python#6609

Context


View Session in Sentry

Cursor iteration (e.g. asyncpg BaseCursor._exec on each cursor.fetch())
produces N spans with the original SQL as their description. These are
sequential FETCH calls draining a pre-existing server-side cursor, not
N independently issued queries — equivalent to how db.redis and
db.connection are already excluded.

Paired SDK change: sentry-python asyncpg integration will tag cursor
fetch spans with op='db.cursor.fetch' instead of the generic 'db' op.

Co-Authored-By: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com>
@github-actions github-actions Bot added the Scope: Backend Automatically applied to PRs that change backend components label Jun 18, 2026
@ericapisani ericapisani marked this pull request as ready for review June 19, 2026 17:43
@ericapisani ericapisani requested a review from a team as a code owner June 19, 2026 17:43
@ericapisani ericapisani requested review from a team and sl0thentr0py June 19, 2026 17:43
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.

1 participant