Baseline conditions and seasonality

Lesson 5 · Extension track · the feature built for lesson 2's problem, which CCAP does not use

Extension track

Lessons 5 and 6 cover New Relic capabilities that exist and that Shippo alerting mostly leaves on the shelf. Knowing them changes what you reach for, even when the answer stays "not this time".

What a baseline condition is

A STATIC condition compares each data point to a number you chose. A BASELINE condition compares each data point to a number New Relic predicted from the signal's own history, and the threshold you set is a count of standard deviations from that prediction.

That single change moves the tuning problem. You stop asking "what error rate is too high for this carrier?" and start asking "how unusual must this be before I care?"

How much Shippo uses it

MeasureCountSource
Live conditions of type BASELINE56 of 1000 sampledNew Relic API
Live conditions of type STATIC944 of 1000 sampledNew Relic API
Terraform blocks with type = "baseline"10shippo-tf-services

Two readings. First, baseline is a 5.6% minority. Second, only 10 Terraform blocks account for 56 live baseline conditions, so most of them were made in the UI, the same click-ops gap measured in lesson 4.

baseline_direction

A prediction has two sides. This argument says which side you care about.

ValueFires whenShippo call sites
upper_onlyThe signal rises unusually far above prediction.8
upper_and_lowerThe signal departs prediction in either direction.2 (services/it-alerts/alerts.tf:119, services/login/monitoring.tf:76)
lower_onlyThe signal falls unusually far below prediction.0

The pattern is legible. Error signals use upper_only: too many errors is bad, unusually few is a gift. Signals where both directions are suspicious, such as login volume and IT alert flow, use upper_and_lower. Nothing at Shippo uses lower_only, because a drop in successes is normally caught with a static BELOW threshold instead, which is easier to reason about.

Read this from Terraform, not from the MCP tool

The get_nrql_alert_conditions tool returns description, enabled, expiration, id, name, nrql, policyId, runbookUrl, signal, terms, type, valueFunction, violationTimeLimitSeconds. It does not return baselineDirection or signalSeasonality. Their absence in a tool result means the tool did not fetch them, not that they are unset. Check Terraform, or the New Relic UI, before concluding anything about these two fields.

signal_seasonality, the answer to lesson 2

Lesson 2 established that Shippo carrier traffic swings 1.84× between its 09:00 trough and its 14:00 peak. Seasonality is the New Relic feature built precisely for that: it tells the baseline model that the signal has a repeating time-of-day or day-of-week shape, so 3 a.m. is compared against other 3 a.m.s rather than against a flat average.

Shippo sets it in exactly three places, always to the same value.

FileValue
infra/newrelic-metric-log-ingest/alerts.tf:99new_relic_calculation
services/carrier-monitoring/newrelic.tf:1243new_relic_calculation
services/tracking-monitoring/vars.tf:1361new_relic_calculation

new_relic_calculation lets New Relic detect the period itself. The provider also accepts explicit periods; check the provider documentation for the current accepted set rather than assuming, because the Shippo module applies no validation:

variable "signal_seasonality" {
  type        = string
  description = "The seasonality of the signal."
  default     = null
}

shippo-tf-services/modules/newrelic-alert/vars.tf:158

No CCAP condition sets it. Not one.

Why CCAP chose ratios instead, and when that is wrong

There are two ways to make a threshold survive diurnal volume.

Guarded ratio (what CCAP does)Baseline with seasonality (what CCAP does not)
MechanismDivide the volume out of the signal.Model the volume and compare against the model.
Tuning inputA percentage you choose.A deviation count you choose.
Explainable in a runbookYes. "Above 15% failures for 20 minutes."Harder. "Five deviations from a learned prediction."
Needs training historyNo. Works from the first window.Yes. Behaves poorly on new or changed signals.
Handles a fault that scales with volumeYes. A ratio is flat if failures scale with calls.Yes.
Handles a signal with no natural denominatorNo. There is nothing to divide by.Yes.

That last row is the decision rule. A ratio needs a denominator that means something. Error rate has one, which is total calls. A raw count of registrations does not. That is why [CCAP] Carrier MCA Registration Count | Anomaly Detection, which counts registrations per carrier, was written as a baseline condition rather than a ratio: there is no sensible denominator for "how many registrations should have happened".

Do not blame baseline for the MCA Registration condition

That condition produced weekend false positives, and it is a baseline condition, so the two facts invite a wrong conclusion. The cause was in the expiration block: openViolationOnExpiration: true with a 24-hour window on a per-carrier facet. See lesson 3. The baseline model was never the problem, and seasonality would not have fixed it.

When to reach for baseline

  1. The signal is a count with no denominator, and the count varies with time of day.
  2. The signal has months of stable history to learn from.
  3. You cannot name a correct static threshold, and neither can anyone else on the team.
  4. A false negative is more acceptable than a permanently mistuned static bar.

If you do use it, add signal_seasonality = "new_relic_calculation" whenever the signal shows the daily shape from lesson 2. Three Shippo services already do. Carrier signals have exactly that shape and none of them do.

Check yourself

1. On a BASELINE condition with critical ABOVE 5, what does the value 5 compare against?

2. Your MCP query of a condition returns no baselineDirection field. What may you conclude?

3. You must alert on a per-carrier count of scan form submissions, which has a strong daily shape and no meaningful denominator. What fits best?

4. Shippo uses upper_only on eight baseline call sites and lower_only on none. What explains the absence?

Read this next

Primary source: New Relic docs, Alert conditions, section on baseline thresholds.

Provider reference for the accepted signal_seasonality and baseline_direction values: Terraform newrelic_nrql_alert_condition.