Bug
The per-IP WS connection cap is enforced with a non-atomic read-then-increment. Concurrent upgrades from one IP can all observe count < limit before any increment lands, then each proceed to increment — overshooting the cap.
Source
src/routes/ws.ts
653 const ipConnections = await store.getConnectionCount(`auth:${clientIp}`);
654 if (ipConnections >= MAX_CONNECTIONS_PER_IP) { ws.close(...); return; }
657 await store.incrementConnectionCount(`auth:${clientIp}`);
Same pattern in the auth-upgrade path at :822-834.
Impact
getConnectionCount and incrementConnectionCount are two separate network round-trips on Upstash. Concurrent upgrades from one IP can all observe count < limit before any increment lands, then each increment — overshooting MAX_CONNECTIONS_PER_IP. The overshoot is more severe on the Upstash/multi-replica path.
Fix
Add an atomic incrementConnectionCountIfBelow(key, limit) → { count, admitted } to SharedStore. Mirror the existing incrementRateBucket Lua script pattern at shared-store.ts:329-361: a single INCR-compare-DECR-on-reject script for Upstash, and a synchronous check-increment in InMemoryStore. Reject when !admitted.
Verification
Fire N (> cap) simultaneous upgrade requests from one IP → admitted count never exceeds the configured cap.
Bug
The per-IP WS connection cap is enforced with a non-atomic read-then-increment. Concurrent upgrades from one IP can all observe
count < limitbefore any increment lands, then each proceed to increment — overshooting the cap.Source
src/routes/ws.tsSame pattern in the auth-upgrade path at
:822-834.Impact
getConnectionCountandincrementConnectionCountare two separate network round-trips on Upstash. Concurrent upgrades from one IP can all observecount < limitbefore any increment lands, then each increment — overshootingMAX_CONNECTIONS_PER_IP. The overshoot is more severe on the Upstash/multi-replica path.Fix
Add an atomic
incrementConnectionCountIfBelow(key, limit) → { count, admitted }toSharedStore. Mirror the existingincrementRateBucketLua script pattern atshared-store.ts:329-361: a single INCR-compare-DECR-on-reject script for Upstash, and a synchronous check-increment inInMemoryStore. Reject when!admitted.Verification
Fire N (> cap) simultaneous upgrade requests from one IP → admitted count never exceeds the configured cap.