I tried the new CloudWatch Alarm feature "Warmup Period"
This page has been translated by machine translation. View original
Introduction
On September 1, 2026, AWS announced in What's New that Amazon CloudWatch alarms now support warmup periods.
According to the What's New post, this feature is available in all regions where Amazon CloudWatch is offered, with no additional charges beyond the standard CloudWatch alarm pricing.
What is a Warmup Period?
A warmup period is a quiet period that delays the start of alarm evaluation for a certain amount of time immediately after alarm creation, suppressing false alerts caused by metrics not yet arriving.
Previously, when you created an alarm before metrics had started arriving, CloudWatch would evaluate the alarm state based on the treat missing data setting from the very first evaluation. With a warmup period, the alarm state (StateValue) becomes INSUFFICIENT_DATA during that period. The evaluation state (EvaluationState) becomes IN_WARM_UP, and alarm actions are not executed.
A warmup period can be specified for both PutMetricAlarm and PutLogAlarm. The required parameter WarmUpPeriodDurationInMinutes accepts values from 1 to 2,880 minutes (2 days). The optional parameter OnlyStartEvaluatingAfterWarmUpPeriodEnds defaults to false. In this case, the warmup ends early once the evaluation window (Period × Evaluation Periods) is filled. When set to true, evaluation will not start until the warmup period expires, even if data arrives early. The documentation states that Datapoints to Alarm does not affect the early termination determination.
Note that the warmup applies only once at alarm creation.
Warm-up applies only once at alarm creation and does not restart.
Verification
The verification was performed using AWS CLI 2.36.36. The aws cloudwatch put-metric-alarm command in this version supports --warm-up-configuration.
Alarm Configuration
Four alarms were created simultaneously in the ap-northeast-1 region, targeting custom metrics in the namespace WarmUpDemo/233910. The threshold and evaluation period are common across all four alarms.
--statistic Average --period 60 --evaluation-periods 1 --datapoints-to-alarm 1
--threshold 80 --comparison-operator GreaterThanThreshold
--treat-missing-data breaching
The reason for choosing breaching for the missing data handling is that with the default missing setting, the alarm remains in INSUFFICIENT_DATA when data is missing, resulting in no behavioral difference with or without a warmup.
The warmup specification (--warm-up-configuration) was set to three patterns (none / 5 minutes / 5 minutes + full wait), and four alarms were created in combination with the target metrics.
A: warmup-demo-A-nowarmup metric=m1 none
B: warmup-demo-B-warm5 metric=m1 {"WarmUpPeriodDurationInMinutes":5}
C: warmup-demo-C-warm5 metric=m2 {"WarmUpPeriodDurationInMinutes":5}
D: warmup-demo-D-warm5-full metric=m2 {"WarmUpPeriodDurationInMinutes":5,"OnlyStartEvaluatingAfterWarmUpPeriodEnds":true}
Metrics were sent starting at t+120 seconds after alarm creation (t=0), at 20-second intervals, and stopped at t+780 seconds. Nothing was sent until t+120 seconds. m1 continued sending values of 10 (below the threshold) from t+120 seconds onward. m2 sent values of 95 (exceeding the threshold) between t+120 and t+240 seconds, then switched back to sending values of 10 after t+240 seconds.
The configuration of all four alarms can be verified with describe-alarms.
aws cloudwatch describe-alarms --alarm-name-prefix warmup-demo --query 'MetricAlarms[].{N:AlarmName,M:MetricName,W:WarmUpConfiguration}' --output json
[
{
"N": "warmup-demo-A-nowarmup",
"M": "m1",
"W": null
},
{
"N": "warmup-demo-B-warm5",
"M": "m1",
"W": {
"WarmUpPeriodDurationInMinutes": 5,
"OnlyStartEvaluatingAfterWarmUpPeriodEnds": false
}
},
{
"N": "warmup-demo-C-warm5",
"M": "m2",
"W": {
"WarmUpPeriodDurationInMinutes": 5,
"OnlyStartEvaluatingAfterWarmUpPeriodEnds": false
}
},
{
"N": "warmup-demo-D-warm5-full",
"M": "m2",
"W": {
"WarmUpPeriodDurationInMinutes": 5,
"OnlyStartEvaluatingAfterWarmUpPeriodEnds": true
}
}
]
N, M, and W are display shorthand names assigned in the query; the field names returned by the API are AlarmName, MetricName, and WarmUpConfiguration. Even for B and C, where the early termination parameter was omitted, false was explicitly shown. For A, where no warmup was specified, WarmUpConfiguration itself was null.
State Immediately After Creation
The state was tracked with polling at 20-second intervals.
aws cloudwatch describe-alarms --alarm-name-prefix warmup-demo --query 'MetricAlarms[].[AlarmName,StateValue,EvaluationState]' --output text
The elapsed seconds column was added at polling time. The subsequent columns are in the order of alarm name, StateValue, and EvaluationState. The following are the results from t+3 to t+43 seconds.
t+3s warmup-demo-A-nowarmup INSUFFICIENT_DATA None
t+3s warmup-demo-B-warm5 INSUFFICIENT_DATA IN_WARM_UP
t+3s warmup-demo-C-warm5 INSUFFICIENT_DATA IN_WARM_UP
t+3s warmup-demo-D-warm5-full INSUFFICIENT_DATA IN_WARM_UP
t+23s warmup-demo-A-nowarmup INSUFFICIENT_DATA None
t+23s warmup-demo-B-warm5 INSUFFICIENT_DATA IN_WARM_UP
t+23s warmup-demo-C-warm5 INSUFFICIENT_DATA IN_WARM_UP
t+23s warmup-demo-D-warm5-full INSUFFICIENT_DATA IN_WARM_UP
t+43s warmup-demo-A-nowarmup ALARM None
t+43s warmup-demo-B-warm5 INSUFFICIENT_DATA IN_WARM_UP
t+43s warmup-demo-C-warm5 INSUFFICIENT_DATA IN_WARM_UP
t+43s warmup-demo-D-warm5-full INSUFFICIENT_DATA IN_WARM_UP
The missing metrics situation and the breaching setting are common across all four alarms. Alarm A, which has no warmup specified, was still INSUFFICIENT_DATA at the t+23 second poll, but had changed to ALARM by the t+43 second poll. At the same time, B / C / D remained in warmup. The EvaluationState for A, which had no warmup specified, is null, displayed as None in text output.
Early Termination vs. Full Wait
Polling at the same 20-second intervals, B and C with default early termination had already started evaluation at the t+190 second poll. Only D with full wait remained in warmup.
t+169s warmup-demo-B-warm5 INSUFFICIENT_DATA IN_WARM_UP
t+169s warmup-demo-C-warm5 INSUFFICIENT_DATA IN_WARM_UP
t+169s warmup-demo-D-warm5-full INSUFFICIENT_DATA IN_WARM_UP
t+190s warmup-demo-A-nowarmup ALARM None
t+190s warmup-demo-B-warm5 OK None
t+190s warmup-demo-C-warm5 ALARM None
t+190s warmup-demo-D-warm5-full INSUFFICIENT_DATA IN_WARM_UP
t+232s warmup-demo-A-nowarmup OK None
t+232s warmup-demo-B-warm5 OK None
t+232s warmup-demo-C-warm5 ALARM None
t+232s warmup-demo-D-warm5-full INSUFFICIENT_DATA IN_WARM_UP
t+317s warmup-demo-C-warm5 OK None
t+317s warmup-demo-D-warm5-full INSUFFICIENT_DATA IN_WARM_UP
t+338s warmup-demo-A-nowarmup OK None
t+338s warmup-demo-B-warm5 OK None
t+338s warmup-demo-C-warm5 OK None
t+338s warmup-demo-D-warm5-full OK None
Alarm A without warmup continued to show ALARM in polls after t+43 seconds, and returned to OK at the t+232 second poll after data arrived. B with default early termination became OK at the t+190 second poll without going through ALARM, without waiting for the 5-minute expiration, after data arrived. C has the same early termination setting, but targets metric m2 which contains a spike. Because evaluation started early, it detected the value of 95 sent during the warmup period and went into ALARM.
D with full wait specified was still in warmup at t+317 seconds and became OK at the next t+338 second poll. Evaluation began after the 5-minute (300-second) expiration. Since the value had returned to 10 by that point, the alarm transitioned directly from INSUFFICIENT_DATA to OK, and the spike was not detected.
This difference can also be confirmed from the state transition history.
State transition history for all 4 alarms
aws cloudwatch describe-alarm-history --alarm-name <alarm name> --history-item-type StateUpdate --query 'reverse(AlarmHistoryItems[].{T:Timestamp,S:HistorySummary})' --output json
T / S are also display shorthand names; the field names returned by the API are Timestamp / HistorySummary.
--- warmup-demo-A-nowarmup ---
[
{
"T": "2026-09-01T23:39:52.933000+09:00",
"S": "Alarm updated from INSUFFICIENT_DATA to ALARM"
},
{
"T": "2026-09-01T23:42:52.928000+09:00",
"S": "Alarm updated from ALARM to OK"
}
]
--- warmup-demo-B-warm5 ---
[
{
"T": "2026-09-01T23:42:16.303000+09:00",
"S": "Alarm updated from INSUFFICIENT_DATA to OK. State now evaluated with the full set of metrics matching the query"
}
]
--- warmup-demo-C-warm5 ---
[
{
"T": "2026-09-01T23:42:15.880000+09:00",
"S": "Alarm updated from INSUFFICIENT_DATA to ALARM. State now evaluated with the full set of metrics matching the query"
},
{
"T": "2026-09-01T23:44:15.879000+09:00",
"S": "Alarm updated from ALARM to OK"
}
]
--- warmup-demo-D-warm5-full ---
[
{
"T": "2026-09-01T23:44:28.840000+09:00",
"S": "Alarm updated from INSUFFICIENT_DATA to OK. State now evaluated with the full set of metrics matching the query"
}
]
There are no ALARM entries in D's history. As described in the previous section, this is because the value at the time evaluation started was 10. B also has no ALARM history entries. B targets m1, and there was no data exceeding the threshold after evaluation started. For both B and D, no StateUpdate history entries were added during the warmup period, and the first entry was from when evaluation began. Since the state remains INSUFFICIENT_DATA throughout the warmup, there are no state changes to record in history. In this case, the absence of state transitions in the alarm history is not abnormal.
Behavior After Metric Transmission Stopped
Metric transmission was stopped at t+780 seconds, and the subsequent state was checked using the same describe-alarms command. +2min / +3min represent the elapsed time since transmission stopped.
--- +2min ---
warmup-demo-A-nowarmup OK None
warmup-demo-B-warm5 OK None
warmup-demo-C-warm5 OK None
warmup-demo-D-warm5-full OK None
--- +3min ---
warmup-demo-A-nowarmup ALARM None
warmup-demo-B-warm5 ALARM None
warmup-demo-C-warm5 ALARM None
warmup-demo-D-warm5-full ALARM None
About 3 minutes after transmission stopped, all four alarms had transitioned to ALARM at the poll. The EvaluationState remained null for all four alarms, and IN_WARM_UP never reappeared up to that point. Handling of missing data that occurs during operation continues to be determined by the treat missing data setting, as before.
Summary
CloudWatch alarms can now specify a quiet period at creation time. This allows false alerts caused by metrics not yet arriving immediately after creation to be suppressed without changing the treat missing data setting. The OnlyStartEvaluatingAfterWarmUpPeriodEnds parameter lets you choose whether to start evaluation when data arrives early, or to wait until the period expires.
For example, in a configuration where an application is deployed after launching an EC2 instance with IaC, metrics will be missing until the application starts and can send custom metrics. Even for alarms with treat missing data set to breaching, specifying a warmup period at creation can suppress the transition to ALARM during this initialization period only.
This is well-suited for use cases where you want to give CloudWatch alarm evaluation a grace period while waiting for an application to start. However, it is not a replacement for ELB target health checks or Auto Scaling initialization grace periods. Since the warmup applies only once at creation, you still need to handle missing data during operation using the treat missing data setting.
Reference Links
