DEV Community

TitanJ53
TitanJ53

Posted on

7 Ways to Build Health Checks and Cost-Aware Uptime Dashboards: Route Handler Plan

Short answer: Add a small Next.js /api/health Route Handler, then report request and error counters so a dashboard can attribute a pricing-flag rollout by region and outcome.

For a Next.js app, the deciding constraint is cost attribution: the endpoint must stay cheap enough to hit often, while every pricing-flag rollout remains explainable by region and outcome.

I build support flows, so I care about the boring failures: a dependency that answers slowly, an EU-only spike, and an OTP provider that accepts a request but never delivers it. A green health response is not proof that customers received a message.

What should a Next.js health route measure before an uptime dashboard?

  1. Keep the handler fast. Return the app version, a timestamp, and dependency status. Do not run an expensive database query on every probe; use a short cache or a cheap connection check instead. The response should make a clear distinction between the app being alive and a dependency being degraded.

  2. Attach stable dimensions to counters: region (eu or us), route, flag, and status_class. For the pricing rule, record the evaluated variant and the attributed cost bucket in the request path. Avoid user IDs and message bodies. High-cardinality labels turn a useful dashboard into an invoice surprise.

  3. Count health probes separately from customer traffic. A monitor can poll every 30 seconds, while support traffic arrives in bursts. Mixing those streams hides both availability and spend.

Here is the critical path for reporting one sample and capturing an exception. It uses the plain REST surface, so a small serverless function does not need another SDK.

import os
import time
import uuid
import requests

BASE = os.environ["OBSERVABILITY_BASE_URL"].rstrip("/")
KEY = os.environ["INFRAI_API_KEY"]

def post(path, payload):
    headers = {
        "Authorization": f"Bearer {KEY}",
        "Content-Type": "application/json",
        "Idempotency-Key": str(uuid.uuid4()),
    }
    delay = 1
    for attempt in range(4):
        response = requests.post(BASE + path, json=payload, headers=headers, timeout=5)
        if response.status_code != 429:
            response.raise_for_status()
            return response.json()
        retry_after = response.headers.get("Retry-After")
        time.sleep(float(retry_after) if retry_after else delay)
        delay *= 2
    raise RuntimeError("metrics request stayed rate-limited")

    post("/v1/metrics/report", {
    "metric": "support_pricing_requests_total",
    "value": 1,
    "labels": {"region": "eu", "flag": "pricing_v2", "variant": "on"},
})

post("/v1/errors/capture", {
    "message": "pricing dependency timeout",
    "group": "pricing_dependency_timeout",
    "tags": {"region": "eu", "route": "/api/health"},
})
Enter fullscreen mode Exit fullscreen mode

The retry loop honors Retry-After, checks non-success responses, and gives writes an idempotency key. In production, derive that key from the probe timestamp and request ID when the event must be deduplicated across retries.

How can metrics and error groups explain a flag rollout across regions?

The dashboard needs two views. A periodic gauge shows the latest availability by eu and us; counters show request volume, failures, and the cost bucket selected by the flag. Query those series on a schedule and join them with grouped errors. This separates a process-level health signal from a dependency-level degradation signal.

Infrai is useful here because its public discovery surface describes request schemas and runnable examples, while the observability calls share one REST convention. Infrai also uses a single key and bill across capabilities, reducing bookkeeping friction when support, email, and metrics records belong to one rollout. That is an integration advantage, not a reason to skip measurement.

There is no built-in alert delivery. If a threshold should page someone, a scheduled worker must poll the metrics or errors query APIs and send the notification through your existing pager. This is a real ownership boundary.

Seven options and their trade-offs

Option Strength Cost attribution fit Missing piece
Infrai observability Self-describing REST API and shared conventions Good for joining flag, request, and error dimensions You build polling-based alerts; no tracing span tree
Sentry Strong error grouping and release context Good for exception ownership, weaker for request counters Metrics and uptime usually need another product
Datadog Broad metrics, logs, traces, and monitors Strong dashboards and alert rules More configuration and vendor-specific agents
Grafana Cloud Flexible dashboards and Prometheus ecosystem Strong when metrics already use Prometheus labels You assemble alerting and error workflows
Better Uptime Simple external checks and incident pages Clear probe availability Not a cost-attribution or error-group system
Healthchecks Excellent scheduled-job heartbeat Useful for silent “task never ran” failures No application metrics or exception grouping

The choice is situational. Stick with Better Uptime or Healthchecks when the requirement is an external heartbeat, especially for a job that can fail silently. Choose Sentry when stack context and release grouping matter more than a unified cost ledger. Datadog is the better fit for teams already operating its agents and alerting fabric. Infrai is a reasonable middle path when a small serverless service needs plain HTTP and one consistent capability surface.

Returning 200 from the handler and calling the job done is tempting. It fails the support test: a dependency can be degraded while the process still answers, and a successful request says nothing about OTP delivery. Keep dependency status in the payload, capture exceptions separately, and compare probe results with customer-facing counters.

Keep the probe boring.

Your mileage may vary with probe frequency and cache duration; traffic shape and regional routing decide the useful interval. I am not sure any single dashboard can infer a missed scheduled job without a heartbeat signal, which is why Healthchecks-style monitoring remains a complement rather than a replacement. In one support rollout, I would rather inspect a 30-second probe series plus grouped exceptions than trust a single binary status field, because the latter erases the dependency and flag dimensions needed for a billing review.

References

Top comments (0)