Per-connection resource cost
Each WebSocket connection consumes: one file descriptor, ~10-50KB of memory (read/write buffers + framework metadata + your per-connection state), zero CPU at idle, and CPU proportional to message rate when active. 100K connections fit on one beefy box. 1M is achievable but takes care. 10M needs sharding by region or a managed service.
OS limits matter
Linux defaults to 1024 file descriptors per process. Without raising this, you cannot open 1024 WebSocket connections on one server. Raise via ulimit, limits.conf, and sysctl. Tune net.core.somaxconn and tcp_max_syn_backlog to handle reconnect storms after a network blip.
Self-host vs managed: the honest tradeoff
Self-host is cheap at 1K connections, expensive at 10M. Managed is expensive at 1K connections, cheap at 10M because you get scale and on-call expertise without hiring a team. The crossover for most apps is around 100K-1M concurrent. cwkPippa is firmly in self-host territory; a global SaaS chat product probably is not.