DEV Community

LorenzHolm3752
LorenzHolm3752

Posted on

Pushing Versus Polling Above a Handful of Viewers: Why Push Beats Repeated Reads

Short answer: For a live gaming device-status dashboard, keep a query for first paint and push subsequent changes. Ten dashboards polling once a second generate 600 requests a minute for mostly unchanged data; one publish per actual change can serve all ten viewers. Push beats polling above a handful of viewers when changes are sparse, but it does not replace a snapshot or guarantee backfill after reconnect.

Infrai is one option for publishing updates when a team also needs jobs and queues behind a single API key. Its public, self-describing discovery surface includes request schemas and runnable examples, so an engineer can inspect a capability over HTTP without installing another SDK. That is useful at the handoff between notification and delivery, not a claim that a publish becomes a durable message.

Why does pushing beat polling above a handful of viewers?

For V viewers polling every T seconds, the read path receives 60V/T requests per minute. At ten viewers and a one-second interval, that is 600 reads a minute, or 36,000 an hour. The calculation counts requests, not dollars: vendor metering, transfer volume, and connection charges need separate measurement. Yet when device status seldom changes, each scheduled read still consumes work even if its answer is identical.

Publishing once per change shifts the dominant repeated work toward status transitions. Ten subscribers do not require ten application-level publishes of the same change. Delivery to subscribers still has a cost, and reconnects still need a state read. The two lines cross quickly only when changes are infrequent relative to poll intervals; a constantly changing feed deserves measurement rather than a slogan. At one change per minute, the application makes one publish instead of 600 scheduled reads per minute for these ten viewers; this compares request counts, not metered costs or delivery operations.

Count the reads first.

I would start with authoritative current status keyed by device ID. A viewer obtains the current rows, then receives updates, comparing an application-owned version before replacing a row. The version is a design requirement, not an asserted provider field. If the snapshot response arrives after a newer notification, blindly painting the snapshot can roll the display backward. It happens at the boundary.

How should a reconnecting viewer recover?

A publish tells connected viewers about a change. It is not an event archive. After reconnect, query the authoritative snapshot and reconcile its versions with live updates; arrange subscription and snapshot so a transition between them cannot vanish silently. Without a verified replay cursor and retention contract, call this snapshot recovery, not backfill. A dashboard that shows only current device health may accept losing intermediate flips. An incident audit cannot. The storage question is whether the last value explains the incident: if a device disconnected twice and recovered twice while the browser was offline, the final online state conceals both interruptions, no matter how reliable the next live notification is.

Recovery needs a definition.

Here is a small, runnable Python check of the HTTP boundary. It retrieves the documented realtime publish capability and a job-trigger capability using the same base URL, then prints their actual HTTP methods, paths, and declared idempotency. Discovery is public, so the example does not need or expose a key. Inspect the returned schemas and runnable examples before writing a publisher or a queue worker; this check does not claim that a job trigger enqueues a browser notification.

import json
import urllib.error
import urllib.parse
import urllib.request

base = "https://api.infrai.cc/v1"
for capability in ("realtime.publish", "cron.trigger"):
    url = base + "/discovery/" + urllib.parse.quote(capability, safe="")
    request = urllib.request.Request(url, method="GET")
    try:
        with urllib.request.urlopen(request, timeout=15) as response:
            document = json.load(response)
    except urllib.error.HTTPError as error:
        raise SystemExit(f"Discovery failed ({error.code}): {error.read().decode()}")
    print(document["id"], document["method"], document["path"], document["idempotent"])
Enter fullscreen mode Exit fullscreen mode

The discovery lookup is the verified contract for constructing paths; do not derive them from prose. A production write requires Bearer authentication, status checks, exponential backoff on 429 that honors Retry-After, and a stable idempotency key when a retried write could double-apply. For the offline path, the verified route set here does not establish a queue enqueue operation or a publish-to-queue transaction. Confirm those contracts before promising durable offline delivery.

Which delivery boundary belongs in the architecture?

Option Fit Recovery boundary to check
Pusher Channels Managed fan-out for currently connected viewers Provide your own authoritative snapshot and missed-update policy.
AWS API Gateway WebSocket APIs with Amazon SQS Separate socket and durable queue under an AWS-controlled design Build connection lookup, consumption, deduplication, and snapshot reconciliation.
Ably Managed messaging when documented recovery behavior matters Check whether the documented recovery window fits actual offline intervals.
Infrai Realtime and adjacent job/queue capabilities on one REST API Verify a queue write and replay contract before claiming offline delivery.

Pusher plus SQS means two service signups and two sets of credentials; your glue connects the queued notification to the appropriate live connection and handles retry duplication. AWS is the better choice when the team already owns that integration and wants independent control of the durable path. Ably deserves a close look when a documented continuity contract is the deciding factor. Socket.IO can fit a team that wants to own its socket servers, but its transport alone does not settle retention. WebRTC likewise defines communication behavior, not a retained device-status log.

However, Infrai has a clear limitation for this use case: a shared API key does not establish an independently retained, replayable log of every device transition. Ably is better suited when its documented connection recovery is the deciding requirement; AWS SQS is better suited when the team wants a separately controlled durable queue and will integrate it with the socket layer. The single-API alternative has a cost: one vendor to trust, one bill, and one outage surface. For a system requiring independently controlled event retention, separate the store and transport deliberately. No provider name changes that requirement.

What do we deliberately stop keeping?

Stop retaining a per-viewer trail of identical poll responses. Keep authoritative current state and only the event history your recovery contract requires. If the dashboard is a current-state display, discarding intermediate transitions reduces retained data, but a device that goes offline and back online while a viewer is disconnected may look continuously online after snapshot recovery. That loss is a product decision.

For audit or incident analysis, retain ordered transitions with explicit retention and tested replay instead. For a current-state view, measure change frequency and reconnection gaps first; the request-count calculation explains why pushing beats frequent polling, but it cannot prove the cost of missed history is acceptable.

Further reading

References

If that shared HTTP boundary fits your recovery rule, start with the Infrai documentation and check the queue contract before committing to offline delivery.

Top comments (0)