FinOps / Guide 4

Power-off schedules

Turning off non-production outside working hours: how much it saves, the tools in each cloud, and what keeps billing.

A VM bills for every hour it runs, whether anyone is using it or not. Development, test, training and demo environments are typically used during working hours on weekdays, yet many run 24 hours a day, 7 days a week. Turning them off outside working hours is one of the easiest savings in the cloud, and it needs no change to the application.

How much it saves

A week has 168 hours. A schedule of 7:00 to 19:00, Monday to Friday, runs a VM for 60 of them.

ScheduleHours running per weekCompute saving
Always on1680%
Weekdays 7:00 to 19:0060about 64%
Weekdays 8:00 to 18:0050about 70%
Off at weekends only120about 29%
On only when someone starts itvariesoften 80% or more

The saving applies to compute. Disks, snapshots and reserved IP addresses keep billing while the VM is off (see the last section).

Choose what to schedule

  • Good candidates: development, test, QA, training and demo VMs; build agents; jump boxes; anything tagged with a non-production environment.
  • Usually not: production, domain controllers, anything other systems depend on overnight (batch, backups, replication targets), and VMs covered by a reservation or committed use discount (you pay for those whether they run or not).

Agree the hours with the team, and give them a way to start a VM out of hours when they need it. A schedule that blocks work gets switched off by the first frustrated engineer.

Use a tag to drive the schedule

Put the schedule on the resource as a tag (Azure, AWS) or label (Google Cloud), so the owner can see it and change it, and automation can act on it. For example:

Tag or labelValueMeaning
Schedule / scheduleoffice-hoursRun weekdays 7:00 to 19:00 local time
weekdaysOff at weekends only
manualStop every evening; start on request
always-onExcluded from scheduling (record why in another tag)

Tools in each cloud

AzureAWSGoogle Cloud
Built-in, per VMAuto-shutdown on each VM (stop only, at a set time)-Instance schedules: a resource policy with start and stop times, attached to VMs
Fleet-wide, tag-drivenStart/Stop VMs v2 (Azure Functions; Microsoft now only maintains it), Azure Automation, or a scheduled scriptInstance Scheduler on AWS (an AWS solution that starts and stops EC2 and RDS on tag-based schedules)Instance schedules, or a scheduled script
Script on this siteInvoke-AzVMPowerSchedule.ps1Invoke-AwsEC2PowerSchedule.ps1Invoke-GcpVMPowerSchedule.ps1

The scripts on this site read a schedule tag or label, support -WhatIf, and skip VMs that belong to scale sets, Auto Scaling groups or managed instance groups, which should be scaled instead.

# Google Cloud: a weekday office-hours schedule, attached to a VM
gcloud compute resource-policies create instance-schedule sched-office-hours --region=us-east1 `
    --vm-start-schedule='0 7 * * MON-FRI' --vm-stop-schedule='0 19 * * MON-FRI' `
    --timezone='America/New_York'
gcloud compute instances add-resource-policies vm-notes-test-01 --zone=us-east1-b `
    --resource-policies=sched-office-hours
# Azure: Stop-AzVM deallocates by default, which stops compute billing.
# -StayProvisioned keeps the VM allocated, and it keeps billing for compute.
Stop-AzVM -ResourceGroupName 'rg-notes-test' -Name 'vm-notes-test-01' -Force

Databases and other services

AzureAWSGoogle Cloud
Pause or stop a databaseAzure SQL Database serverless pauses automatically when idle; Azure Database for PostgreSQL and MySQL flexible servers can be stoppedAmazon RDS and Aurora can be stopped for up to 7 days, then start again automaticallyCloud SQL instances can be stopped (activation policy NEVER)
ContainersScale AKS user node pools to zero; stop the clusterScale EKS node groups downScale GKE node pools down; Autopilot bills for running pods

What keeps billing when a VM is off

  • Disks (OS and data) and snapshots.
  • Public IP addresses: Azure Standard public IPs, every AWS public IPv4 address (US$0.005 an hour since February 2024, attached or not), and Google Cloud static external IPs that are reserved but not in use.
  • Reservations and committed use discounts attached to the VM's size: the commitment is paid whether the VM runs or not. Don't schedule VMs you've committed for, and don't commit for VMs you schedule.
  • Azure only: a VM that is stopped from inside the operating system is not deallocated and keeps billing for compute. Stop it from the portal, PowerShell or the CLI so it shows Stopped (deallocated).