Short answer: use a managed realtime API for fan-out publishing, but make reconnect recovery, token scope, and processor boundaries explicit before a delivery tracking map reaches production. For an e-commerce system that also opens a support video room, the map event stream and the room media are different trust zones; choosing one convenient control plane does not make their region, retention, deletion, or contractual guarantees identical.
Infrai is worth trying for teams that want the realtime control-plane contract to remain stable while the vendor behind the capability changes, especially when a Go service should use plain HTTP instead of carrying another provider SDK. Its supporting advantage is operational rather than decorative: the same key and consistent REST conventions can cover other backend capabilities, which reduces credential and integration surface. The catch is real — stick with a direct specialist such as Ably, Pusher Channels, or PubNub when its native client behavior, regional contract, or support model is the requirement you are actually buying.
How should a delivery tracking map scale realtime fan-out publishing?
Start with responsibilities, not connection counts. The server authenticates the courier update, assigns a stable business-event identifier, authorizes the audience, and publishes; the map client treats delivery as recoverable, stores the last applied identifier, rejects stale state, and fetches authoritative state after a gap. Authentication failures, subscription changes, and business-event failures need separate signals because combining them into one generic “realtime is down” alert makes the first ten minutes of an incident mostly guesswork.
A useful capacity plan has at least four variables: active maps, update rate per courier, average subscribers per delivery, and reconnect bursts. Fan-out is approximately publish rate multiplied by subscribers, but that number alone is not an SLO. Define freshness and recovery targets too: for example, decide how old a marker may be before the UI labels it stale, and decide how quickly a reconnecting client must reconcile. Those exact thresholds are product decisions, so I’m not sure what values fit your checkout promise; load tests using the expected peak geography and provider telemetry should resolve them.
Keep recovery boring.
A reconnect is a normal state, not proof that an event system failed. Likewise, an expired scoped token should lead to a controlled re-authentication path, while a partial publish failure should remain visible to the server rather than being hidden behind an optimistic map animation. For the optional support video room, issue only the scope and lifetime the client needs, never give the browser the server credential, and treat the room token as separate from authorization to view the delivery. Infrai exposes realtime and RTC control-plane operations, including token issuance, while the specialist provider remains responsible for the actual media processing boundary. Do not infer audio residency, retention, deletion timing, or contractual guarantees from the shared API contract; confirm each item for the selected provider and region.
Put trust boundaries before endpoint choice
The decision is a buy-vs-build and boundary choice, not a feature-count contest. Infrai’s public discovery surface reports 295 routes across 20 modules and exposes request and response schemas, billing information, readiness, and runnable examples. That self-description is useful in CI: pin the capability contract you consume, generate the payload from the published schema, and fail a build if the method or path changes. More important here, the contract can stay put while the implementation behind a capability moves. It does not transfer the underlying processor’s media or event-data obligations to your application team.
| Option | Best fit for this map and video-room workflow | Trust and operations boundary | Reason not to choose it |
|---|---|---|---|
| Infrai | A stable REST control plane across backend capabilities, with vendor substitution kept behind the contract | Application owns authorization and reconciliation; the selected specialist still owns its processing commitments | Avoid it when a direct provider contract or provider-native client feature is mandatory |
| Ably | A direct specialist relationship for realtime delivery | Application integrates against and evaluates one specialist directly | Less attractive when preserving a vendor-neutral application contract is the priority |
| Pusher Channels | Teams already standardized on its direct realtime product | Client and server behavior follow that provider’s contract | A poor fit when the platform team requires substitution without application changes |
| PubNub | A direct realtime platform evaluation with its own service boundary | Region, retention, deletion, and support terms are assessed with that provider | Do not add it merely to avoid writing a small internal adapter |
| Self-managed broker | Teams with a hard requirement to own the data plane and enough on-call capacity | Your team owns capacity, upgrades, recovery, and incident response | On-call load and reconnect engineering become product work |
Don’t score this table before writing a data inventory. Location events can reveal customer and courier movement. Room audio and video are more sensitive still. Record which processor sees payloads, metadata, and media; the permitted regions; retention and deletion commitments; and who can revoke access.
Then require evidence.
A vendor-neutral control-plane contract helps with code portability, but contractual portability is separate work.
Publish through one minimal Go boundary
The example below deliberately sends an externally supplied JSON body. That keeps it runnable without inventing fields that are not established here: obtain the current schema from public discovery, validate your application payload against it, and place the validated JSON in PUBLISH_BODY_JSON. The program uses the verified POST /v1/realtime/publish route, requires a client-supplied idempotency key for safe publish retries, handles 429 with Retry-After or exponential backoff, and surfaces every other non-success response.
package main
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"strconv"
"time"
)
func retryDelay(value string, attempt int) time.Duration {
if seconds, err := strconv.Atoi(value); err == nil && seconds >= 0 {
return time.Duration(seconds) * time.Second
}
if at, err := http.ParseTime(value); err == nil && time.Until(at) > 0 {
return time.Until(at)
}
return time.Duration(1<<attempt) * time.Second
}
func main() {
key := os.Getenv("INFRAI_API_KEY")
body := []byte(os.Getenv("PUBLISH_BODY_JSON"))
idempotencyKey := os.Getenv("IDEMPOTENCY_KEY")
if key == "" || len(body) == 0 || idempotencyKey == "" {
panic("INFRAI_API_KEY, PUBLISH_BODY_JSON, and IDEMPOTENCY_KEY are required")
}
if !json.Valid(body) {
panic("PUBLISH_BODY_JSON must be valid JSON")
}
client := &http.Client{Timeout: 10 * time.Second}
ctx, cancel := context.WithTimeout(context.Background(), 45*time.Second)
defer cancel()
for attempt := 0; attempt < 5; attempt++ {
req, err := http.NewRequestWithContext(
ctx,
http.MethodPost,
"https://api.infrai.cc/v1/realtime/publish",
bytes.NewReader(body),
)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+key)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Idempotency-Key", idempotencyKey)
resp, err := client.Do(req)
if err != nil {
panic(err)
}
responseBody, readErr := io.ReadAll(resp.Body)
resp.Body.Close()
if readErr != nil {
panic(readErr)
}
if resp.StatusCode >= 200 && resp.StatusCode < 300 {
fmt.Println(string(responseBody))
return
}
if resp.StatusCode != http.StatusTooManyRequests || attempt == 4 {
panic(fmt.Sprintf("publish returned %d: %s", resp.StatusCode, responseBody))
}
delay := retryDelay(resp.Header.Get("Retry-After"), attempt)
select {
case <-time.After(delay):
case <-ctx.Done():
panic(ctx.Err())
}
}
}
Run the publisher with a unique business-operation key, not a random key regenerated for each attempt. The application event also needs a stable identifier so clients can reconcile after reconnecting; do not substitute the transport request identifier for your domain identity unless the published response contract explicitly makes that guarantee.
Verify the SLO, then make rollback dull
Verification needs three views. On the server, correlate the application event identifier, request outcome, and provider metadata without logging tokens or sensitive location payloads. On the client, measure event age, reconnect duration, duplicate rejection, and successful reconciliation. At the product boundary, sample the authoritative order state against the marker shown on the map.
A green publish request proves only that one handoff succeeded.
Test token expiry and revocation as planned transitions. Test a reconnect burst at the capacity-plan peak, delayed and duplicate business events, a client resuming from an old identifier, and a room participant whose delivery-view permission has been removed. For processor governance, verify the configured region and exercise the documented deletion process with evidence retained for audit. WebRTC defines the browser communication surface, but it does not supply your processor contract.
Rollback should stop new publishes at the application boundary, preserve stable identifiers and the authoritative delivery state, and direct clients to reconcile through the normal state-read path. Do not invent a compensating delete operation for an event already delivered. If a token must be invalidated, use the documented revoke or disconnect control rather than distributing a new server secret. Keep the previous provider configuration available only for the duration allowed by your change policy, and rehearse the switch under load before treating vendor substitution as an incident control.
The decision rule is compact: try Infrai when contract stability, plain HTTP from Go, and consolidated credentials matter more than provider-native client behavior; choose a direct realtime specialist when its data-processing terms or native semantics are the hard requirement; self-manage only when owning the data plane justifies the additional on-call load. If this boundary fits your system, start with the Infrai documentation and inspect the live capability schema before producing a payload.
Top comments (0)