app-server: WebSocket notification fan-out serializes once per recipient
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 35/100
- Issue type
- Refactor
- Clarity
- Mostly clear
- Activity status
- Quiet
- Tech stack
- rust
- Domain
- backend, performance
Research direction
Start with send_server_notification_to_connections in codex-rs/app-server/src/outgoing_message.rs, then trace route_outgoing_envelope and filter_outgoing_message_for_connection in codex-rs/app-server/src/transport.rs. Read run_websocket_outbound_loop and serialize_outgoing_message in the transport crate, and coordinate with #36655. Done means admitted unchanged notifications share serialization while per-connection queues, filtering, failures, ordering, and framing remain unchanged.
Written by the indexing model from the issue text.
Description
What variant of Codex are you using?
App Server
What feature would you like to see?
I found a potential performance concern in current source rather than a confirmed user-visible bug. When the same ServerNotificationEnvelope is admitted for multiple WebSocket recipients, route_outgoing_envelope clones the typed OutgoingMessage into each bounded writer queue. Each run_websocket_outbound_loop then calls serialize_outgoing_message independently, so identical eligible notification payloads are serialized once per WebSocket recipient.
Please consider a shared immutable notification wrapper with one lazily initialized serialized JSON string. Reuse it only after should_skip_notification_for_connection admits a recipient and filter_outgoing_message_for_connection leaves the notification unchanged. Per-connection queue entries and write_complete_tx values must remain separate; serialization-failure handling, FIFO delivery, bounded slow-client disconnect behavior, targeting, initialization checks, opt-outs, experimental gating, and WebSocket text framing must remain unchanged. Requests, responses, and any payload rewritten per connection are outside this proposal.
Additional information
Evidence
send_server_notification_to_connectionsbuilds one targeted notification and clones it for selected connections.route_outgoing_envelopeidentifies eligible broadcast connections and clones the same message per recipient.filter_outgoing_message_for_connectiononly rewrites command-execution approval requests. For notifications,should_skip_notification_for_connectioncan drop a recipient but does not rewrite the delivered payload.run_websocket_outbound_loopcallsserialize_outgoing_messageafter dequeueing each message, creating a separate JSON string per recipient writer.- Related but distinct: #36655 tracks the targeted emitter’s unnecessary deep payload clone, while this report concerns repeated downstream WebSocket serialization. A shared notification wrapper or cache may address both costs, so implementation should be coordinated with #36655 rather than introduce a parallel notification representation. #34761 removed an intermediate JSON Value conversion but still serializes each queued WebSocket copy.
Impact
Not measured. An identical admitted notification may be serialized and allocated once per WebSocket recipient. Potential CPU and allocation cost scales with notification size, eligible WebSocket recipient count, and notification rate; throughput, latency, allocation volume, and occurrence have not been measured.
Question
Would maintainers consider a shared lazily serialized notification wrapper that preserves per-connection filtering, queues, write-complete signaling, and WebSocket framing?
I checked all relevant issues, comments, pull requests, discussions, and release notes; this report is not a duplicate.
I am reporting this finding only and am not proposing a pull request unless a maintainer invites one.
Disclosure
Investigated thoroughly with GPT-5.6 (high reasoning effort), using Oh My Pi as the agent framework.
This report is not generic or unreviewed AI-generated output. Its claims were checked against the cited evidence, and it includes the relevant detail intended to help maintainers resolve the issue.
If reports like this are not useful to the project, please let me know and I will refrain from submitting similar ones. My intent is to help without wasting maintainer time or energy or discouraging their work.
Thank you for your work.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.5k
- Avg merge
- 1m
- Merged PRs (30d)
- 1k
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from openai/codex
-
enhancement remote
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
bug CLI windows-os
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
macOS sandbox blocks hw.optional.arm64 sysctl, causing Flutter to misdetect Apple Silicon as x64 Openbug CLI sandbox
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
bug CLI TUI
Difficulty 2/5 1-3 hours Newbie friendliness 90/100
-
CLI config enhancement skills
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
kwakseongjae/auto-hwp#319 ·
-
area:cli bug filter-quality good first issue priority:medium
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
Difficulty 1/5 Under an hour Newbie friendliness 72/100
bevyengine/bevy#25861 ·
-
comp-datalake
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
ClickHouse/ClickHouse#121222 ·
-
A-linter
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
oxc-project/oxc#26863 ·