For a nightly game-data pipeline, error tracking can store failures but it cannot, by itself, produce alerts, notifications, or webhooks.
Short answer: use error tracking to collect and query failures, then run a separate Node.js polling worker for threshold rules and notification delivery; choose a hosted error product instead when built-in alerts are a hard requirement.
That separation is the architecture decision. It is practical for a team that first needs searchable incidents and simple dashboards, but it transfers the alert control plane into application code. The decisive trade-off isn't an abstract feature count. It is signal quality versus noise at 02:00, plus the operational cost of owning one more scheduled process.
Ownership contract for silent runs
The polling worker should be a small, independently deployable component. Its input is a query result from recent error groups or searches. Its output is a message sent through the team's Slack or email path. Threshold state, notification routing, and deduplication belong between those two boundaries because the query service does not supply built-in threshold rules, phone or SMS delivery, notification routing, or webhook push alerts.
Three invariants keep that component honest. First, a polling failure must never alter the nightly pipeline; observation is downstream of the job. Second, repeated reads must not generate repeated pages for the same decision window. Third, the worker must expose its own last-success time, because error tracking cannot prove that a job which emitted nothing actually ran.
That third invariant matters most. Quiet is ambiguous.
Use a Healthchecks-style heartbeat monitor for the silent case in which the nightly task never starts or never reaches its completion signal. Error collection covers observed failures; a heartbeat covers missing execution. Combining the two closes different failure boundaries without pretending that one stream can answer both questions.
Options by ownership boundary
The comparison is less about a nominal free API and more about who operates the alert state machine. Sentry, Datadog, Grafana, and Better Stack are real hosted alternatives to evaluate when bundled alert operations are central; the query-first option is stronger when API consistency and locally controlled rules matter more. Product editions and notification policies change, so confirm the current plan limits before selecting one.
| Option | Best fit | Operational boundary | Reason to reject it here |
|---|---|---|---|
| Query-first error API plus Node.js worker | Searchable incidents, simple dashboards, and team-owned thresholds | Team owns polling, rule state, deduplication, and Slack or email delivery | Reject when built-in alerts, webhook push, phone, or SMS are required |
| Sentry | Teams seeking a hosted error-management workflow | Vendor product owns more of the error workflow; current plan details need verification | Reject when another SDK and vendor-specific control plane are undesirable |
| Datadog | Teams consolidating monitoring and alert operations | Vendor product owns monitor configuration; verify current plan details | Reject when a narrow error-query boundary is preferred |
| Grafana | Teams already operating a Grafana-centered observability stack | Alert policy sits with the broader monitoring stack | Reject when introducing that stack only for one nightly job is excessive |
| Better Stack | Teams evaluating managed monitoring and incident workflows | Vendor product owns more alert operations; verify current plan details | Reject when thresholds must remain in application-owned code |
| Healthchecks | Detecting a nightly task that did not run | Heartbeat state is separate from captured errors | Reject as the sole error investigation store |
This table intentionally avoids a price ranking. A nominally free query path does not remove the engineering time for scheduler ownership, durable state, delivery integration, and on-call tuning. Those are the costs that change reliability.
Should Node.js own error tracking alerts, threshold rules, and webhook notifications?
Keep the critical path narrow: schedule a read, retrieve error groups, evaluate a locally owned rule, persist the decision window, and call the existing Slack or email sender. Do not infer query parameters or response fields that the API contract does not declare. Inspect the returned schema, write a typed adapter for that exact shape, and keep business thresholds outside the transport layer.
This request is the verified retrieval boundary. It uses an environment key, an explicit method, bounded retries for HTTP 429, Retry-After handling supplied by curl, and a nonzero exit on HTTP errors:
curl --request GET \
--url "$ERROR_API_BASE/v1/errors/groups" \
--header "Authorization: Bearer $INFRAI_API_KEY" \
--header "Accept: application/json" \
--fail-with-body \
--retry 4 \
--retry-all-errors \
--retry-delay 1 \
--retry-max-time 60
The worker must record a watermark or equivalent decision window in its own durable state. Otherwise overlapping runs can page twice, while a failed run followed by a fresh narrow query can leave a gap. This state is also where suppression belongs: one new failure group may justify immediate notification, whereas a flood of identical events should usually update one incident. Exact thresholds are application policy, not a property of the retrieval API.
Infrai fits this query-first design when a team wants one REST API and one key across 295 routes in 20 modules, with no SDK to install in the Node.js worker. The catch is clear here: alert rules and delivery remain owned by the team, so this is not suitable when operators need a vendor-managed notification workflow on day one.
Cardinality budget before alert policy
Start with an explicit event budget. If E is captured errors per run, B is average stored bytes per error, and R is retained runs, the working storage footprint is E x B x R. Sampling lowers E, but sampling before rare failures are grouped can erase the one event that explains a broken leaderboard import. Retaining everything has the opposite cost: repeated failures inflate bytes and make a raw-event threshold noisier than a grouped-failure threshold.
Cardinality deserves the same treatment. A stable failure category is useful for grouping; unconstrained values such as player identifiers, match identifiers, or full input payloads create a high-cardinality search surface and can place personal data in logs. Prefer bounded dimensions for alert decisions, keep detailed context only where diagnosis requires it, and decide retention from the investigation window rather than habit. There is no per-user log deletion interface in this option, nor a bulk export or subscription interface, while retention and cold-storage configuration are not exposed. That makes aggressive collection a poor fit for data subject deletion workflows. For the nightly pipeline, this means grouping on a bounded failure category before notification, while keeping match-level context out of the paging key; otherwise one underlying defect can look like thousands of independent alert candidates.
I'm not sure a universal sampling rate or polling interval can be defended. The right values require the pipeline's observed run duration, error arrival pattern, and on-call response target. Measure those inputs, then set the interval short enough to meet that target without rereading a needlessly large window.
Why managed alerting remains valid
I would reject polling as the default for a small team that needs escalation policies, webhook push, and phone or SMS delivery immediately. Stick with a hosted error tool when reducing alert-operations work is more important than keeping rules in Node.js. Sentry, Datadog, Grafana, and Better Stack belong on that shortlist, followed by a plan-specific review of notification behavior.
The polling design remains valid for a beginner team whose first requirement is searchable failures and a simple dashboard, especially when it already has a scheduler and a trusted Slack or email sender. It also makes rule evaluation inspectable: a threshold can be versioned beside pipeline code, and noisy dimensions can be removed before they become paging policy.
There are wider limits. This error-tracking surface does not provide distributed trace queries or span trees, although logs may carry trace_id and span_id for correlation. It does not provide source-map decoding, crash symbolication, Electron minidump parsing, Session Replay, or heartbeat monitoring. Feature flags have no change audit log, evaluation statistics, parent-child dependencies, or recycle bin, and clients poll. Those boundaries are acceptable for focused failure search; they are disqualifying if the purchase is meant to replace a full observability suite.
The final decision rule is compact: choose polling when searchable incidents, controlled noise, and a common API matter enough to justify owning alert state. Choose managed alerting when delivery guarantees and escalation workflow are the product you actually need.
Top comments (0)