NoBBomb
NoBBomb is a GCP kill switch. The name stands for "No Billing Bomb". It’s a simple script that you can deploy on your GCP project or fork and modify as you like. The purpose of this script is to target well-known GCP APIs that are prone to generating unexpectedly high costs.
Install / Use
/learn @leo-kling/NoBBombREADME
NoBBomb
<span align="justify">No Billing Bomb (NoBBomb), a GCP Kill Switch & Anti-Burst solution.
Introduction
All-in-one package to increase billing safety on GCP projects, featuring:
- An easy to configure
config.shfile - An easy to deploy script (
deploy.sh) (see Deployed Resources) - Your project's Billing Account currency code (no conversion needed!)
- A classic GCP budget alert:
- Email notifications
- Pub/Sub topic + Eventarc for automatic kill switch trigger
- Custom Cloud Run service:
- [Experimental] Anti-Burst on vulnerable services
- Self-updating every 5th minute (10:00am, 10:05am, 10:10am, etc..)
- Uses Cloud Billing API for real-time SKU prices
- Uses Cloud Monitoring API for 5-minute usage metrics
- A modular architecture to add more services (see MonitoredService Object)
- Exploitable logs / http response on
/nobbombroute (used by Cloud Scheduler)
- Kill switch with 3 modes:
SHUTDOWN: Brutal Hard Stop (shutdown project) (auto unlink billing account)DISABLE_BILLING: Hard stop (disable billing) (default)NONE: Kill switch disabled -> You can add your own logic in thekill_switch.py
- [Experimental] Anti-Burst on vulnerable services
ℹ️ Kill Switch mode works for both budget mechanisms (Budget Alert & Custom Cloud Run), so if you choose SHUTDOWN mode for example, the project will be shutdown either on budget threshold reach or on burst detection.
Before You Start
Prerequisites
[Mandatory] Edit the config.sh file to set your preferences before deploying.
Ensure that you have sufficient permissions on the target GCP project (ex: Owner).
If you need to deploy NoBBomb to a different project, re‑authenticate so the billing information updates correctly.
Be aware that NoBBomb deployment has been tested exclusively on a bash shell.
Additional Notes
Set EXPERIMENTAL_FEATURE=0 in config.sh to disable the Cloud Run anti-burst feature and keep the service as a kill switch only.
Note that you won't be notified when the billing is disabled (DISABLE_BILLING mode) but GCP does send an email when the project is shutdown (SHUTDOWN mode), so you can keep this in mind when choosing the kill switch mode.
Deployment
Standard
Be sure to have gcloud CLI installed on your machine.
Then run:
bash .mise-tasks/login.sh
bash deploy.sh
Mise
If you're familiar with mise, simply run:
mise install
mise login
mise deploy
Deployed Resources
- Services
artifactregistry.googleapis.comcloudbuild.googleapis.comrun.googleapis.comeventarc.googleapis.compubsub.googleapis.comcloudscheduler.googleapis.combillingbudgets.googleapis.com
- Service Account
- Named
nobbomb-kill-switch-sa@[GCP_PROJECT_ID].iam.gserviceaccount.com - IAM
roles/run.invokeron the Cloud Runroles/monitoring.viewerroles/serviceusage.serviceUsageAdminroles/billing.adminroles/resourcemanager.projectDeleter
- Named
- Current Month Budget Alert
- Named:
nobbomb-budget-alert-[GCP_PROJECT_ID]
- Named:
- Cloud Run Service with FastAPI
- Named
nobbomb-kill-switch
- Named
- Cloud Scheduler (At every 5th minute)
- Named
nobbomb-kill-switch-scheduler
- Named
- Pub/Sub Topic
- Named
nobbomb-budget-alert-topic
- Named
- Eventarc Trigger
- Named
nobbomb-pubsub-to-cloudrun-event-arc
- Named
Important Notes
The script is designed to be idempotent, it checks if resources already exist before creating them, so you can re-run it safely if needed.
The app generates its own expenses as it uses Cloud Run and Cloud Monitoring APIs, so be aware of this when deploying on low-budget projects. In my testing, it has never cost more than $1/month.
The kill switch will activate for both budget mechanisms:
- Cloud Budget Alert: On threshold reach OR on Cloud Run analysis
- Custom Cloud Run: On experimental burst detection, which is based on real-time SKU price and usage data
These approaches are complementary and increase safety, which could be summarized as:
- Budget Alert is perfect but slow
- Custom Cloud Run is fast but not perfect
As the goal is not to be accurate to the cent, but to avoid large billing surprises, all SKUs are arbitrarily fetched from us-central1.
Budget Alert applies to the total project cost while Cloud Run monitoring targets specific services only. For example, if Firestore alone causes a cost spike, the Cloud Run kill switch will still rely on the global monthly budget, even though other unrelated services may contribute to it. Since NoBBomb is intended to monitor specific services, this should not be an issue.
If you choose the SHUTDOWN mode, the project pending deletion can be found here.
Example Scenarios
Good Case Scenario:
- Your budget is set to 20$
- You have nothing but Firestore
- Firestore suddenly spikes to 20.01$
- NoBBomb Cloud Run detects the spike and triggers the kill switch immediately
Bad Case Scenario:
- Your budget is set to 20$
- A not monitored service (ex: Compute Engine) has a 19.99$ ongoing cost
- Firestore suddenly spikes to 19.99$ and stops
- Your total cost is now 39.98$ and only the budget alert will trigger once Billing data are updated
Note that the bad case scenario is far better than having no protection at all, which would be a disaster scenario where sky's the limit.
As NoBBomb is under heavy development, consider this behavior as a known limitation for now. I wish to improve it in the future by implementing a logic that could better manage these situations.
Burst Detection - Monitored Services
Monitored services / SKUs are listed in src/config/monitored_services_list.py. You can remove unwanted services by editing this file before deploying. Each object should be considered as a MonitoredService Object. Check the MonitoredService Object section for more details.
Because some services use simple “count” metrics while others rely on more complex signals (ex: Gemini short/long context), burst-detection accuracy can vary by service. A “medium confidence” rating doesn’t mean a service isn’t monitored, it means the signal may be less precise than for high-confidence services.
Monitored with high confidence:
- bigquery.googleapis.com
- Read Bytes Scanned
- firestore.googleapis.com
- Read
- Write
- Delete
- TTL delete
Monitored with medium confidence:
- aiplatform.googleapis.com
- Text Input/Output predictions
- gemini-3-pro
- gemini-3-flash
- gemini-2.5-pro
- gemini-2.5-flash
- gemini-2.5-flash-lite
- gemini-2.0-flash
- gemini-2.0-flash-lite
- Text Input/Output predictions
Functioning Details
Why this app ?
This project aims to help as many people as possible, especially small businesses, students, and non-critical projects (dev environments, sandboxes).
Here's an example graph illustrating GCP billing lag times using Firestore read operations:

