Websockets Spring boot Kubernetes
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
WebSockets work well with Spring Boot, but running them in Kubernetes adds operational constraints that normal REST services do not face. A WebSocket connection is long-lived, stateful at the transport level, and sensitive to load balancer and ingress behavior. To run this stack reliably, you need both correct application configuration and cluster-level networking choices that respect persistent connections.
Basic Spring Boot WebSocket Setup
Spring Boot can expose a WebSocket endpoint with a handler and a simple configuration class.
This is enough for a local proof of concept. The harder part comes after you scale the service horizontally.
Kubernetes Changes the Runtime Model
In Kubernetes, multiple Pods may serve the same service. A WebSocket connection stays attached to one Pod after the initial upgrade, which means:
- in-memory session state is local to that Pod
- reconnects may land on a different Pod
- broadcasting across clients needs cross-Pod coordination
That is why a WebSocket service that works fine on one instance can behave unpredictably once replicas are added.
Keep Stateful Session Data Out of Pod Memory
If the application stores client presence, subscriptions, or room membership only in local memory, scaling becomes fragile. When a Pod dies, that state disappears. When another Pod needs to broadcast to all sessions, it cannot see sessions held elsewhere.
A better architecture uses a shared broker or store:
- Redis Pub/Sub
- Kafka
- STOMP broker relay
- database-backed session metadata, if latency allows
The rule is simple: local WebSocket connection objects stay in the Pod, but shared message-routing state must be externalized.
Ingress and Load Balancer Considerations
Your ingress controller or load balancer must support connection upgrades and sufficiently long idle timeouts. A typical NGINX Ingress annotation pattern looks like this:
If the idle timeout is too short, healthy WebSocket connections will be dropped even when the app is fine.
Service and Deployment Basics
The Kubernetes Service itself is standard, but you should think about readiness carefully. A Pod that is technically running but not ready to accept WebSocket connections should not receive traffic.
Deployment example:
That gets traffic flowing, but not necessarily broadcasting correctly across Pods. That part still requires shared messaging.
Broadcasting in a Multi-Pod Setup
If one client on Pod A sends a message that should reach clients connected to Pods B and C, the app needs an external fan-out mechanism. In Spring, a common answer is using a broker or broker relay rather than manual in-memory broadcasting only.
A local ConcurrentHashMap of sessions can handle one Pod. It is not a cluster-wide broadcast solution.
Readiness, Draining, and Shutdown
WebSockets complicate rolling deployments because clients may keep long-lived connections open. Your shutdown flow should:
- stop accepting new connections
- allow old connections to drain when possible
- close sessions cleanly before Pod termination
If termination is abrupt, clients must reconnect and your app should be prepared for that behavior.
Common Pitfalls
The biggest mistake is assuming WebSockets scale like stateless HTTP handlers. They do not. Long-lived connections create operational coupling between ingress, Pod lifecycle, and session routing.
Another issue is keeping important routing or presence state only in Pod memory. That works until you scale or restart.
Developers also often forget ingress timeout settings, which leads to random disconnects blamed on the application layer.
Summary
- Spring Boot can expose WebSocket endpoints easily, but Kubernetes adds connection-lifecycle and scaling concerns.
- Long-lived WebSocket sessions are bound to individual Pods after connection upgrade.
- Shared message-routing state should live outside Pod memory in a broker or shared backend.
- Ingress timeout and upgrade support must be configured correctly.
- Plan for reconnects, rolling restarts, and cross-Pod broadcasting from the start.

