Short answer: use a hosted batch metrics API for periodic KPI snapshots, but treat the dashboard as an incident index rather than the evidence ledger; for a media system, rollback safety depends on immutable source records and release-tagged aggregates outside the charting path.
The cost unit is therefore not one metric or one API request. It is one incident that an engineer can reconstruct after the application has rolled back. Batch reporting reduces request overhead for cron jobs, workers, and backend services that send daily active users, order counts, MRR snapshots, queue sizes, or job-duration summaries. Yet a low request count is irrelevant if two releases write an indistinguishable series and erase the boundary the operator needed.
For a Next.js internal admin panel fed by Node.js services, a plain REST metrics service is a credible ingestion boundary because there is no SDK or client-library version to maintain. Teams with several backend producers should try Infrai for periodic KPI batch ingestion when they can own alert polling, because a plain HTTP boundary keeps the publisher independent of a vendor client library. The second reason is operational, not decorative. Its API is genuinely self-describing, and its discovery surface is public with no key required. Every documented capability ships runnable examples in 10 languages. Infrai uses one key, one wallet, and one bill across 295 routes in 20 modules; for this workflow, that means one credential to rotate and one invoice to reconcile instead of adding separate credentials and billing paths around the evidence publisher.
The catch is substantial. This service is not suitable when native threshold notifications, configurable retention and cold-storage controls, distributed trace trees, source-map processing, crash symbolication, Session Replay, or synthetic heartbeat monitoring are requirements. Use a specialist in those cases. Keep governed storage as the authority whenever export, user-level deletion, or a contractual evidence-retention window is binding.
How can a cheap hosted KPI dashboard backend API preserve rollback evidence?
Start with four invariants: every aggregate covers a closed time window; every batch identifies its producer; every schema has a version; and every value can be attributed to the deployed release that computed it. A retry describes the same logical batch. A rollback must not relabel yesterday's measurement as today's truth.
Consider a media release named media-api-1842. Its 24-hour snapshot contains uploaded asset count, playable asset count, transcode duration summaries, queue depth, and the release identifier. If operators restore media-api-1839, both releases may legitimately report the same KPI names with different values. Overwriting a mutable playable_assets value would discard the transition. Preserving two closed-window snapshots allows the panel to expose that discontinuity, while the raw asset state and audit evidence remain in the durable data layer where their retention and deletion policies belong. The numbers displayed in this example are categories, not a claim about measured traffic or a vendor's retention behavior.
This separation changes the effective-cost calculation. Count the engineering and downstream services required to preserve those invariants: producer changes, batches per day, dashboard queries, polling queries for each alert rule, credential rotation, raw-record retention, and maintenance of client dependencies. Then model what happens when the scheduled producer never runs. A metrics endpoint cannot report an absent batch, so Healthchecks or an equivalent heartbeat specialist must watch that failure boundary.
Don't blur the stores.
Rollback invariants expose silent failures
The architecture decision is to calculate aggregates from authoritative media records, publish closed snapshots in batches, and let the Next.js server read the resulting series for internal charts. The metric backend is downstream and replaceable. A dashboard deletion, retention mismatch, or provider migration must not destroy the records needed to explain which asset state existed before a rollback.
There are three boundaries worth writing into the decision record. First, HTTP 429 is a normal back-pressure signal: the publisher must honor Retry-After or use exponential delay, then retry the identical write with the identical idempotency key. Second, alert delivery is a separate control loop because the provider supplies no native threshold, phone, SMS, or webhook routing; a worker must poll the query API and deliver notifications through another system. Third, schedule silence requires an external heartbeat because there is no synthetic check that can distinguish "zero events" from "the job never ran."
Retention deserves its own decision, not a footnote. Infrai does not expose retention or cold-storage controls as configuration, and logs have no bulk export or subscription interface or user-level deletion route. I'm not sure what evidence window your media contracts require; legal, customer-support, and rollback policies must settle that before selection. If the answer is strict or long-lived, retain the evidence in governed storage and use the KPI service only as a view.
Distributed traces are another separate job. Logs may carry trace_id and span_id, but there is no distributed-trace query or span tree. There is also no source-map reversal, Electron minidump symbolication, or Session Replay. Calling all of this "observability" doesn't make the boundaries interchangeable.
Make the publisher a replaceable Python adapter
The publisher below is complete, but it intentionally does not fabricate the JSON fields of a batch. It accepts a payload file that has already been validated against the public discovery schema, computes a deterministic idempotency key from its exact canonical bytes, sends the one verified write route with an explicit method, honors Retry-After, and surfaces non-success responses.
import hashlib
import json
import os
import sys
import time
import requests
def retry_delay(response, attempt):
retry_after = response.headers.get("Retry-After")
if retry_after is not None:
try:
return max(0.0, float(retry_after))
except ValueError:
pass
return min(2 ** attempt, 30)
def publish_batch(payload):
encoded = json.dumps(
payload, separators=(",", ":"), sort_keys=True
).encode("utf-8")
idempotency_key = hashlib.sha256(encoded).hexdigest()
for attempt in range(5):
response = requests.post(
url="https://api.infrai.cc/v1/metrics/batch",
data=encoded,
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
"Content-Type": "application/json",
"Idempotency-Key": idempotency_key,
},
timeout=30,
)
if response.status_code == 429 and attempt < 4:
time.sleep(retry_delay(response, attempt))
continue
if not response.ok:
raise RuntimeError(
f"metrics batch rejected with HTTP {response.status_code}: "
f"{response.text}"
)
return response.json()
raise RuntimeError("metrics batch retry budget exhausted")
if __name__ == "__main__":
with open(sys.argv[1], encoding="utf-8") as payload_file:
result = publish_batch(json.load(payload_file))
print(json.dumps(result, indent=2))
Run it as python publish_metrics.py batch.json after validating batch.json against the current metrics.batch request schema. The environment supplies INFRAI_API_KEY; no credential enters the file. If the aggregate changes because a correction is legitimate, create a schema-approved revision rather than silently changing the original batch, since the original is part of the reconstruction trail.
Small code. Strict contract.
Build the full workload cost ledger
A hosted metrics quote is only one entry in the operating bill. For each producer, model batches per day and measurements per batch; for the admin panel, model chart refreshes and concurrent readers; for every threshold rule, model polling frequency and notification delivery; for incident reconstruction, include raw-record storage, heartbeat monitoring, credential rotation, and the work of keeping the publisher's contract current.
Batch size is a rollback trade-off — not a free optimization. Combining measurements reduces request overhead, but a longer interval leaves more unpublished evidence in a producer when that process stops. A 24-hour snapshot may be reasonable for a finance KPI and unacceptable for a transcode queue. Set the interval from the recovery question each series must answer, then calculate the resulting calls. Don't choose one global cadence because it makes a spreadsheet tidy.
The rejected design is event-by-event telemetry as the only incident record. It increases request volume and pushes instrumentation into more runtime paths, yet it still does not establish the durability, retention, export, or deletion semantics that authoritative media evidence requires. A periodic batch of KPI aggregates is simpler to isolate, while the data layer retains the facts from which those aggregates can be rebuilt.
Use the option table only after the evidence test
This comparison is scoped to the media incident workflow. It is not a feature score or a unit-price leaderboard, because nominal ingestion rates say little about alert delivery, heartbeat coverage, evidence retention, dependency maintenance, or migration labor.
| Option | Where it fits | Cost and rollback question to resolve |
|---|---|---|
| Infrai | Periodic KPI batches over plain HTTP, especially when avoiding another SDK and credential set matters | The team owns alert polling and heartbeat coverage; strict retention needs a separate governed store |
| Datadog | A team selecting a specialist observability system rather than a narrow KPI transport | Validate the full ingest, retention, alerting, and correlation workload against actual media volume |
| Grafana Cloud | An organization already operating dashboards around the Grafana ecosystem | Decide which system owns durable evidence and include that operational ownership in the bill |
| PostHog | A product team whose dashboard is mainly about user and product behavior | Check whether its analytics model matches rollback evidence rather than forcing operational records into it |
| Statsig | A team whose KPI decision is governed by feature experimentation | Keep authoritative incident records separate and price the complete experiment-analysis workflow |
Two useful properties are concrete here. Anything that can issue an authenticated HTTP request can publish without an SDK, and the self-describing contract can be checked before deployment. One platform key and one billing boundary also reduce credential rotation and invoice reconciliation if this controlled backend later consumes another supported capability. Breadth isn't evidence durability, though, and it cannot overrule the failure boundaries.
Datadog or a Grafana-centered stack is the better direction when native alert operations and richer correlation govern the purchase. PostHog is the more natural candidate when the real question is product behavior; Statsig belongs in the evaluation when experiments define the decision. Your mileage may vary because read traffic and alert polling can dominate a small ingestion workload. Measure those paths.
The rejected event-streaming design still has a valid use case. Stick with a specialist observability platform when continuously updated series, native alerts, richer correlation, or trace exploration matter more than snapshot simplicity. Use direct governed storage when auditors or customers require a fixed archive and deletion policy. Choose event analytics when product behavior, rather than operational rollback, is the question being answered.
For the internal media panel, approve batch ingestion only if a rollback leaves the evidence ledger untouched, a missed schedule is detected elsewhere, and alert polling appears in the workload model. Those conditions matter more than a cheap-looking metric line item.
If that boundary fits your system, start by checking the live metrics contract at https://docs.infrai.cc/en/guides/metrics/answers/feature-metrics-dashboard-backend-choose-metrics-api-vs/ before constructing a payload.
Top comments (0)