Guide ยท the hard cap

The GCP kill switch: an actual spending cap, in ~20 minutes

Google Cloud budgets notify โ€” they don't stop anything. The new spend-cap budgets (Preview) only cover a handful of services, and not the ones in the horror stories: Firestore, Compute, BigQuery. If you want a true hard cap today, you build it yourself with Google's own recipe: budget โ†’ Pub/Sub โ†’ a Cloud Function that unlinks billing.

โš ๏ธ Understand what this does before deploying it. Unlinking billing hard-stops every paid service in the project. Resources can be deleted โ€” Compute disks, IPs, data in paid tiers. This is the fire sprinkler, not the thermostat: it ruins the furniture to save the house. Never point it at a project whose data you can't lose, and remember spend can still leak during the up-to-hours billing-data delay.

The recipe (Google's official pattern)

  1. Create a Pub/Sub topic, e.g. budget-killswitch.
  2. Create a budget for the project with your cap amount, and connect the topic to it (console โ†’ Budgets & alerts โ†’ "Connect a Pub/Sub topic").
  3. Deploy this Cloud Function, triggered by that topic:
// index.js โ€” disables billing when the budget is exceeded (Node 20)
const {CloudBillingClient} = require("@google-cloud/billing");
const billing = new CloudBillingClient();
const PROJECT_ID = process.env.GCP_PROJECT_ID;
const PROJECT_NAME = `projects/${PROJECT_ID}`;

exports.stopBilling = async (pubsubEvent) => {
  const data = JSON.parse(
    Buffer.from(pubsubEvent.data, "base64").toString()
  );
  if (data.costAmount <= data.budgetAmount) {
    return console.log("Under budget โ€” no action.");
  }
  const [info] = await billing.getProjectBillingInfo({name: PROJECT_NAME});
  if (!info.billingEnabled) {
    return console.log("Billing already disabled.");
  }
  await billing.updateProjectBillingInfo({
    name: PROJECT_NAME,
    projectBillingInfo: {billingAccountName: ""}, // unlink = hard stop
  });
  console.log(`Billing DISABLED for ${PROJECT_ID}`);
};
  1. Grant the function's service account roles/billing.projectManager on the project (it needs permission to unlink billing).
  2. Test it with a low temporary budget before trusting it with production.

Full walkthrough in Google's docs, and community-maintained versions exist (e.g. Cyclenerd's).

The gap the kill switch can't close

Budget notifications ride the same delayed billing pipeline as everything else โ€” by the time the cap fires, a runaway can already be thousands of dollars in. And a kill switch gives you no why: no baseline, no culprit, no forecast. That's the layer CostCap covers: spend-rate telemetry every ~20 minutes, spike alerts within the hour, leaked-key detection, and budget warnings before the threshold โ€” so in practice the kill switch is the last resort that never has to fire.

๐Ÿงข Recommended setup: CostCap as the early-warning layer (alerts at 50/90/100% and on-pace-to-exceed), the kill switch as the final backstop on projects that can tolerate a hard stop.

Want the warning before the sprinklers?

Free for one billing account. Monitored in minutes.

Put a cap on it โ†’