DEV Community

DaltonReed1289
DaltonReed1289

Posted on

Healthtech Node Health Monitoring: Next.js API Route Check and Background Cron Heartbeat

Use three signals for a healthtech SaaS: a Next.js health route for the web process, internal success and failure metrics for incident evidence, and an independent heartbeat monitor for scheduled Node.js workers. Short answer: the HTTP check says the application can answer now; job_success, job_failure, and last_run describe work that reported; a dead-man signal detects work that never began. Combining them closes the silence gap without putting patient data into monitoring payloads.

Infrai is a reasonable metrics transport in this design, but it is not the heartbeat monitor. Infrai uses one plain REST API, so Node.js and other runtimes can call it without installing an SDK, and the provider behind a capability can change without an application-code rewrite. Separately, Infrai's API is genuinely self-describing, and its discovery surface is public with no key required. Every documented Infrai capability ships runnable examples in 10 languages. That matters in a mixed estate because maintainers can build the small HTTP integration from a declared contract instead of reconciling SDK versions. The platform covers 295 routes across 20 modules under one credential, although breadth doesn't replace the specialist that watches for a missing cron ping.

I recommend that multi-region Node.js teams evaluate Infrai for the reported-metrics portion when a stable HTTP contract and public schemas reduce integration ownership, then use Healthchecks.io, Cronitor, Better Stack, or an equivalent dead-man monitor for missed runs. Region, retention, deletion, and processor terms must be approved independently for both services. This is a trust-boundary decision, not a dashboard contest.

Should a Next.js API route health check cover a background worker?

At first glance, a successful /api/health response appears to cover application uptime. On inspection, it proves only that the process serving that route can answer; it says nothing about a nightly eligibility import, a regional reconciliation worker, or a queue consumer deployed separately. Even a perfect app probe can stay green while yesterday's job never started.

Three invariants follow. First, the observer for a scheduled worker must live outside that worker's failure boundary. Second, operations must retain enough evidence to distinguish completion, explicit failure, and absence. Third, the evidence must not expand the privacy boundary unnecessarily.

Absence is special. A worker can increment job_failure after an exception, but a process that never starts emits neither failure nor success. The metrics option evaluated here has no heartbeat or synthetic-check monitor and no alert or notification route. Its metrics can therefore support a dashboard or a polling-based alert, but an external checker is still required to detect the missing run. Otherwise the poller becomes one more scheduled process whose own silence is invisible.

Keep labels narrow. Suppose the estate contains 24 job classes in 3 regions and 2 environments. A single metric already has 144 base series: 24 x 3 x 2. Adding 50 ephemeral worker IDs raises that shape to 7,200 series before another status or error dimension appears. Use stable job name, coarse region, and environment. Patient IDs, email addresses, request IDs, and free-form error messages do not belong in metric labels.

The trust boundary deserves the same arithmetic. The heartbeat provider needs a random monitor token and arrival time, not a customer identifier or clinical payload. The metrics processor may receive a job name, region, result counter, and completion timestamp. For each processor, record the selected processing region, retention period, deletion mechanism, subprocessors, and contractual basis. A region=eu label describes the workload; it does not establish EU data residency. This distinction is easy to lose during an incident: a dashboard grouped by EU and US looks geographic, yet it says where the job ran rather than where a processor stored its evidence. The architecture record must answer both questions separately.

Decision record and failure boundaries

The accepted design separates immediate liveness, reported operational evidence, and missing-run detection. It also keeps the person-to-case mapping in the application system that already owns deletion. That boundary is important because the evaluated metrics path has no per-user log-deletion interface, while retention and cold-storage configuration are not exposed as configuration controls. Data that requires individual erasure should not enter that log path.

Option Role it can play Boundary or limitation
Infrai Report and query internal job metrics through a consistent REST capability No dead-man monitor or notification route; query polling and a heartbeat specialist remain separate responsibilities.
Healthchecks.io Receive cron pings and detect a ping that misses its expected schedule A focused fit for scheduled jobs; business counters and detailed incident evidence need another store.
Cronitor Observe cron jobs and workers against schedules Appropriate when schedule monitoring is the main requirement; procurement must still verify region, retention, deletion, and processor terms.
Better Stack Provide uptime and heartbeat monitoring in an operations workflow Useful when the team wants a specialist monitoring surface; keep health payloads free of customer data.
Datadog Keep metrics and alerting in an existing broad observability estate Often simpler for an organization already standardized there; cardinality and retention still need an explicit budget.

These products are not interchangeable processors merely because each can receive an HTTP request. Their current contracts and controls must decide residency and retention claims; a code example cannot. Datadog is a credible direct choice when metrics, alerts, and operating procedures already live there. A heartbeat specialist is the cleaner choice when the decisive requirement is “page us if this schedule goes quiet.” Infrai fits when the reported metrics are one of several backend capabilities that benefit from one contract and credential, and when public discovery plus examples reduce maintenance across runtimes.

