@@ -177,6 +177,17 @@ type ExchangeSettings struct {
177177
178178 ExchangeResidentTtl time.Duration
179179
180+ // 2026-07-15: network peers DISABLED pending a pubsub throughput
181+ // redesign. The per-resident listener model (one dedicated pubsub
182+ // connection + a poll per connected top-level client) times churn-driven
183+ // publish fanout structurally exceeds cluster pubsub capacity at fleet
184+ // scale: stalled consumers stop reading their sockets for up to the 60s
185+ // channel-send timeout, server-side output buffers accumulate across tens
186+ // of thousands of subscriber connections, and the shard-channel owner
187+ // nodes are pushed to maxmemory (2026-07-15 outage). Gates registration
188+ // (announce), heartbeat refresh, teardown publish, and the listener.
189+ EnableNetworkPeers bool
190+
180191 ExchangeResidentWaitTimeout time.Duration
181192 ExchangeResidentPollTimeout time.Duration
182193
@@ -242,6 +253,7 @@ func DefaultExchangeSettingsWithBufferSize(bufferSize int) *ExchangeSettings {
242253 ExchangeWriteHeaderTimeout : exchangeResidentWaitTimeout ,
243254 ExchangeReconnectAfterErrorTimeout : 1 * time .Second ,
244255 ExchangeResidentTtl : 300 * time .Second ,
256+ EnableNetworkPeers : false ,
245257
246258 ExchangeResidentWaitTimeout : exchangeResidentWaitTimeout ,
247259 ExchangeResidentPollTimeout : 15 * time .Second ,
@@ -420,25 +432,11 @@ func (self *Exchange) NominateLocalResident(
420432 instanceId ,
421433 residentId ,
422434 )
423- if resident .peerNetworkId != nil {
424- if resident .peerCategory == model .NetworkPeerCategoryProxy {
425- // proxy clients are counted but not visible peers
426- model .AddNetworkProxyPeer (
427- self .ctx ,
428- * resident .peerNetworkId ,
429- clientId ,
430- self .settings .ExchangeResidentTtl ,
431- )
432- } else {
433- model .AddNetworkPeer (
434- self .ctx ,
435- * resident .peerNetworkId ,
436- resident .peerProfile ,
437- residentId ,
438- self .settings .ExchangeResidentTtl ,
439- )
440- }
441- }
435+ // note: initial peer registration happens in ConnectionAnnounce.run once
436+ // the connection survives the announce window (2026-07-15: registration
437+ // on the nomination hot path melted pubsub under connection churn and
438+ // hung nominations against memory-full redis nodes). The heartbeat below
439+ // maintains and re-adds the registration for the resident's lifetime.
442440 go server .HandleError (func () {
443441 defer func () {
444442 cleanupCtx := context .Background ()
@@ -447,7 +445,10 @@ func (self *Exchange) NominateLocalResident(
447445 clientId ,
448446 resident .residentId ,
449447 )
450- if resident .peerNetworkId != nil {
448+ // RemoveNetworkPeer no-ops (no publish) when this resident never
449+ // registered, so churny residents that died before announcing
450+ // emit nothing here
451+ if self .settings .EnableNetworkPeers && resident .peerNetworkId != nil {
451452 if resident .peerCategory == model .NetworkPeerCategoryProxy {
452453 model .RemoveNetworkProxyPeer (
453454 cleanupCtx ,
@@ -531,10 +532,12 @@ func (self *Exchange) NominateLocalResident(
531532 // `ForwardIdleTimeout`), and without a refresh the registration
532533 // expires after `ExchangeResidentTtl` and other residents prune
533534 // it to a disconnect marker, bounding disconnect detection.
534- if resident .peerNetworkId != nil && 0 < resident .TransportCount () {
535+ if self . settings . EnableNetworkPeers && resident .peerNetworkId != nil && 0 < resident .TransportCount () {
535536 server .HandleError (func () {
536537 if resident .peerCategory == model .NetworkPeerCategoryProxy {
537- // AddNetworkProxyPeer doubles as the heartbeat
538+ // AddNetworkProxyPeer doubles as the heartbeat, and is
539+ // also the initial proxy registration (proxy clients
540+ // do not pass through ConnectionAnnounce)
538541 model .AddNetworkProxyPeer (self .ctx , * resident .peerNetworkId , clientId , self .settings .ExchangeResidentTtl )
539542 return
540543 }
@@ -2110,7 +2113,7 @@ func (self *Resident) Run() {
21102113 // The listener sends the complete list on subscribe (reset) and diffs
21112114 // after. Proxy clients are counted but not subscribed — a hosted device
21122115 // does not consume the peer list.
2113- if self .peerNetworkId != nil && self .peerCategory == model .NetworkPeerCategoryClient {
2116+ if self .exchange . settings . EnableNetworkPeers && self . peerNetworkId != nil && self .peerCategory == model .NetworkPeerCategoryClient {
21142117 networkPeerListener := model .NewNetworkPeerListener (
21152118 self .ctx ,
21162119 * self .peerNetworkId ,
0 commit comments