Direct answer
Direct answer: real-time analytics for a web application should deliver a fresh, decision-ready view of events without making the interface, data model or operating cost unnecessarily complex. The reliable pattern is to define a specific live use case, create a versioned event contract, ingest events durably, calculate prepared state, stream only the changes the browser needs and show freshness, errors and reconnection honestly.
A dashboard that updates every second can still be wrong. It may count duplicate events, mix client time with server time, lose data during reconnects or show yesterday's state without a warning. The useful question is not “How do we add WebSockets?” It is “Which decision improves when this number arrives sooner, and how fresh must it be?”
That question protects the project from building a permanent distributed system for a metric that could refresh every minute. It also reveals where true immediacy matters: collaborative editing, auctions, operations consoles, live support, inventory, logistics, multiplayer state, fraud review or an incident dashboard.
Choose the live use case before the stack
Write one sentence that includes the user, event, decision and useful time window. “A support lead sees a rising queue within ten seconds and can rebalance agents” is a requirement. “The analytics should be real time” is not.
Then define a latency budget for the complete path: browser capture or backend event, network, ingestion, processing, storage, delivery and rendering. The target should include a percentile rather than only an average. A system that is fast most of the time but stalls during the important campaign launch needs a capacity and backpressure plan.
Decide what the number means before deciding how quickly it moves. Is “active user” a person with an open tab, a session that produced an event in the last five minutes or an authenticated account currently connected? Each definition produces a different chart. Put definitions in the product documentation and keep the same logic in batch reports so the team is not arguing with two versions of reality.
Design events as a product contract
An event should describe a meaningful fact, not mirror every DOM click. Useful fields usually include an event identifier, name, schema version, occurred-at timestamp, actor or anonymous-session reference, relevant object identifier, source and a small set of properties. Generate the identifier once and preserve it through retries.
Prefer business events such as checkout_completed, document_shared or shipment_delayed over brittle events like blue_button_clicked. Interface details change; the business fact should remain understandable. Client events can capture interactions the server never sees, but authoritative outcomes should generally come from the backend. A browser saying “payment succeeded” is not the same evidence as a confirmed payment record.
Version the schema and validate it at ingestion. Producers will change at different speeds, especially across web, mobile and backend services. Consumers should either understand the version or reject it visibly. Silent property renaming is how trustworthy dashboards become decorative.
Collect less. Extra properties create privacy, governance and migration work. If a field has no defined decision, retention period or owner, leave it out.
Polling, server-sent events or WebSockets?
Polling is often enough. The browser requests prepared state on an interval, the server stays stateless between requests and infrastructure is easy to cache and observe. Use it for modest freshness requirements, small audiences or dashboards that already tolerate periodic refresh.
Server-sent events are a strong fit when updates move mainly from server to browser. The browser's EventSource interface receives a text/event-stream response and reconnects automatically. MDN's server-sent events guide describes this one-way model. It works well for job progress, notification feeds and live metrics where the client still sends ordinary HTTP requests for commands.
WebSockets provide a two-way channel. They fit collaborative state, presence, games and fast command-and-update loops. MDN notes an important limitation of the browser WebSocket API: it does not provide backpressure. If messages arrive faster than the application can process them, memory or responsiveness can suffer. Aggregate updates, limit subscriptions and drop intermediate visual frames when the newest state is what matters.
Choose from communication shape and failure behaviour, not from perceived modernity. All three options need authentication, authorization, rate limits, reconnect logic, versioning and monitoring.
Process once, serve prepared state
Separate event intake from browser delivery. An ingestion endpoint validates and durably records events. A queue or stream allows processors to calculate counters, windows, funnels and materialized views without making the producer wait. A delivery service publishes compact changes to subscribed clients.
Assume at-least-once delivery and make processing idempotent. A retry should not increase revenue twice. Keep event time and processing time because mobile clients, background tabs and offline work can deliver events late. For windowed metrics, define how late data is accepted and when the displayed period becomes final.
Do not make every connected browser query the raw event store. Prepare the current state or incremental update once, then fan it out. Keep historical analysis in a store designed for analytical scans and current UI state in a fast, bounded representation. This separation improves both performance and cost.
Start smaller than the architecture diagram in your head. Our tech-stack guide applies here too: choose technology from the workload and the team's ability to operate it. A managed queue and a compact worker may be a better first release than a cluster with five unfamiliar systems.
When a Postgres-backed application needs CDC
If PostgreSQL is the source of truth for orders, subscriptions, account state or inventory, repeatedly scanning it for a live dashboard creates avoidable load and can miss deletes. Change data capture reads committed inserts, updates and deletes from PostgreSQL logical replication, then sends those changes to a stream or analytical destination.
A typical product architecture is PostgreSQL → a CDC reader such as Debezium or a managed connector → Kafka-compatible transport → an analytical store. The destination must handle duplicate deliveries, row versions and deletes before exposing the result. Tinybird's PostgreSQL migration guide documents this pattern and explains when a scheduled copy is simpler than CDC.
Do not route every analytics event through PostgreSQL. Clickstream, logs and telemetry can go directly to an event ingestion API when they are not transactional business state. CDC is most valuable where the database commit is the authoritative fact and the product needs that fact reflected in seconds.
Use live metrics that lead to action
Real-time analytics is most useful for operational questions. Which checkout step is failing now? Is a deployment increasing errors? Are orders building up in one region? Is a collaboration document falling behind? These metrics have an owner and a response.
Separate product analytics from technical observability. Product events explain behaviour and outcomes. Logs, metrics and traces explain how the system executed. Correlation identifiers can connect them without copying sensitive payloads into logs. OpenTelemetry's browser guidance shows how document load, user interaction and network instrumentation can contribute traces, while also warning that browser instrumentation remains experimental in parts. Adopt deliberately, not by installing every available plugin.
Give every live tile a freshness indicator and definition. Display the last successful update, the current scope and whether values are preliminary. A number without those cues looks more certain than it is.
Design the interface for connection state
A live interface has more states than “loading” and “done.” It can be connecting, current, delayed, reconnecting, partially stale or unavailable. Design each state. Preserve the last confirmed value but label it as stale; do not replace it with zero. A zero is data. Missing is a system condition.
Avoid animating every event. Human attention is limited, and constant motion makes trends harder to read. Batch visual updates, highlight meaningful thresholds and let users pause or narrow the stream. Provide a table or accessible textual summary for charts when the information is important.
Optimistic UI and analytics need different truth rules. A collaborative interface may show a local change before the server confirms it, but an operational metric should distinguish pending from confirmed. If both appear identical, users cannot understand a rollback.
Protect users before instrumenting everything
Create an event inventory with purpose, fields, legal basis where applicable, recipients, retention and deletion behaviour. Do not send full URLs, form values, search queries or free text by default; they can contain personal or confidential information. Remove secrets and tokens before data reaches logs or analytics.
Authorize subscriptions on the server. A user who can open a WebSocket is not automatically entitled to every topic. Re-check membership when roles change, use short-lived credentials, limit channel scope and close connections after logout or revocation.
Real-time systems can amplify abuse because one producer fans out to many consumers. Validate payload size and type, rate-limit producers, cap subscriptions and isolate tenants. Do not let user-provided event names become arbitrary topic paths.
Release and operate it like a distributed feature
Instrument event acceptance, rejection, queue lag, processing errors, duplicate rate, active connections, reconnects, fan-out delay and dropped updates. Create a synthetic event that traverses the complete path so a healthy status proves more than the public endpoint responding.
Roll out in stages. First calculate the metric beside the existing report. Compare definitions and totals. Then expose it internally with freshness and error states. Load-test reconnect storms and slow clients. Finally open it to the intended audience with cost and capacity alerts.
Have a graceful fallback. A live dashboard can switch to periodic refresh when the stream is unavailable. A progress view can offer manual refresh. The product remains useful while the team repairs the real-time layer.
If your application needs this architecture, start with a scoped technical consulting exercise or discuss the complete build with our web development team. The valuable deliverable is a clear event and decision model, not a shopping list of streaming tools.
FAQ
Is Google Analytics or another reporting tool real-time analytics?
It may provide a recent activity view, but an application-specific live feature usually needs owned event definitions, permissions, prepared state and a delivery path connected to a concrete decision.
Are WebSockets always faster than server-sent events?
Raw latency is rarely the deciding factor. WebSockets are two-way; server-sent events are server-to-client and simpler for many feeds. Choose based on message direction, reconnection, infrastructure and operating needs.
When should a dashboard stay batch-based?
Keep batch or periodic refresh when the decision does not improve with lower latency, the data becomes reliable only after reconciliation or the cost and complexity of streaming exceed the value.
Primary documentation consulted: MDN on the WebSocket API and server-sent events, the W3C Performance Timeline specification and OpenTelemetry browser instrumentation. Featured image generated for Influendoo on August 31, 2026; displayed data is abstract.
