Skip to content

perf: avoid reading HTTP request body before drop/sample decisions#44

Merged
jy-tan merged 1 commit intomainfrom
drop-before-read-body
Jan 17, 2026
Merged

perf: avoid reading HTTP request body before drop/sample decisions#44
jy-tan merged 1 commit intomainfrom
drop-before-read-body

Conversation

@jy-tan
Copy link
Contributor

@jy-tan jy-tan commented Jan 17, 2026

Summary

Optimizes inbound HTTP request handling by performing drop transform checks and sampling decisions before reading the request body. Previously, the WSGI handler (and by extension Flask) would capture the full request body upfront, even for requests that would ultimately be dropped or not sampled, resulting in unnecessary I/O.

Problem

The WSGI handler was capturing the full request body before checking:

  1. Whether the request should be dropped by transform rules (e.g., /health* endpoints)
  2. Whether the request should be sampled

This meant:

  • Unnecessary stream reads for requests that would be skipped
  • Wasted memory allocation for buffering bodies that are never used
  • The original wsgi.input stream was consumed and replaced with a BytesIO, even when not needed

Solution

Introduced should_record_inbound_http_request() utility in mode_utils.py that consolidates drop and sampling checks into a single pre-flight check. All HTTP server instrumentations now call this before reading the request body.

New flow:

Extract method/target/headers (cheap, no body read)
         ↓
should_record_inbound_http_request()  →  Drop check  →  Sampling check
         ↓
    If False: return early (body never read)
         ↓
    If True: capture body  →  create span  →  process request

Changes

  • drift/core/mode_utils.py: Added should_record_inbound_http_request() utility
  • drift/instrumentation/wsgi/handler.py: Pre-flight check before capture_request_body()
  • drift/instrumentation/django/middleware.py: Pre-flight check before request.body access
  • drift/instrumentation/fastapi/instrumentation.py: Consolidated inline drop/sample checks into shared utility

Design Decisions

  1. RECORD mode only: Pre-flight checks only apply to RECORD mode. REPLAY mode skips them since the CLI controls what gets replayed.

  2. HTTP-specific naming: Function is named should_record_inbound_http_request (not generic should_record_inbound_request) to be explicit about protocol specificity and leave room for future should_record_inbound_grpc_request or similar.

  3. Consistent behavior: All three HTTP server instrumentations (WSGI/Flask, Django, FastAPI) now have identical pre-flight check behavior.

Testing

  • ✅ All unit tests pass (182 passed)
  • ✅ Flask e2e tests pass (8/8)
  • ✅ Django e2e tests pass (8/8)
  • ✅ FastAPI e2e tests pass (10/10)

@jy-tan jy-tan changed the title perf(instrumentation): avoid reading HTTP request body before drop/sample decisions perf: avoid reading HTTP request body before drop/sample decisions Jan 17, 2026
Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 4 files

@jy-tan jy-tan merged commit fd714f8 into main Jan 17, 2026
17 checks passed
@jy-tan jy-tan deleted the drop-before-read-body branch January 17, 2026 04:22
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.

2 participants