Note that this is a very worst-case scenario graph, as GCP billing lag times can vary. My point here is to insist on the drifting nature of GCP billing.
Caution: The budget doesn't automatically set a hard cap on spending. We recommend that you set your budget amount below your available funds, to account for delays in usage reporting.
Note: Google Cloud products report usage and cost data to Cloud Billing processes at varying intervals. As a result, you might see a delay between your use of Google Cloud services, and the usage and costs being available to view in Cloud Billing. Typically, your costs are available within a day, but can sometimes take more than 24 hours.
Architecture Overview
Here is a simplified architecture diagram of NoBBomb:

MonitoredService Object
A MonitoredService Object represents a specific GCP service or SKU that NoBBomb monitors for potential cost spikes.
Raw Object
class MonitoredService:
# Hand crafted Data
service_name: str = ""
service_id: str = ""
sku_name: str = ""
sku_id: str = ""
# Cloud Billing
price_tier: int = 0
# Cloud Monitoring
metric_name: str = ""
metric_filter: str | None = None
# Computed Fields
price_per_unit: float | None = None
number_of_units: int | None = None
expense: float | None = None
Firestore Read Example
MonitoredService(
service_name="Firestore Read Operations",
service_id="EE2C-7FAC-5E08",
sku_name="read_ops",
sku_id="6A94-8525-876F",
metric_name="firestore.googleapis.com/document/read_ops_count",
metric_filter=None,
)
Explanation of Fields
service_name: A human-readable name for the service or SKU being monitored.
