# SageMaker Notebook Missing Auto-Stop

> SageMaker notebooks probed with no lifecycle configuration attached are candidates for a measured off-hours start/stop schedule priced as cost times the heatmap idle fraction. ZopNight abstains on every notebook today: NotebookInstances publish no AWS-managed CloudWatch metrics, so no heatmap exists. Remediation still suggests a 1-hour idle-shutdown script as a safety net.

Source: https://zop.dev/integrations/aws/recommendations/sagemaker-notebook-missing-auto-stop
Updated: 2026-08-19

---

## Notebooks with no lifecycle config attached

- Metadata["lifecycleConfigName"] (sagemaker.go stamps the attached NotebookInstanceLifecycleConfigName, or "" when none), read Metadata-first (Principle 5; the prior hasTag(Tags,"auto_stop","false") gate was tag-gated-dead, no producer wrote it). Key-absent (not probed / describe failed) → abstain; non-empty value (a config is attached) → abstain; key-present-and-empty (probed, no config) → proceed.
- PRODUCER-GAP ScheduleData[uid].IdlePercentage for sagemaker-notebook: SageMaker NotebookInstances [publish no AWS-managed CPU/Memory CloudWatch metrics](https://docs.aws.amazon.com/sagemaker/latest/dg/monitoring-cloudwatch.html) by default, so the aggregator's GetScheduleRecommendations returns nil for "sagemaker-notebook" and produces no heatmap or ScheduleData, so this rule abstains on every notebook in production today (correct concrete-or-abstain, but it does not yet fire). To make it fire, feed the heatmap with a notebook-activity producer (opt-in CloudWatch Agent custom metrics, CWAgent namespace, or a last-activity-derived idle signal).

## Why a schedule, not a one-shot stop

concrete-or-abstain (cost-driven schedule). The lever is a recurring off-hours start/stop schedule that pauses the notebook during the measured idle window, not a one-shot stop (compute one-shot stop is advisory-only) and not a $0 governance advisory (the missing-lifecycle-config compliance angle is already fully owned by sibling RC-1623). savings = cost × ScheduleData[uid].IdlePercentage, optimized = cost − savings. Abstains (returns nil) when no measured schedule data exists or the idle fraction is non-positive: never a fabricated flat fraction, never a $0 advisory. (See PRODUCER-GAP above: abstains on every notebook today.)

## Setting up idle shutdown on a notebook

1. Review the recommended off-hours schedule (start/stop cron, timezone) and apply it from this recommendation
2. Also attach a lifecycle configuration with an idle-shutdown on-start script as a safety net
3. Set idle timeout to 1 hour for development notebooks
4. Consider migrating to SageMaker Studio which has built-in auto-shutdown