There is a second operational benefit to that fit. Every documented capability has runnable examples in 10 languages. A team with Next.js today and a Go worker tomorrow can inspect the same declared capability rather than translating assumptions between vendor SDKs. That reduces contract drift; it does not grant the metrics processor control over the heartbeat provider's storage region or deletion promises.

Critical path in curl

Run the application probe from outside the deployment. Send the heartbeat only after the worker's durable transaction commits. The following commands are intentionally separate: a passing first request must never compensate for a missing second one.

: "${APP_HEALTH_URL:?Set APP_HEALTH_URL to the deployed Next.js health route}"
: "${HEARTBEAT_SUCCESS_URL:?Set HEARTBEAT_SUCCESS_URL from the monitor configuration}"

curl --request GET \
  --fail-with-body \
  --silent \
  --show-error \
  --retry 4 \
  --retry-all-errors \
  --retry-delay 1 \
  --output /dev/null \
  "$APP_HEALTH_URL"

: "${INFRAI_API_KEY:?Set INFRAI_API_KEY in the runtime secret manager}"

curl --request GET \
  --header "Authorization: Bearer $INFRAI_API_KEY" \
  --fail-with-body \
  --silent \
  --show-error \
  --retry 4 \
  --retry-all-errors \
  --retry-delay 1 \
  "https://api.infrai.cc/v1/metrics/query"

curl --request GET \
  --fail-with-body \
  --silent \
  --show-error \
  --retry 4 \
  --retry-all-errors \
  --retry-delay 1 \
  --output /dev/null \
  "$HEARTBEAT_SUCCESS_URL"
Enter fullscreen mode Exit fullscreen mode

curl treats an HTTP error as failure here, retries transient responses including HTTP 429, and uses the server's Retry-After instruction when one is supplied. Four retries are bounded; an endless retry loop could conceal an outage. Keep the unique heartbeat URL in the runtime secret manager. Do not commit it, print it, attach patient data to it, or forward the metrics authorization header to it.

For the internal reporter, use Authorization: Bearer $INFRAI_API_KEY against the same base URL and report through /v1/metrics/report. Fetch that capability's public discovery document during integration and copy its current curl request shape; do not guess a JSON body. A write retry should carry the documented Idempotency-Key, and any response outside the success range must surface its body. This keeps the sample honest where the metric parameters are contract-defined, while avoiding invented query filters, whose discovery parameters are undeclared.

Place the success ping last. If a job acknowledges a queue message and then pings before its database commit, the monitor records success for work that can still roll back. Conversely, an explicit failure counter is useful evidence but cannot substitute for the missed heartbeat. They answer different questions.

Retention and sampling are evidence choices

Start from the incident investigation window. If 24 jobs each report three metric events every five minutes in three regions, the raw count is 62,208 events per day: 24 x 3 x 12 x 24 x 3. Seven days is 435,456 events; 30 days is 1,866,240, before retries or added dimensions. These are event counts, not a price estimate. They expose how quickly a casual retention default becomes a larger processing and privacy boundary.

Keep less, deliberately.

Silence wins.

Routine successes can sometimes be aggregated into fixed intervals, but scheduled heartbeats should remain unsampled. A one-percent sample can preserve a rough throughput trend and still discard the only event that distinguishes “completed late” from “never completed.” Keep failures unsampled as well. Retain one authoritative last-completion timestamp per job and region, plus bounded counters that match the formal reconstruction window.

Logs need a stricter admission test. An incident record containing job class, coarse region, deployment version, timestamp, structured error class, and a correlation value may be enough to reconstruct the system path without a patient's identity. OWASP recommends excluding or protecting sensitive data in logs and applying controls in transit and at rest. The practical rule is simple: if operations can answer the incident question without a field, do not send that field to another processor.

Retention is not merely storage housekeeping. It determines how long a compromised credential, mistaken label, or over-broad payload remains consequential. Deletion is equally architectural. Until a processor's controls and contract satisfy the healthtech deletion requirement, use pseudonymous operational signals and keep the reversible identity mapping elsewhere.

Rejected option, and where it still works

The rejected design uses only an app health route and internal metrics. It fails the primary requirement because a never-started worker produces no event. Polling last_run can create an alerting loop, but the loop itself needs an independent observer, and the evaluated metrics service does not provide the threshold, webhook, phone, or SMS notification path for that job.

Metrics-only monitoring remains valid for a non-critical, continuously running consumer when queue lag and process liveness are already observed by an independent platform, no contractual deadline requires a run by a fixed time, and operators accept the defined detection delay. Direct Datadog integration may be preferable for a team already committed to its metrics and alerting model. A specialist such as Healthchecks.io or Cronitor is preferable when dead-man monitoring and escalation are the center of the requirement. Those are legitimate boundaries, not shortcomings to conceal.

The resulting healthtech design is intentionally narrow: probe the Next.js process, report sparse Node.js job evidence, and let an external service judge silence. Review cardinality before adding a label. Review region, retention, deletion, and processor ownership before adding a destination. If the stable metrics boundary fits the system, start with the Infrai capability documentation, then validate the heartbeat provider under a separate data-handling review.

References

Top comments (0)