perf(obs): carry stream shape as attributes, not one span per SSE chunk #141
No reviewers
Labels
No labels
burndown-2026-08
autonomy
async-consult
autonomy
epic
autonomy
headless
autonomy
live-collab
coherence-core
priority
P0
priority
P1
priority
P2
priority
P3
priority
P4
qa-fixture
role/advocate
role/director
role/exec
role/frontend
role/gamedev
role/human
role/platform
role/qa
role/science
role/sysadmin
state
ambient
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
coilyco-flight-deck/agent-proxy!141
Loading…
Reference in a new issue
No description provided.
Delete branch "task/issue-140-sse-chunk-spans"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #140.
The problem
The ASGI instrumentation spans every send, and on the streaming path one send is one SSE frame. A streamed completion therefore cost a
POST /v1/chat/completions http sendspan per chunk: 361,384 of them over 24h, the majority of all trace volume the proxy produced.Ingest cost was the smaller half. The trace API caps a trace at 1000 spans, and one sampled 183s
sirens-dowelturn burned 965 of that budget on chunk spans from a single completion. The turn span and its tool calls fell outside the cap and never rendered. Any trace holding a streamed completion was opaque, which is the exact trace an operator opens.What this does
Takes the issue's first-choice option: no per-chunk spans at all, stream shape as attributes instead.
exclude_spans=["send"]onFastAPIInstrumentor.instrument_appretires the chunk spans. The knob is per-app, so the singlehttp sendspan on non-streaming responses goes with them. It carried a status code the server span already reports.request.chatspan:agentproxy.stream.frames,.bytes,.duration_ms, and.first_token_ms.first_token_msis absent, not zero, when a stream produced no content. A stream that died before generating and one that answered instantly are different events.error.type.The dependency floor is load-bearing
exclude_spansarrived inopentelemetry-instrumentation-fastapi0.48b0, and the floor moves from 0.46b0 to match._instrument_fastapiswallows exceptions so observability never blocks startup, which means an older wheel would reject the keyword and silently drop all inbound tracing rather than just the send spans. The new test asserts the server span survives for that reason, not only that the chunk spans are gone.Verification
tests/test_stream_spans.py, 5 tests. Each was mutation-checked: removingexclude_spans, dropping the attribute stamping, always-emittingfirst_token_ms, and skipping heartbeat frames each fail the suite.just format-check,just lint,just typecheck, andpre-commit run --all-filesall clean.docs/stream-accounting.md, linked fromdocs/proxy.mdanddocs/features-landed.md.🤖 Generated with Claude Code