Severity
Medium — redundant CPU that scales with (message rate × connected viewers).
Problem
Every store event is broadcast to all WebSocket subscribers, and each subscriber's task serializes the same payload independently.
MessageStore::insert sends one StoreEvent::NewMessage(Box<summary>) over the broadcast channel (src/store.rs:120).
- Each connected client runs its own
handle_ws loop, and for every event calls send_ws_event (src/web.rs:230-243), which does serde_json::json!{...}.to_string() — a fresh JSON serialization of the identical summary, once per socket.
With N developers watching the same Orchestra feed (the documented multi-user scenario in CLAUDE.md), an incoming message is serialized N times into N identical strings.
Why it matters
The serialization is pure duplicated work on the hot ingest-broadcast path. At high message rates with several viewers it multiplies CPU and allocation for zero benefit, and competes with the parse/validate work already on that path (#180 / KB-4).
Suggested fix
Serialize each event payload once (e.g. in insert, or a small adapter that converts StoreEvent → pre-rendered JSON String/Arc<str> before broadcasting), then have each handle_ws task send the shared bytes verbatim. The broadcast channel can carry the already-serialized frame (or an Arc<str>) instead of the structured event, so per-socket work is just a send.
Found during the architecture review.
Severity
Medium — redundant CPU that scales with (message rate × connected viewers).
Problem
Every store event is broadcast to all WebSocket subscribers, and each subscriber's task serializes the same payload independently.
MessageStore::insertsends oneStoreEvent::NewMessage(Box<summary>)over the broadcast channel (src/store.rs:120).handle_wsloop, and for every event callssend_ws_event(src/web.rs:230-243), which doesserde_json::json!{...}.to_string()— a fresh JSON serialization of the identical summary, once per socket.With N developers watching the same Orchestra feed (the documented multi-user scenario in
CLAUDE.md), an incoming message is serialized N times into N identical strings.Why it matters
The serialization is pure duplicated work on the hot ingest-broadcast path. At high message rates with several viewers it multiplies CPU and allocation for zero benefit, and competes with the parse/validate work already on that path (#180 / KB-4).
Suggested fix
Serialize each event payload once (e.g. in
insert, or a small adapter that convertsStoreEvent→ pre-rendered JSONString/Arc<str>before broadcasting), then have eachhandle_wstask send the shared bytes verbatim. The broadcast channel can carry the already-serialized frame (or anArc<str>) instead of the structured event, so per-socket work is just asend.Found during the architecture review.