# Schedule Google Compute Engine Instances to Save Big Money.

URL: https://onthegoalways.com/blog/gcp-suspend-resume-vm
Author: Sachin Ghait
Published: 2021-10-04
Updated: 2026-09-28
Category: Cloud

> **TL;DR:** If you only use a GCP Compute Engine VM for a few hours daily, you're overpaying. This guide shows how to automate VM start/stop (or suspend/resume) on a cron schedule using Cloud Scheduler, Pub/Sub, and Cloud Functions. When stopped, you only pay for disk and network -- not compute. Note that suspend/resume (like hibernate) only works on N2+ instances, not E2. The post covers the full setup including IAM permissions and function deployment.

Virtual machine is first type of compute for someone starting with the cloud. As per many reports 80-85% enterprise workload have migrated to cloud. \
With this increased cloud adoptions, individuals also thinking of shifting some heavy compute tasks on cloud VMs, rather than building a machine at home. As there is a benefit of `pay-as-you-go` model in cloud resources and no mainteance required.

In this article I’ll be showing you how you can save up money if you are using compute engine VMs for very few hours a day.

## How does pay-as-you-go pricing work for Compute Engine?

With `pay-as-you-go` model you only pay for time you use a resource.
If you have a schedule like daily for 2-3 hours you will need to use a VM, you can keep it in `stopped` or `suspended` state.

GCP compute engine lets you start and stop a compute engine VM.
In this case you only pay minor charges for network resources and disk attached.
In GCP there is also an option to suspend and resume compute engine VM. Which is similar to hibernate on our physical machines.

Here is the maths. If you need a VM for 3 hours a day, running it 24/7 means you pay for 21 idle hours. Scheduling it cuts compute time to 3/24, which is 12.5% of the always-on hours.

One limit to know: a suspended VM can stay suspended for up to 60 days. After that, Compute Engine moves it to `TERMINATED` and the saved memory state is lost ([Google Cloud docs](https://cloud.google.com/compute/docs/instances/suspend-resume-instance)).


**NOTE:** Right now as I am writing this article, E2 type compute engine instances do not support suspend/resume feature. So I had to choose N2 type VM. So keep this in mind if you want suspend/resume feature for your use-case.

## How do I schedule a VM to suspend and resume automatically?

[This gcp documentation ](https://cloud.google.com/scheduler/docs/start-and-stop-compute-engine-instances-on-a-schedule) show how you can use cloud functions along with pub-sub trigger and cloud scheduler to manage state of VM on a cron schedule.

These extra resources are required for this solution

1. cloud function - logic to change VM state
2. pub-sub - acts as trigger for cloud function
3. cloud scheduler - publishes message to pub-sub when cron expression is matched.

VM price for month ranges from 15$-20$ per vCPU. cloud schedulerand pubsub costs 3-4 \$ for this use case. This is peanuts amount as compared to VMs monthly cost.
Use [pricing calculator](https://cloud.google.com/products/calculator) to calculate exact costs.

## Implementation

Cloud function has a `pub-sub` trigger.
![Cloud Function trigger configured with a Pub/Sub topic](/assets/vm-auto-trigger.webp)
Cloud function code is as below, `change_vm_state` function is invoked when pub-sub message is received.

```python{1,3-5}
import base64
import googleapiclient.discovery
import sys

PROJECT = "GCP-PROJECT-NAME"
ZONE = "VM-ZONE"
INSTANCE = "INSTANCE-NAME"

def suspend(compute):
    return compute.instances().suspend(project=PROJECT, zone=ZONE, instance=INSTANCE).execute()

def resume(compute):
    return compute.instances().resume(project=PROJECT, zone=ZONE, instance=INSTANCE).execute()

def change_vm_state(event, context):
    # Parse pubsub message
    pubsub_message = base64.b64decode(event['data']).decode('utf-8')
    # Pubsub message should not be empty
    if pubsub_message == None:
        print("No operation specified, choose either `suspend` or `resume`")
        sys.exit()
    # Create compute client using googleapiclient.
    # Suspend resume comes under beta APIs, so we need to pass `compute` and `beta` params.
    compute = googleapiclient.discovery.build('compute', 'beta')

    if pubsub_message == "suspend":
        suspend(compute)
    elif pubsub_message == "resume":
        resume(compute)
    else:
        print("Invalid operation. choose either `suspend` or `resume`")
        sys.exit()
```

This scripts require `google-api-python-client==1.10.0` library as dependancy.
We need to reference the `beta` APIs using this library.
Read more in the [Compute Engine beta REST API reference](https://cloud.google.com/compute/docs/reference/rest/beta).

Keep in mind that you have to attach a service account which has compute engine permissions to start/stop/suspend/resume VM.
![Service account and IAM roles for the VM scheduler function](/assets/vm-auto-service-acc.webp)

Using cloud scheduler you can send a message to pubsub on a cron schedule.
![Cloud Scheduler job that publishes to a Pub/Sub topic on a cron schedule](/assets/vm-auto-cluod-scheduler.webp)

In next step you can define what message to send to pub-sub.
![Pub/Sub topic used to trigger VM start and stop](/assets/vm-auto-pub-sub.webp)

This way you dont have to remember to suspend the VM when you are done working. \
![gif](https://media0.giphy.com/media/26xBzL5fpjhJ9dQNa/200.webp?cid=ecf05e47wnymqyqvko2pn52q3ieue2lyhw821z1hj56yy1dl&rid=200.webp&ct=g)

## Frequently Asked Questions

### What is the difference between stopping and suspending a VM?

Stopping shuts down the OS, like powering off. Suspending saves memory and application state to storage, like hibernate, so you resume where you left off.

### Do I pay anything while the VM is stopped or suspended?

You don't pay for vCPUs and memory. You still pay for attached persistent disks and any reserved static IPs. For a suspended VM you also pay to store its saved memory.

### Is there a simpler way than Cloud Functions?

Yes. Compute Engine has built-in instance schedules that start and stop VMs on a cron schedule with no code. Use the Cloud Function approach when you need suspend and resume.

## References

- [VM feature comparisons for top 3 clouds](https://www.youtube.com/watch?v=KkKcaFp0z1s&t=699s)
- [Google Cloud: Start and stop instances on a schedule with Cloud Scheduler](https://cloud.google.com/scheduler/docs/start-and-stop-compute-engine-instances-on-a-schedule)
- [Google Cloud: Suspend or resume a Compute Engine instance](https://cloud.google.com/compute/docs/instances/suspend-resume-instance)
- [Google Cloud: Schedule a VM to start and stop](https://cloud.google.com/compute/docs/instances/schedule-instance-start-stop)
