TL;DR: The simplest, highest-ROI AWS optimization is turning things off when you're not using them — yet a shocking number of teams run dev/test environments 24/7 while developers only touch them during business hours. An instance needed ~50 of 168 hours a week is a ~70% overspend running around the clock. AWS Instance Scheduler (free, since 2016) automates start/stop with a single tag; implement it once and save every month, forever.
The numbers
- ~70% cut for a weekday-business-hours schedule (≈50 active of 168 hours).
- Worked example: ten m5.large at $0.096/hr → $700.80/mo running 24/7 vs ~$208/mo on office hours —
$492/mo ($6,000/yr) saved, zero architecture change. - Demo/training environments used a few hours a week can save 90%+.
- AWS Instance Scheduler deploys via CloudFormation (Lambda + DynamoDB + CloudWatch Events); you define periods/schedules and tag instances with the schedule name.
Do this
- Deploy AWS Instance Scheduler and tag instances with a schedule (e.g. start 8:30 AM, stop 6:30 PM, weekdays), defaulting non-prod to "off":
aws ec2 create-tags --resources i-0123abcd --tags Key=Schedule,Value=office-hours - Target the right environments — dev/test/demo/training/sandbox are the sweet spot; leave true 24/7 production alone, and schedule staging only if it isn't mirroring prod.
- Handle global teams with region-specific schedules (NYC boxes on ET hours, London on GMT) or an extended shared window (still ~58% off at 1 AM–11 PM ET) — "global team" doesn't mean "always on."
- Add override periods for release weeks or on-call needs, and give developers a manual "wake up" path for the rare off-hours case.
- Don't forget databases — RDS uses its own stop/start feature, separate from EC2 scheduling.
Gotchas
- Instance-store (ephemeral) volumes lose data on stop — use EBS for anything you need to persist.
- Unattached Elastic IPs still bill when the instance is stopped — release them or front with a load balancer (see Unassociated Elastic IPs).
- Startup must be clean — instances relying on manual startup scripts need the schedule tested end-to-end before you trust it.
- Manual stopping won't stick — someone always forgets; the savings only compound when it's automated.
Skip this if
- The workload genuinely serves traffic 24/7 — there's no idle window; commit the baseline with Compute Savings Plans or Reserved Instances instead.
- The instance has expensive warm-up (large in-memory models/caches) and you need fast resume with state intact — EC2 Hibernation preserves RAM across the pause. For virtual desktops, WorkSpaces AutoStop is the equivalent lever.