一键导入
realtime-scaling
Scale a realtime backend horizontally with pub/sub fanout and presence tracking. Use when moving past a single-node WebSocket/SSE server.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Scale a realtime backend horizontally with pub/sub fanout and presence tracking. Use when moving past a single-node WebSocket/SSE server.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | realtime-scaling |
| description | Scale a realtime backend horizontally with pub/sub fanout and presence tracking. Use when moving past a single-node WebSocket/SSE server. |
Realtime backends are stateful: each user's connection lives on one node. Horizontal scale is a fanout + routing problem, not a stateless load-balance problem.
Each realtime node holds:
channel -> [connection] (local subscribers).connection -> [channel] (for cleanup on disconnect).No user state lives only in one node -- persist whatever must survive a node restart.
Every business-side event publishes once to a pub/sub bus; every node filters against its local subscriber map.
publisher -> bus(channel=X) -> [nodeA, nodeB, nodeC]
| | |
v v v
matching local connections dispatch
Options:
For most mobile apps under a few hundred thousand concurrent connections, Redis (Pub/Sub + Streams) is sufficient.
Hierarchical, coarse first:
user:{user_id} -- direct messages, badges
thread:{thread_id} -- chat channel
entity:{type}:{id} -- per-object updates
broadcast:{tenant} -- fanout to all users in a tenant
Avoid per-connection channels -- they do not fan out and increase subscription churn.
When a client subscribes, the node checks whether it is already subscribed to that bus topic. Maintain a refcount:
func (n *Node) Subscribe(conn *Conn, ch string) {
if n.refs[ch] == 0 { n.bus.Subscribe(ch) }
n.refs[ch]++
n.channels[ch] = append(n.channels[ch], conn)
}
func (n *Node) Unsubscribe(conn *Conn, ch string) {
// remove conn from n.channels[ch]
n.refs[ch]--
if n.refs[ch] == 0 { n.bus.Unsubscribe(ch) }
}
One bus subscription per node per channel. Internal fanout is O(subscribers on node).
Presence = "who is online in channel X right now". Cheap versions use Redis sorted sets keyed by channel, scored by last heartbeat timestamp:
ZADD presence:thread:thr_01HX7 <now_ms> <user_id>
ZREMRANGEBYSCORE presence:thread:thr_01HX7 0 <now_ms - 30_000>
ZRANGE presence:thread:thr_01HX7 0 -1 -- currently online
The node updates the user's score on every heartbeat. A separate janitor cleans stale entries every 30 s.
For large channels, do not broadcast "X is online" to everyone; push presence diffs or count-only updates.
A user has N devices connected to possibly N different nodes. Publishing to user:{user_id} reaches all of them via the bus. No extra logic needed if channel naming is correct.
Balance connections across nodes uniformly (consistent hashing by device_id) or randomly. Sticky sessions are not required if the bus fans out properly, but they help in two cases:
user_id).Rules of thumb per node (modern hardware, well-tuned):
Scale by adding nodes behind the LB; the bus absorbs fanout.
XADD + consumer groups, not PUBLISH.Per node: open connections, messages/sec (in/out), bus lag, per-channel fanout p95, CPU %, memory. Alert on concurrent-connection drops > 10% minute-over-minute (likely bug or bus issue, not user behavior).
When and how to use a Backend-for-Frontend (BFF) for mobile -- scoping, ownership, and anti-patterns. Use when deciding whether a BFF is justified or designing one.
GraphQL server design tuned for mobile -- persisted queries, batching, N+1 mitigation, and Apollo client integration. Use when building or reviewing a GraphQL API for mobile apps.
Design mobile-friendly HTTP APIs with predictable pagination, filtering, sorting, sparse/partial responses, and a consistent error envelope. Use when specifying new endpoints or reviewing existing ones for mobile use.
REST conventions tuned for mobile clients -- resources, HTTP caching, idempotency, and versioning. Use when designing or reviewing RESTful endpoints.
Server-side OAuth 2.1 + PKCE for native mobile apps -- authorization endpoint, token endpoint, refresh rotation, and device binding. Use when implementing or reviewing the auth server for mobile clients.
Model multi-device sessions on the backend with sliding vs absolute expiry, device listing, and remote logout. Use when building the session model or a "Your devices" screen.