Control resource usage with notifications Stay organized with collections Save and categorize content based on your preferences.
This document explains how to use budget notifications to selectivelycontrol resource usage.
When youdisable billing on a project,all services stop and all resources are eventually deleted. If you need a morenuanced response, you can selectively control resources. For example, you canstop some Compute Engine resources while leaving Cloud Storage resourcesintact. Stopping only some resources reduces your costs without completelydisabling your environment.
In the following example, the project runs research with a number ofCompute Engine virtual machines (VMs) and stores results inCloud Storage buckets. Using the budget notifications as the trigger, afterthe budget is exceeded, this Cloud Run function shuts down allCompute Engine instances, but doesn't affect the stored results.
Before you begin
Before you begin, you must complete the following tasks:
Set up a Cloud Run function
- Complete the steps inCreate a Cloud Run function.Ensure that you set theTrigger type to the same Pub/Subtopic that your budget will use.
Add the following dependencies:
Node.js
Copy the following to your
package.jsonfile:{"name":"cloud-functions-billing","private":"true","version":"0.0.1","description":"Examples of integrating Cloud Functions with billing","main":"index.js","engines":{"node":">=16.0.0"},"scripts":{"compute-test":"c8 mocha -p -j 2 test/periodic.test.js --timeout=600000","test":"c8 mocha -p -j 2 test/index.test.js --timeout=5000 --exit"},"author":"Ace Nassri <anassri@google.com>","license":"Apache-2.0","dependencies":{"@google-cloud/billing":"^4.0.0","@google-cloud/compute":"^4.0.0","google-auth-library":"^9.0.0","googleapis":"^143.0.0","slack":"^11.0.1"},"devDependencies":{"@google-cloud/functions-framework":"^3.0.0","c8":"^10.0.0","gaxios":"^6.0.0","mocha":"^10.0.0","promise-retry":"^2.0.0","proxyquire":"^2.1.0","sinon":"^18.0.0","wait-port":"^1.0.4"}}Python
Copy the following to your
requirements.txtfile:slackclient==2.9.4google-api-python-client==2.131.0Copy the following code into your Cloud Run function:
Node.js
const{CloudBillingClient}=require('@google-cloud/billing');const{InstancesClient}=require('@google-cloud/compute');constPROJECT_ID=process.env.GOOGLE_CLOUD_PROJECT;constPROJECT_NAME=`projects/${PROJECT_ID}`;constinstancesClient=newInstancesClient();constZONE='us-central1-a';exports.limitUse=asyncpubsubEvent=>{constpubsubData=JSON.parse(Buffer.from(pubsubEvent.data,'base64').toString());if(pubsubData.costAmount<=pubsubData.budgetAmount){return`No action necessary. (Current cost:${pubsubData.costAmount})`;}constinstanceNames=await_listRunningInstances(PROJECT_ID,ZONE);if(!instanceNames.length){return'No running instances were found.';}await_stopInstances(PROJECT_ID,ZONE,instanceNames);return`${instanceNames.length} instance(s) stopped successfully.`;};/** * @return {Promise} Array of names of running instances */const_listRunningInstances=async(projectId,zone)=>{const[instances]=awaitinstancesClient.list({project:projectId,zone:zone,});returninstances.filter(item=>item.status==='RUNNING').map(item=>item.name);};/** * @param {Array} instanceNames Names of instance to stop * @return {Promise} Response from stopping instances */const_stopInstances=async(projectId,zone,instanceNames)=>{awaitPromise.all(instanceNames.map(instanceName=>{returninstancesClient.stop({project:projectId,zone:zone,instance:instanceName,}).then(()=>{console.log(`Instance stopped successfully:${instanceName}`);});}));};Python
importbase64importjsonimportosfromgoogleapiclientimportdiscoveryPROJECT_ID=os.getenv("GCP_PROJECT")PROJECT_NAME=f"projects/{PROJECT_ID}"ZONE="us-west1-b"deflimit_use(data,context):pubsub_data=base64.b64decode(data["data"]).decode("utf-8")pubsub_json=json.loads(pubsub_data)cost_amount=pubsub_json["costAmount"]budget_amount=pubsub_json["budgetAmount"]ifcost_amount <=budget_amount:print(f"No action necessary. (Current cost:{cost_amount})")returncompute=discovery.build("compute","v1",cache_discovery=False,)instances=compute.instances()instance_names=__list_running_instances(PROJECT_ID,ZONE,instances)__stop_instances(PROJECT_ID,ZONE,instance_names,instances)def__list_running_instances(project_id,zone,instances):""" @param {string} project_id ID of project that contains instances to stop @param {string} zone Zone that contains instances to stop @return {Promise} Array of names of running instances """res=instances.list(project=project_id,zone=zone).execute()if"items"notinres:return[]items=res["items"]running_names=[i["name"]foriinitemsifi["status"]=="RUNNING"]returnrunning_namesdef__stop_instances(project_id,zone,instance_names,instances):""" @param {string} project_id ID of project that contains instances to stop @param {string} zone Zone that contains instances to stop @param {Array} instance_names Names of instance to stop @return {Promise} Response from stopping instances """ifnotlen(instance_names):print("No running instances were found.")returnfornameininstance_names:instances.stop(project=project_id,zone=zone,instance=name).execute()print(f"Instance stopped successfully:{name}")Set theEntry point to the correct function to execute:
Node.js
Set theEntry point to
limitUse.Python
Set theEntry point to
limit_use.Review thelist of environment variables set automatically and determine if you need to manually set theGCP_PROJECT variableto the project running the virtual machines.
Set theZONE parameter. This parameter is the zone where instancesare stopped when the budget is exceeded.
Note: This code sample only stops instances in a single zone in the specifiedproject. Depending on your needs, you can change the code inside yourCloud Run function to handle other projects and zones.ClickDEPLOY.
Configure service account permissions
Your Cloud Run function runs as an automatically created serviceaccount. To control usage, you need to grant the service account permissions toany services on the project that it needs to modify by completing the followingsteps:
- Identify the correct service account by viewing the details of yourCloud Run function. The service account islisted at the bottom of the page.
Go to theIAM page in the Google Cloud console to set theappropriate permissions.
Test that instances are stopped
To ensure your function works as expected, follow the steps inTest a Cloud Run function.
If successful, your Compute Engine VMs in the Google Cloud console are stopped.
What's next
Review other programmatic notification examples to learn how to do thefollowing:
Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2026-02-19 UTC.