Engineering Note

Our Rails app handled 5,000 concurrent users easily. Adding real-time updates changed everything.

We introduced ActionCable for live notifications and status updates.

The feature worked perfectly in testing.

Production told a different story.

As adoption grew, we noticed:
* Memory usage increasing steadily
* WebSocket connections staying open for hours
* Background jobs competing with real-time broadcasts
* Response times becoming inconsistent during peak traffic

The surprising part?

The database wasn't the bottleneck.

Persistent connections were.

Instead of adding more application servers, we changed the architecture:
* Moved heavy work to Sidekiq before broadcasting
* Broadcast only essential updates
* Reduced unnecessary WebSocket subscriptions
* Monitored connection count alongside CPU and memory

The impact was immediate:
* Memory usage stabilised
* Fewer connection drops during peak traffic
* More consistent real-time performance

Important learning:
Real-time features are easy to build.

Running them reliably at scale is where the engineering starts.

Every open WebSocket is a long-lived production resource.

Treat it that way.