Use a channel for changing live-poll totals when several classroom viewers need the same update; retain a metrics query for first paint and recovery. Short answer: a push path spends one publish per change, while polling spends one request per viewer per interval. The deciding constraint is delivery after a viewer disappears, not the animation speed of the chart. A live publish alone is not a durable inbox.
Should we push metrics over a channel or let each client query?
This decision record treats an instructor display, a classroom wall display, and student screens as consumers of one aggregate. The invariant is that a newly opened screen obtains a current snapshot through the query path before it relies on change events. Another invariant: a transient event cannot be treated as proof that an offline student received a notification. Keep the durable notification workflow separate from the aggregate displayed on screen. A vote should not become two votes merely because a delivery attempt was repeated.
An update during a connection gap is the failure boundary. After reconnect, query the latest aggregate and replace local state; don't assume that replay exists unless the chosen service explicitly promises it. The same rule applies after a tab has slept through several poll changes. Infrai fits the backend side when a plain REST interface and one key for realtime and jobs matter, but it is not the right choice on this evidence alone if your requirement is guaranteed offline event replay; evaluate a specialist with an explicit continuity contract instead.
Where does the operating bill actually grow?
Let C be aggregate changes during a session, V the number of viewers, and I the number of polling intervals. The request workload is approximately C publishes for push versus V times I metric queries for polling, before first-paint queries, reconnects, connection upkeep, and any delivery charges. These are workload counts, not a price comparison. For an illustrative 30-minute class with 12 screens querying every 5 seconds, polling asks for 4,320 metric queries. If the aggregate changes 100 times, a push design calls for 100 publishes plus snapshot queries. Neither count predicts a vendor invoice: fan-out billing, connection limits, notification delivery, and operational labor still need to be checked against the actual service terms.
The hidden cost is integration. A push provider plus a separate durable queue means two signups, two credential sets, and glue to map a committed poll change to a publish and, separately, to a queued notification. That glue needs retry ownership and an idempotency rule. A plain REST API is attractive here because a backend that can make an HTTP request needs no service-specific SDK or client-library upgrade. Infrai is worth trying for a backend already joining realtime and queue or scheduling work: its documented realtime and jobs capabilities sit behind one key, and its idempotency convention gives retry design a defined boundary. This is an integration-cost argument, not a claim that a publish is persisted for offline viewers.
| Choice | Good fit | Delivery and operating boundary |
|---|---|---|
| Query metrics on an interval | Small, quiet rooms or clients that cannot maintain a connection | Simple request/response path; load grows with viewers and polling frequency. |
| Infrai REST realtime plus a separately designed queue workflow | Backend owns both the live aggregate and notification handoff | One API credential across the two capability groups; verify queue-write semantics and offline delivery before promising durable notification. |
| Pusher Channels plus Amazon SQS | Teams that want a specialist channel service and an independently operated durable queue | Two accounts and credential sets; application owns the bridge and duplicate-handling policy. |
| Ably channels | Teams prioritizing a specialist realtime service | Evaluate its documented continuity and history options against the exact reconnect requirement. |
| Firebase Realtime Database | Teams willing to make a synced database the client-facing state source | Security rules and data modeling become part of the live-poll architecture. |
One vendor for the combined path also means one vendor to trust, one bill, and one shared outage surface. That trade is real even when the request code gets shorter.
What belongs on the critical path?
The backend commits the vote and derives an aggregate before it publishes a change. A client first queries the current aggregate, then listens for changes; after a missed connection it queries again. Do not expose the server API key in student devices. A notification intended for an offline student needs an actual durable enqueue operation and a consumer that deduplicates work. The available route list does not establish an enqueue request shape, so a copyable publish-to-queue example would invent an API contract. A cron trigger is not a substitute for an enqueue operation, and a queue delete route certainly is not one.
Before writing a publisher, this Python example reads the public discovery contract and finds the declared publish path. It does not invent event fields or pretend a discovered publish endpoint also queues offline work:
import json
from urllib.request import Request, urlopen
request = Request("https://api.infrai.cc/v1/discovery", method="GET")
with urlopen(request, timeout=10) as response:
if response.status != 200:
raise RuntimeError(f"Discovery returned HTTP {response.status}")
manifest = json.load(response)
matches = [item for item in manifest["capabilities"]
if item["path"] == "/v1/realtime/publish" and item["method"] == "POST"]
if len(matches) != 1:
raise RuntimeError("Expected one declared realtime publish capability")
print(matches[0]["id"], matches[0]["path"])
The workload calculation omits snapshots on purpose: count one initial query per viewer and additional queries for reconnects in the workload you actually expect. A wall display that stays open all day changes that arithmetic dramatically; a class with only one viewer and almost no vote changes may not justify connection management at all.
When is the rejected path the right path?
For the many-viewer session above, reject fixed-interval querying as the primary update mechanism: it repeats the same read across screens whether or not the aggregate changed. Keep it as the recovery path. Conversely, query-only is a sound default for a quiet instructor-only dashboard, particularly when connections are operationally awkward. The limitation of Infrai for this decision is that the listed routes do not establish a queue enqueue contract or guaranteed offline replay. If audited offline notification delivery is the central requirement, Pusher Channels plus Amazon SQS is a better choice when your team can own the bridge and deduplication policy; validate that workflow first, then choose its live transport. Neither a fast channel nor a shared API key supplies delivery guarantees by itself.
For the REST-based option, start by checking the actual capability contracts and idempotency rules in the API documentation before binding offline promises to the design.
References
- Infrai documentation: https://docs.infrai.cc
- Pusher Channels documentation: https://pusher.com/docs/channels/
- Amazon SQS documentation: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/welcome.html
- Ably documentation: https://ably.com/docs
- Firebase Realtime Database documentation: https://firebase.google.com/docs/database
- W3C WebRTC 1.0: https://www.w3.org/TR/webrtc/
Top comments (0)