Do You Actually Need Real-Time? The Streaming Tax Most Devs Never Audit
Photo: server infrastructure data streaming network cables dashboard, via www.racksolutions.com
There's a moment every engineering team hits—usually around the third sprint of building a new dashboard or notification system—where someone says, "Let's just make it real-time." It sounds right. It feels modern. And WebSockets are right there in every major framework, practically begging to be used.
The problem? Real-time is expensive, and most teams never stop to ask whether they actually need it.
We're not talking about apps where milliseconds genuinely matter—stock trading platforms, multiplayer games, live surgical monitoring. We're talking about the analytics dashboard that refreshes 50 times a minute to show data that changes twice an hour. The notification feed hammering a WebSocket connection to deliver updates that could have waited five seconds. The activity log streaming events to a UI that nobody's watching.
If any of that sounds familiar, your infrastructure is probably running a tab you forgot to close.
The Real Cost of "Always On"
Let's get concrete. A persistent WebSocket connection isn't free. On the server side, each open connection holds memory, a file descriptor, and CPU cycles for heartbeat management. At modest scale—say, 10,000 concurrent users—that's manageable. At 500,000, you're looking at serious infrastructure overhead just to keep connections alive, regardless of whether any data is actually flowing.
Then there's the upstream cost. Real-time architectures typically rely on message brokers like Kafka, Redis Pub/Sub, or AWS Kinesis sitting between your data sources and your connected clients. These aren't cheap to run, and they're especially not cheap when they're processing a firehose of events to deliver updates that land in a UI nobody has open.
One mid-size SaaS company—a project management tool with around 80,000 active users—audited their streaming stack and found that roughly 65% of their WebSocket connections were to browser tabs that hadn't been interacted with in over 20 minutes. They were paying to push updates into the void. After implementing a simple inactivity timeout that downgraded idle connections to polling, their message broker costs dropped by nearly half within a billing cycle.
Polling Isn't Dead—It Just Got Smarter
Polling got a bad reputation because naive polling is genuinely wasteful: hit an endpoint every second, get back the same data 59 times out of 60, repeat forever. But intelligent polling is a different animal entirely.
The core idea is adaptive intervals. If your endpoint returns unchanged data three times in a row, back off—poll every 10 seconds instead of every 2. If something changes, tighten the interval back up. This alone can cut request volume by 60-70% for typical low-churn data sources without any perceptible difference to the user.
Server-Sent Events (SSE) are another underused middle ground. Unlike WebSockets, SSE is unidirectional—the server pushes updates to the client over a standard HTTP connection, but the client doesn't maintain a persistent bidirectional channel. For read-heavy use cases like live feeds, dashboards, and notification streams, SSE is lighter, simpler to implement, and works through standard load balancers without extra configuration. If you're not sending data from the client in real-time, you probably don't need a WebSocket.
Delta Compression: Only Send What Changed
Even when real-time delivery is genuinely warranted, most implementations send way more data than necessary. Full state snapshots flying across the wire every few seconds add up fast—both in bandwidth costs and in the CPU overhead of serializing and deserializing those payloads.
Delta compression—sending only the diff between the previous state and the current one—can slash payload sizes dramatically. Libraries like json-patch (RFC 6902) or immer on the client side make this pattern relatively straightforward to implement. For structured data with predictable schemas, a binary diff format like MessagePack or CBOR can compress deltas even further.
One fintech team that rebuilt their real-time portfolio view this way cut their outbound WebSocket traffic by 73%. Same update frequency, same user experience, less than a third of the data.
The Caching Layer Nobody Adds to Real-Time
Here's a pattern that gets overlooked constantly: a shared cache in front of your real-time data source. If 1,000 clients are all subscribed to the same "top products" feed, there's no reason to compute that payload 1,000 times. Compute it once, cache it with a short TTL, and fan it out.
Redis works well here, but even a simple in-memory cache with a 2-second expiry can eliminate a massive amount of redundant computation. The key insight is that "real-time" and "cached" aren't mutually exclusive. A result that's 1.5 seconds old is still effectively real-time for 99% of use cases—and it's a result you computed once instead of a thousand times.
Before You Rearchitect: The Audit Checklist
Before touching any infrastructure, spend an afternoon answering these questions:
- What's the actual update frequency of your data source? If it changes every 30 seconds, a 2-second polling interval is overkill.
- What percentage of connected clients are actively viewing the UI? Instrument this. The answer is usually surprising.
- Are you sending full state or deltas? If full state, how large are those payloads?
- Do any of your real-time channels only flow one direction? If so, WebSockets might be the wrong tool.
- What does your message broker cost per month, and what percentage of messages result in a visible UI change?
The last question tends to be the most clarifying. When teams calculate the ratio of messages processed to meaningful UI updates delivered, the number is often somewhere between 5% and 15%. The rest is overhead.
The Bottom Line
Real-time infrastructure is a powerful tool, and there are absolutely applications that need it. But it's become a default choice rather than a deliberate one, and that default carries a real cost—in compute, in complexity, and in the engineering time required to maintain systems that are more sophisticated than the problem actually demands.
The fastest path to cheaper, more maintainable streaming isn't a new tool or a different cloud provider. It's asking an honest question: does this data actually need to move this fast? More often than not, the answer will surprise you—and so will the savings.