Every other lesson in this course teaches you how to build something on Google Cloud. This one teaches you how to pay for it — and, just as importantly, how to not pay for it by accident. The single most common way a newcomer gets hurt on any cloud is not a security breach; it is a surprise bill. A forgotten virtual machine, a SELECT * over a terabyte, a static IP address reserved and never released — each quietly accrues charges while you sleep. The defence is not luck or constant vigilance; it is understanding the money model end to end and wiring up the guardrails that Google gives you for free.
This lesson is deliberately exhaustive, because billing is the one part of the platform where a small gap in understanding maps directly to real money. We start from the top of the model — the Cloud Billing account, the object that actually holds your payment method and pays the bills — and the two flavours it comes in (self-serve and invoiced). We cover how a billing account connects to projects (the link that turns “I created a resource” into “I owe money”), the complete set of Cloud Billing IAM roles (who is allowed to see spend, set budgets, or move a project’s billing), and the sub-account / reseller model for partners and large organisations. Then we get practical: budgets and alerts (scope, thresholds, the difference between a warning and a hard stop, and Pub/Sub notifications that let you build automated cost control); Cloud Billing reports and the cost table (grouping spend by service, project and — crucially — label); billing export to BigQuery (the three export types, and the SQL that turns raw usage into answers). Finally we lay out the full discount landscape — committed-use discounts (spend-based vs resource-based), sustained-use discounts, Spot VMs, and the Free Tier — and the difference between a quota (a technical cap) and a budget (a financial alarm). By the end you should be able to set up billing for a new organisation, attribute every rupee or dollar of spend to the team that caused it, and sleep through the night.
This is a Foundation-level lesson, so every term is defined the first time it appears. But it is complete: a learner who reads it once should know every option Cloud Billing presents.
Learning objectives
By the end of this lesson you will be able to:
- Distinguish a Cloud Billing account from a project, explain the link between them, and choose between self-serve and invoiced billing.
- Apply the correct Cloud Billing IAM role to each person — Billing Account Administrator, User, Viewer, Costs Manager, Creator, and the project-side Project Billing Manager — and explain why billing permissions are deliberately separate from project permissions.
- Set up budgets with the right scope, thresholds and alert recipients, and explain why a budget is an alarm, not a brake — then build a real hard-stop using Pub/Sub and automation.
- Read the Cloud Billing reports and cost table, and use labels to attribute spend to teams, environments and cost centres.
- Configure billing export to BigQuery (standard usage, detailed usage, and pricing) and write SQL to answer “what did we spend, on what, and where”.
- Choose the right discount for a workload — CUDs (spend-based vs resource-based), SUDs, Spot, and the Free Tier — and quantify the trade-off of each.
- Tell a quota apart from a budget, and design a cost-attribution scheme that survives organisational growth.
Prerequisites & where this fits
You should already understand the resource hierarchy — Organization → Folders → Projects → Resources — and the idea that a project is the unit of isolation and that costs roll up per project. If any of that is shaky, read Google Cloud Fundamentals: Resource Hierarchy, IAM and Pricing first; this lesson goes far deeper on the billing half of that story without repeating the basics. You will also want a Google Cloud account with the $300 free trial or an existing billing account where you have at least Billing Account Viewer. This lesson sits in the Fundamentals module of the GCP Zero-to-Hero course, immediately after the CI/CD deep-dive and before the IAM deep-dive — billing is foundational knowledge every other domain assumes.
Core concepts: the four objects in the money model
Before any option makes sense, you need four mental models. Get these straight and everything else is detail.
1. The Cloud Billing account. This is the object that holds a payment instrument (a credit card, or an agreed invoice arrangement) and that actually pays for usage. It is not a project, and it is not a Google account — it is a separate, top-level object with its own ID (a string like 0X0X0X-0X0X0X-0X0X0X). You can have many of them. A billing account belongs to one Organization (or, for individuals, sits on its own) and is administered through the Billing section of the console, not through any single project.
2. The project. A project is the container that resources live in — VMs, buckets, databases. By itself a project cannot be charged: it has no payment method. To incur charges, a project must be linked to a billing account. The relationship is many-to-one: one billing account can pay for many projects, but each project is linked to exactly one billing account at a time. This link is the hinge of the whole model — resources cost money, projects contain resources, and the billing account pays for the projects linked to it.
3. The bill (charges and credits). As resources run, Google meters usage (vCPU-seconds, gigabyte-months, requests, egress bytes) and applies the published price to produce charges. Against those it applies credits — promotional credit (the $300 trial), committed-use discount credits, sustained-use discount credits, free-tier credits — to produce the net cost you actually pay. Understanding that the headline charge and the net cost are different numbers is the first step to reading any report.
4. The labels and the hierarchy that make spend legible. A bill is only useful if you can answer who spent it and on what. Spend naturally rolls up the resource hierarchy (resource → project → folder → organisation). To slice it any other way — by team, environment, cost centre, application — you attach labels (key/value tags) to resources and projects. Labels are the single most important habit in cloud cost management; we return to them repeatedly.
A few more terms you will meet:
- Invoice — the monthly document (for self-serve accounts, the statement; for invoiced accounts, a true invoice with payment terms).
- Cost vs usage — usage is the metered quantity (e.g. 730 vCPU-hours); cost is usage × price − credits.
- Pricing — Google’s published rates per SKU, before any discount.
- SKU — a Stock Keeping Unit: the finest-grained billable line item (e.g. “N2 Instance Core running in Mumbai”). Every charge maps to a SKU and a service (e.g. Compute Engine).
- Recommender / FinOps — the discipline and the tooling (Recommender, Active Assist) that suggest where to cut waste.
Billing accounts: self-serve vs invoiced, and the lifecycle
A Cloud Billing account comes in two types, and the type is fixed at creation — you cannot flip a self-serve account into an invoiced one; you migrate to a new account. Knowing the difference is a classic Cloud Digital Leader exam point.
| Aspect | Self-serve (online) | Invoiced (offline) |
|---|---|---|
| Payment method | Credit/debit card or, in some regions, direct debit/bank transfer | Monthly invoice with agreed payment terms (e.g. net 30) |
| Who it suits | Individuals, start-ups, small teams | Enterprises, government, anyone needing PO/invoice workflows |
| How you get it | Self-service sign-up — instant | Apply through Google Cloud sales; subject to credit check and minimum spend |
| Documents | Monthly statements, payment receipts | True invoices with billing contacts and tax details |
| Currency/tax | Set at creation, cannot change later | Negotiated; supports more billing arrangements |
| Cost | None to open | None to open; terms are contractual |
| Gotcha | Card failures can suspend resources; keep a backup card | Lead time to set up; not instant |
The lifecycle and its states. A billing account moves through a small set of states you should recognise:
- Open / active — paying for usage normally.
- Closed — you (an administrator) closed it; linked projects stop being able to use paid services and resources may be disabled then eventually deleted. Closing a billing account is destructive to the workloads it funds — detach or relink projects first.
- Suspended — Google suspended it, typically for payment failure (a declined card) or a policy/abuse issue. Resources are disabled until you fix payment. This is the state newcomers hit when a trial card expires.
- Pending — awaiting verification, e.g. during invoiced-account setup.
Account-level settings you can configure: the payment method (add/replace cards, set a backup card), billing contacts and notification language/preferences, the payments profile (legal name, address, tax IDs — shared across Google services and required for invoices), and payment user roles (who can manage the payment instrument). The currency and country of a billing account are chosen at creation and are immutable — a frequent surprise. If you need a different currency, you create a new billing account.
Payments profile vs billing account — don’t confuse them. The payments profile (Google Payments) holds your legal identity and tax info and can back many products and many billing accounts. A Cloud Billing account is the Cloud-specific object that links to projects. One payments profile, potentially several billing accounts.
Linking projects to billing accounts
This is the operation that turns infrastructure into expenditure, so it has its own permission and its own gotchas.
- One link at a time. A project is linked to exactly one billing account. You can change the link (move a project to a different billing account) or disable billing on a project entirely.
- Disabling billing on a project does not delete the project, but it stops paid services — your VMs stop, paid APIs return billing errors. Free-tier-only usage may continue. This is sometimes used as an emergency brake (more on that under budgets).
- The two-sided permission. To attach a project to a billing account you need power on both sides: permission to use the billing account (Billing Account User) and permission on the project (Project Billing Manager, or Owner). This deliberate split means a project owner cannot quietly start spending your organisation’s money, and a billing admin cannot reach into a project they have no rights to. This separation is a favourite interview question.
# See which billing account a project uses
gcloud billing projects describe my-project-id
# Link a project to a billing account (needs rights on BOTH sides)
gcloud billing projects link my-project-id \
--billing-account=0X0X0X-0X0X0X-0X0X0X
# Disable billing on a project (emergency brake — stops paid services)
gcloud billing projects unlink my-project-id
# List every project paid for by a billing account
gcloud billing projects list --billing-account=0X0X0X-0X0X0X-0X0X0X
Cloud Billing IAM roles: every role and where it lives
Billing has its own set of IAM roles, granted at the billing-account level or the organisation level — separate from the roles you grant on projects. This separation exists so that “can spend money” and “can build things” are independent decisions. Learn this table; the exams test it and so do interviewers.
| Role | ID | Granted on | What it can do | Typical holder |
|---|---|---|---|---|
| Billing Account Creator | roles/billing.creator |
Organisation | Create new billing accounts | Org admin / finance lead |
| Billing Account Administrator | roles/billing.admin |
Billing account (or org) | Full control: manage payment, roles, budgets, link/unlink projects, close account | Billing owner |
| Billing Account User | roles/billing.user |
Billing account (or org) | Link projects to this billing account (the right half of the two-sided link) | Anyone who must start funded projects |
| Billing Account Viewer | roles/billing.viewer |
Billing account (or org) | Read cost information, reports, transactions — no changes | Auditors, FinOps analysts |
| Billing Account Costs Manager | roles/billing.costsManager |
Billing account (or org) | Manage budgets, exports and view cost data — but cannot manage payment or link projects | FinOps / cost owner |
| Project Billing Manager | roles/billing.projectManager |
Project (or folder/org) | Link/unlink this project to a billing account (the left half of the link); cannot see costs or change the account | Project owner who must attach billing |
Two subtleties worth internalising:
- Costs Manager vs Viewer. Viewer is read-only on costs. Costs Manager can additionally create and edit budgets and exports — the right role for a FinOps person who must set guardrails but should never touch the company card or move projects.
- The link needs two roles. As above, attaching a project requires Billing Account User and Project Billing Manager. Granting only one leaves the user stuck — a very common “why can’t I link my project?” support ticket.
# Grant a FinOps analyst read-only cost access on a billing account
gcloud billing accounts add-iam-policy-binding 0X0X0X-0X0X0X-0X0X0X \
--member="user:analyst@example.com" \
--role="roles/billing.viewer"
# Let a team lead create funded projects (the right half of the link)
gcloud billing accounts add-iam-policy-binding 0X0X0X-0X0X0X-0X0X0X \
--member="group:platform-team@example.com" \
--role="roles/billing.user"
Sub-accounts and the reseller / large-organisation model
For partners (resellers) and very large organisations that need to separate billing per customer or per business unit while still rolling everything up to a single master invoice, Cloud Billing offers sub-accounts.
- A sub-account is a Cloud Billing account whose charges are rolled up into a parent (master) billing account — the customer or business unit gets its own billing account (own budgets, own projects, own line items), but the parent pays Google and sees the consolidated total.
- This is the foundation of the reseller programme: a Google partner holds the master account and creates a sub-account per end customer, billing each customer separately while settling one invoice with Google.
- Sub-accounts require the invoiced billing model and are created via the Cloud Billing API (they are not a self-serve console click). Each sub-account behaves like a normal billing account for IAM, budgets and export purposes.
- For most internal teams you do not need sub-accounts — a single billing account with disciplined labels and per-project attribution is simpler. Reach for sub-accounts when you must produce separate invoices per tenant, or when a business unit needs a hard administrative boundary around its own spend.
Sub-account vs label vs separate billing account — choosing the boundary. Use labels when you need reporting slices within one account (cheapest, most flexible). Use a separate billing account when a unit needs full administrative independence but no consolidated invoice. Use a sub-account when a unit needs independence and its charges must roll up to one master invoice (resellers, holding companies).
Budgets & alerts: an alarm, not a brake
A budget watches spend against an amount and fires alerts at thresholds you choose. The single most important thing to understand — and the most common misconception — is this:
A budget does not stop spending. By default it only notifies. Google does not put a hard cap on your account because abruptly killing production at month-end would be more dangerous than a slightly larger bill. If you want an actual hard stop, you build one (see the Pub/Sub section below).
Every setting when you create a budget
When you create a budget (Billing → Budgets & alerts → Create budget), you configure four groups of options. Here is every one.
1. Scope — what the budget watches.
| Scope setting | Choices | What it means | When to use |
|---|---|---|---|
| Projects | Entire billing account, or a chosen subset of projects | Limit the budget to specific projects | Per-team or per-environment budgets |
| Services | All services, or specific ones (e.g. just BigQuery) | Watch spend on particular services | Catch a runaway BigQuery or GKE bill |
| Labels | Filter to resources with a given label key/value | Watch only labelled spend (e.g. env:prod) |
Cost-centre or environment budgets |
| Credits | Include or exclude discounts/promotions/CUD credits in the tracked amount | Decide whether the budget tracks gross or net spend | Track net cost to reflect what you actually pay |
| Subaccounts (reseller) | Include/exclude sub-account spend | Scope across the reseller hierarchy | Reseller budgeting |
2. Amount — the number to track against.
| Amount type | Behaviour | When to use |
|---|---|---|
| Specified amount | A fixed figure you type (e.g. ₹50,000 / $600 per month) | Most budgets — a known monthly target |
| Last month’s spend | Auto-tracks against whatever you spent last month | Catch month-on-month growth without re-editing |
| Time range | Monthly (default), quarterly, yearly, or a custom range | Match your finance cadence; yearly for annual commitments |
3. Thresholds — when to alert. You add one or more percentage thresholds of the amount. Each can be measured against:
- Actual spend — alert when what you have already spent crosses, say, 50%, 90%, 100%. (Default thresholds are 50/90/100%.)
- Forecasted spend — alert when Google’s projection of month-end spend is on track to cross a threshold. This is the powerful one: a forecast alert at 100% can warn you on the 12th that you are heading over budget, long before you actually do.
You can mix both — e.g. forecast ≥ 100% and actual ≥ 90% and actual ≥ 100%. There is no limit that matters in practice; add as many as are useful.
4. Actions — who/what is notified.
| Notification channel | What it does | Setup |
|---|---|---|
| Emails billing admins and users by default | On by default | |
| Monitoring channels | Email specific people (not just billing admins) via Cloud Monitoring notification channels | Tick the option, pick the channel |
| Pub/Sub topic | Publishes a structured JSON message to a topic on every threshold and data update — the hook for automation | Tick “Connect a Pub/Sub topic”, choose the topic |
# Create a budget on a billing account with default + forecast thresholds
gcloud billing budgets create \
--billing-account=0X0X0X-0X0X0X-0X0X0X \
--display-name="Prod monthly budget" \
--budget-amount=50000INR \
--filter-projects="projects/my-prod-project" \
--threshold-rule=percent=0.5 \
--threshold-rule=percent=0.9 \
--threshold-rule=percent=1.0 \
--threshold-rule=percent=1.0,basis=forecasted-spend \
--notifications-rule-pubsub-topic="projects/my-project/topics/budget-alerts"
Programmatic cost control with Pub/Sub: building a real hard stop
The Pub/Sub option turns a passive budget into the trigger for automated action. When a threshold (or any data refresh) occurs, Cloud Billing publishes a JSON message to your topic. A subscriber — typically a Cloud Function — receives it and can do whatever you program: post to Slack, open a ticket, throttle a workload, or, in the strongest form, disable billing on the project to halt all paid services.
The message payload contains the fields you need to decide:
{
"budgetDisplayName": "Prod monthly budget",
"costAmount": 51230.55,
"budgetAmount": 50000.0,
"alertThresholdExceeded": 1.0,
"currencyCode": "INR"
}
A minimal hard-stop function reads the message, and when cost exceeds budget, calls the Cloud Billing API to unlink the project (which stops paid services):
import base64, json
from googleapiclient import discovery
PROJECT = "projects/my-prod-project"
def stop_billing(event, context):
data = json.loads(base64.b64decode(event["data"]).decode("utf-8"))
if data["costAmount"] <= data["budgetAmount"]:
return # under budget, do nothing
billing = discovery.build("cloudbilling", "v1")
# Setting billingAccountName to "" disables billing on the project
billing.projects().updateBillingInfo(
name=PROJECT, body={"billingAccountName": ""}
).execute()
Use the hard stop with care. Disabling billing stops production. It is appropriate for sandboxes, training accounts, demo projects and personal experiments — exactly the places a newcomer overspends. For production, prefer graceful automation (scale workloads down, alert on-call) over a guillotine. Always test the function on a throwaway project first.
This pattern — budget → Pub/Sub → Cloud Function → action — is the canonical “programmatic budget” architecture and a common exam and interview scenario. It is also the honest answer to “how do I set a hard spending cap on GCP?”: you build it; Google does not provide one out of the box.
Cost reports & the cost table: reading the bill
The console gives you two main lenses on spend, both under Billing.
Cost reports (Billing → Reports) is an interactive, charted view. Its power is in Group by and Filter:
- Group by: Service (Compute Engine, BigQuery…), SKU (the finest line item), Project, Folder/Organisation, and — critically — Label key. Grouping by label is how you answer “what did the
team:paymentsresources cost this month?”. - Filter: by time range, project, service, SKU, location/region, and credit type.
- Credits: toggle to view gross cost, net cost (after discounts), or break out specific credit types — so you can see the value your CUDs and SUDs deliver.
- Forecast: the report projects month-end spend, the same engine behind forecast budget alerts.
The cost table (Billing → Cost table) is the detailed, exportable breakdown — closer to an itemised invoice — letting you drill from service down to SKU and project, and download to CSV. Use reports for exploration and the cost table for reconciliation.
There is also a Pricing view (the price list for your account, including any negotiated/contract prices) and a Commitments view (your active CUDs and their utilisation/coverage). For deep, ad-hoc analysis beyond what the console offers, you graduate to BigQuery export — next.
Why labels are the heart of cost management
You will hear this in every FinOps conversation: you cannot manage what you cannot attribute. Spend rolls up the hierarchy automatically, but the questions that matter to a business cut across it — by team, environment, application, cost centre, customer. Labels (key/value pairs on resources and projects) are how you make those slices possible.
- Agree a label taxonomy early and enforce it: e.g.
env(prod/staging/dev),team,app,cost-centre,owner. - Apply labels on resources and on projects (project labels flow to all resources within for many services).
- Enforce labels with Organisation Policy (require certain label keys) and catch gaps in reports (group by a label and look for the “unlabelled” bucket).
- Labels are lower-case key/value strings with limits (up to 64 labels per resource; specific character rules) — design short, consistent keys.
A note on terminology: GCP also has tags (a separate, hierarchy-bound construct used mainly for IAM conditions and policy, not billing) — do not confuse them with labels, which are the billing/reporting mechanism. For cost attribution, you want labels.
Billing export to BigQuery: the analyst’s superpower
The console reports are excellent for the common questions, but eventually you will want to ask something they cannot answer — “show me daily egress cost by region for the payments team over the last 90 days, excluding credits”. That is what billing export to BigQuery is for: Cloud Billing writes your usage and cost data into a BigQuery dataset where you can query it with SQL, join it to your own data, and build dashboards (Looker Studio, etc.).
You enable export from Billing → Billing export → BigQuery export, choosing a project and dataset to receive the data. There are three export types, and knowing the difference is exam-worthy:
| Export type | What it contains | Granularity | When to use | Cost |
|---|---|---|---|---|
| Standard usage cost | Daily cost per service, SKU, project, label — the everyday spend data | Day-level rows | Almost all cost analysis and dashboards | BigQuery storage + query cost only |
| Detailed usage cost | Everything in standard plus resource-level detail (cost per individual resource, e.g. per VM) | Resource-level rows (much larger) | When you must attribute cost to a specific resource | More storage (bigger tables) |
| Pricing | Your account’s price list (SKU prices, including negotiated/contract rates and tiered pricing) | Per-SKU price rows | Estimating cost before you spend; modelling what-ifs | Minimal |
Important properties:
- Export is not retroactive — it begins from the day you enable it. Turn it on now, even on a personal account, so the history exists when you need it.
- The data lands in tables named like
gcp_billing_export_v1_<BILLING_ACCOUNT_ID>(standard) andgcp_billing_export_resource_v1_<...>(detailed). - Querying the export costs BigQuery money (bytes scanned / your reservation) — partition-aware queries keep that trivial.
A first query — total net cost by service this month:
SELECT
service.description AS service,
ROUND(SUM(cost) + SUM(IFNULL((SELECT SUM(c.amount)
FROM UNNEST(credits) c), 0)), 2) AS net_cost
FROM `my-project.billing_export.gcp_billing_export_v1_0X0X0X_0X0X0X_0X0X0X`
WHERE DATE(_PARTITIONTIME) >= DATE_TRUNC(CURRENT_DATE(), MONTH)
GROUP BY service
ORDER BY net_cost DESC;
Cost by a label (e.g. attribute spend to teams):
SELECT
(SELECT value FROM UNNEST(labels) WHERE key = 'team') AS team,
ROUND(SUM(cost), 2) AS gross_cost
FROM `my-project.billing_export.gcp_billing_export_v1_0X0X0X_0X0X0X_0X0X0X`
WHERE DATE(_PARTITIONTIME) >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
GROUP BY team
ORDER BY gross_cost DESC;
The cost column is the gross charge; credits (discounts, promotions, CUD/SUD) live in a repeated credits field you add back (as negative amounts) to get net cost — exactly the gross-vs-net distinction from the Core Concepts section, now in SQL.
Discounts: the full landscape
Google reduces your bill through several mechanisms. Some are automatic; some you opt into; one requires changing how you run workloads. Here is every one, with the trade-off.
| Discount | How you get it | Applies to | Typical saving | Commitment | The trade-off |
|---|---|---|---|---|---|
| Sustained-Use Discount (SUD) | Automatic — the more of a month a resource runs | Compute Engine (predefined N1/N2/N2D etc.), GKE nodes, sole-tenant | Up to ~20–30% (varies by family) | None | None — it just happens; you cannot “buy more” of it |
| Committed-Use Discount — spend-based | Opt in: commit to spend $X/hour for 1 or 3 years | Many services (Compute flexible, Cloud Run, Cloud SQL, GKE Autopilot, BigQuery editions, and more) | ~ up to 46% (varies) | 1 or 3 years | You pay the commitment even if you under-use it |
| Committed-Use Discount — resource-based | Opt in: commit to a specific amount of vCPU/RAM in a region for 1 or 3 years | Compute Engine (and a few others) | ~ up to 57% | 1 or 3 years | Locked to a machine family/region; idle commitment is wasted |
| Spot VMs (and Spot in GKE) | Choose “Spot” provisioning when creating the VM/node | Compute Engine, GKE | Up to ~60–91% off on-demand | None | Preemptible — Google can reclaim with ~30s notice; no SLA; only for fault-tolerant/batch work |
| Free Tier | Automatic within monthly limits | A list of services (small f1/e2-micro VM, GCS, Cloud Functions invocations, BigQuery 1 TB query + 10 GB storage, etc.) | The free allowance itself | None | Hard monthly caps; exceeding them is billed normally |
| $300 free trial credit | Automatic for new accounts | Almost everything, for 90 days | The $300 | None | Time- and amount-limited; converts to pay-as-you-go after |
A few clarifications newcomers need:
- SUD vs CUD. SUDs are automatic and free — you get them just by running steady workloads on the eligible (predefined N-family) machines. CUDs are a deal you sign for a bigger discount in exchange for a 1- or 3-year commitment. They can stack: a committed resource gets the CUD; on-demand usage above the commitment can still earn SUD.
- Spend-based vs resource-based CUDs. Spend-based commits to a dollar amount per hour and is flexible (it floats across machine families, regions, even multiple services for the flexible variant) — easier to use, slightly smaller discount. Resource-based commits to specific vCPU/RAM in a specific region — bigger discount but rigid; if you stop using that shape, the commitment is wasted. Choose spend-based when your usage is steady but its shape changes; resource-based when you know exactly what hardware you will run for years.
- Spot is not “cheap on-demand” — it is interruptible. Treat it as free compute that can vanish: perfect for batch processing, CI, rendering, fault-tolerant data jobs; never for a database or a single stateful service. (Spot replaced the older “preemptible VMs”; the key behavioural difference is Spot has no fixed 24-hour cap.)
- Free Tier ≠ free trial. The Free Tier is an always-on monthly allowance on specific services; the $300 trial is a one-off credit for new accounts. You can use both; once the trial ends, Free Tier continues.
The cost-attribution + commitment playbook. Label everything → measure steady-state usage from the BigQuery export → cover the predictable baseline with CUDs (spend-based for flexibility) → let SUDs cover the rest of steady N-family usage automatically → run bursty, fault-tolerant work on Spot → keep experiments inside the Free Tier and the trial. That sequence is the heart of GCP FinOps and exactly what the cost-optimisation lesson expands on.
Quotas vs budgets: two different safety mechanisms
Beginners often ask “I set a budget — why did my workload not stop?” The answer is that budgets and quotas are different tools with different jobs.
| Budget | Quota | |
|---|---|---|
| Purpose | Financial awareness and (with automation) control | A technical limit on how much of a resource you can use |
| What it caps | Nothing by default — it alerts; can trigger automation | Hard cap: e.g. “max 24 vCPUs of N2 in asia-south1”, “max API requests/min” |
| Stops spend? | No (unless you build it) | Indirectly — you literally cannot create more of the resource |
| Set where | Billing → Budgets & alerts | IAM & Admin → Quotas (per service, per region) |
| Two kinds | n/a | Rate quotas (requests per minute) and allocation quotas (concurrent resources) |
| Good for | Cost visibility, forecasting, FinOps | Hard guardrails, blast-radius limits, preventing abuse |
In practice you use both: quotas to put a hard ceiling on how many expensive resources can ever exist (a genuine brake on runaway creation), and budgets to watch the money and notify or automate when spend trends wrong. A well-run project lowers quotas to sensible limits and sets budgets — belt and braces.
The diagram traces the whole money model: payment instruments feed a billing account, which links to many projects; IAM roles gate who can see or change spend; budgets watch cost and fan out to email, Monitoring and a Pub/Sub topic that drives automation; export to BigQuery powers analysis; and discounts (CUD/SUD/Spot/Free Tier) reduce the net cost at the bottom.
Hands-on lab: link, label, budget, export and query — all free
In this lab you will set up the core billing guardrails on a project using Cloud Shell (free, browser-based, gcloud pre-installed). Every step is free — you create no chargeable resources.
Prerequisites: a billing account where you have Billing Account Administrator (or Costs Manager for the budget steps), and at least one project. Open Cloud Shell from the console.
Step 1 — Identify your billing account and project
gcloud billing accounts list
# Note the ACCOUNT_ID (looks like 0X0X0X-0X0X0X-0X0X0X)
export BILLING_ID="0X0X0X-0X0X0X-0X0X0X" # paste yours
export PROJECT_ID="$(gcloud config get-value project)"
echo "Project: $PROJECT_ID Billing: $BILLING_ID"
Step 2 — Confirm the project’s billing link
gcloud billing projects describe "$PROJECT_ID"
# billingEnabled: true → linked and able to use paid services
If billingEnabled is false, link it (needs Billing Account User + Project Billing Manager):
gcloud billing projects link "$PROJECT_ID" --billing-account="$BILLING_ID"
Step 3 — Add a label for cost attribution
# Label the project so its spend can be sliced by team/env in reports
gcloud projects update "$PROJECT_ID" \
--update-labels=env=lab,team=learning,cost-centre=training
# Verify
gcloud projects describe "$PROJECT_ID" --format="value(labels)"
Step 4 — Create a budget with actual and forecast alerts
gcloud billing budgets create \
--billing-account="$BILLING_ID" \
--display-name="Lab budget" \
--budget-amount=200INR \
--filter-projects="projects/$PROJECT_ID" \
--threshold-rule=percent=0.5 \
--threshold-rule=percent=0.9 \
--threshold-rule=percent=1.0 \
--threshold-rule=percent=1.0,basis=forecasted-spend
# List your budgets
gcloud billing budgets list --billing-account="$BILLING_ID"
(Adjust the amount/currency to your account. If your CLI rejects the currency suffix, set the amount in the console instead — Billing → Budgets & alerts.)
Step 5 — Enable BigQuery billing export
Export is a console action (there is no gcloud billing export enable command):
- Go to Billing → Billing export → BigQuery export.
- Under Standard usage cost, click Edit settings, choose your project and a dataset (create one named
billing_exportif needed), and Save. - Optionally enable Detailed usage cost and Pricing the same way.
Export starts now, not retroactively — that is exactly why we turn it on early. Data appears within a few hours to a day.
Step 6 — (After data lands) query your spend
Once the export table exists (give it a day on a low-usage account):
bq query --use_legacy_sql=false '
SELECT service.description AS service, ROUND(SUM(cost),2) AS gross_cost
FROM `'"$PROJECT_ID"'.billing_export.gcp_billing_export_v1_'"${BILLING_ID//-/_}"'`
WHERE DATE(_PARTITIONTIME) >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
GROUP BY service ORDER BY gross_cost DESC'
Validation
gcloud billing projects describe "$PROJECT_ID"showsbillingEnabled: true.gcloud projects describeshows your three labels.gcloud billing budgets listshows Lab budget.- The BigQuery export dataset shows a
gcp_billing_export_v1_*table (after data lands).
Cleanup
# Delete the lab budget (replace with the ID from `budgets list`)
gcloud billing budgets delete BUDGET_ID --billing-account="$BILLING_ID"
# Remove the lab labels (optional)
gcloud projects update "$PROJECT_ID" \
--remove-labels=env,team,cost-centre
To stop BigQuery export, return to Billing → Billing export and disable it; delete the billing_export dataset if you created it solely for this lab.
Cost note: every step is free. Listing accounts, linking billing, labelling a project, creating a budget and enabling export incur no charge. The only thing that ever costs money here is querying the export table in BigQuery — and a single month of a low-usage account scans kilobytes, which falls inside the BigQuery free tier. You created no VMs, buckets or databases, so there is nothing left billing.
Common mistakes & troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| “I set a budget but spend went over and nothing stopped” | A budget only alerts by default | Build a Pub/Sub → Cloud Function hard stop, or lower quotas for a real cap |
| “Can’t link my project — permission denied” | You have only one side of the link | Grant Billing Account User and Project Billing Manager |
| “Resources suddenly stopped / APIs return billing errors” | Billing account suspended (payment failure) or someone unlinked the project | Fix the payment method; relink the project (gcloud billing projects link) |
| “BigQuery export has no data for last month” | Export is not retroactive; it starts when enabled | Enable it now; you cannot recover history before enablement |
| “Reports don’t show cost by team” | Resources/projects are unlabelled | Apply a label taxonomy; enforce with Org Policy; re-group the report |
| “My discount didn’t apply” | Wrong mechanism for the workload — e.g. expecting SUD on a custom/E-series machine, or a CUD shape you no longer run | Check eligibility (SUD = predefined N-family; match CUD region/family); view Commitments for utilisation |
| “Can’t change my billing account’s currency” | Currency/country are immutable at creation | Create a new billing account in the desired currency and relink projects |
| “Closing the billing account deleted my work” | Closing a billing account disables and can delete funded resources | Relink projects to another account before closing; treat closure as destructive |
Best practices
- Set a budget on day one for every billing account and per major project — it is free and the single best habit.
- Add forecast-based alerts, not just actual — they warn you mid-month while you can still act.
- Enable BigQuery export immediately (standard at minimum) so the history exists when finance asks.
- Adopt a label taxonomy early (
env,team,app,cost-centre,owner) and enforce it with Organisation Policy; chase down the “unlabelled” bucket in reports. - Lower quotas to sensible ceilings as a hard brake against runaway creation, complementing budgets’ financial alerts.
- Separate billing IAM from project IAM — grant Viewer/Costs Manager to FinOps, keep Admin tight, and never hand out Admin when User or Costs Manager will do.
- Cover the predictable baseline with CUDs, let SUDs handle the rest automatically, run bursty fault-tolerant work on Spot, and keep experiments inside the Free Tier.
- Review the cost report weekly and the Commitments view monthly (CUD utilisation under ~100% is money wasted).
- Act on Recommender (Active Assist) idle-resource and CUD recommendations.
Security notes
Billing data is sensitive — it reveals architecture, scale and business activity — so treat access to it with the same care as any other privileged data.
- Least privilege on billing roles. Grant Billing Account Viewer for read-only insight and Costs Manager for budget/export management; reserve Billing Account Administrator (and Creator at the org) for a small, audited group. The payment instrument is reachable only by payment-capable roles — keep that list tiny.
- The two-sided link is a security control, not just a chore: it stops a project owner from unilaterally spending the organisation’s money and stops a billing admin from reaching into projects they have no rights to. Preserve that separation.
- Protect the Pub/Sub automation path. A function that can disable billing (i.e. take down production) is highly privileged — give it a dedicated service account with only
billing.resourceAssociations/updateBillingInforights on the target projects, restrict who can publish to the budget topic, and review its code as you would any kill-switch. - Lock down the export dataset. BigQuery billing export contains your entire cost picture — apply dataset-level IAM so only FinOps and finance can query it.
- Audit billing changes. Cloud Audit Logs record billing-account IAM changes, project link/unlink and budget edits — monitor them; an unexpected unlink or a new Admin binding is worth an alert.
Interview & exam questions
1. What is the difference between a Cloud Billing account and a project, and how do they relate? A billing account holds the payment method and pays the bills; a project contains resources. A project must be linked to exactly one billing account to incur charges; one billing account can pay for many projects (many-to-one). Resources cost money, projects contain resources, and the linked billing account pays.
2. Self-serve vs invoiced billing — when would you choose each? Self-serve uses a card and is instant — for individuals and small teams. Invoiced bills monthly with payment terms (net 30) and needs a sales process and credit check — for enterprises and anyone needing PO/invoice workflows. The type is fixed at creation.
3. Two people both have access, yet neither can link a project to the billing account. Why? Linking requires power on both sides: Billing Account User on the billing account and Project Billing Manager (or Owner) on the project. If each person holds only one of the two, the operation fails. Grant both.
4. Does a budget stop spending? How would you implement an actual hard cap? No — a budget only alerts by default. For a hard cap you connect the budget to a Pub/Sub topic, subscribe a Cloud Function, and have it disable billing on the project (or scale workloads down) when cost exceeds the amount. Quotas provide a complementary technical cap on resource creation.
5. Explain the difference between a budget and a quota. A budget is a financial alarm (and, with automation, control) — it watches money and notifies. A quota is a technical limit on how much of a resource you can use (vCPUs in a region, API requests/minute) and genuinely prevents creation beyond the cap. Use both together.
6. What are the three BigQuery billing export types and when do you use each? Standard usage cost — daily cost by service/SKU/project/label (most analysis). Detailed usage cost — adds per-resource rows (attribute cost to a specific VM) at the price of much larger tables. Pricing — your SKU price list (estimating before you spend). Export is not retroactive.
7. SUD vs CUD — what’s the difference, and can they combine? Sustained-Use Discounts are automatic and free for steady usage of predefined N-family machines. Committed-Use Discounts are a 1- or 3-year commitment for a larger discount. They can combine: committed usage gets the CUD; on-demand usage above the commitment can still earn SUD.
8. Spend-based vs resource-based CUDs? Spend-based commits to a dollar amount per hour and is flexible across families/regions (and services, for the flexible variant) — smaller discount, easier to use. Resource-based commits to specific vCPU/RAM in a specific region — bigger discount but rigid; idle commitment is wasted. Choose spend-based for steady-but-changing usage, resource-based when you know the exact hardware for years.
9. What are Spot VMs and when must you never use them? Spot VMs are deeply discounted (~60–91% off) but preemptible — Google can reclaim them with ~30 seconds’ notice and they carry no SLA. Use them for fault-tolerant, restartable work (batch, CI, rendering); never for databases or single stateful services that cannot tolerate sudden termination.
10. Why are labels described as the heart of cost management? Spend rolls up the hierarchy automatically, but business questions cut across it — by team, environment, app, cost centre. Labels make those slices possible in reports and in BigQuery export. Without them you cannot attribute spend, and you cannot manage what you cannot attribute.
11. What is a billing sub-account and who uses it? A sub-account is a billing account whose charges roll up to a parent (master) account — used by resellers (a sub-account per end customer, billed separately, settled as one invoice with Google) and large orgs needing per-unit billing under one master. It requires the invoiced model and is created via the Cloud Billing API.
12. The Billing Account Costs Manager role — what can it do that Viewer cannot, and what can it not do? Costs Manager can additionally create/edit budgets and exports (Viewer is read-only). It still cannot manage the payment instrument or link projects — those need Administrator and the project-side role respectively. It is the right role for a FinOps owner who sets guardrails but should not touch the company card.
Quick check
- Which object actually holds the payment method and pays the bill — a project or a billing account?
- True or false: a budget will automatically stop your spending when it reaches 100%.
- Which two IAM roles, together, are required to link a project to a billing account?
- Name the three BigQuery billing export types.
- Which discount is automatic for steady use of predefined N-family VMs and requires no commitment?
Answers
- The billing account holds the payment method and pays; the project just contains resources and must be linked to a billing account.
- False. A budget only alerts by default; a hard stop must be built (e.g. Pub/Sub → Cloud Function → disable billing) or approximated with quotas.
- Billing Account User (on the billing account) and Project Billing Manager (on the project) — the two-sided link.
- Standard usage cost, detailed usage cost, and pricing.
- The Sustained-Use Discount (SUD).
Exercise
On a personal or sandbox project, build an automated cost guardrail end to end and document it:
- Create a Pub/Sub topic
budget-alertsand a budget scoped to the project that publishes to it, with actual thresholds at 50/90/100% and a forecast alert at 100%. - Deploy a Cloud Function subscribed to the topic that, on a threshold message, posts the cost/budget figures somewhere visible (log, Slack, or email). (Optional, sandbox-only: extend it to disable billing above 100% and test that paid services stop.)
- Enable BigQuery standard export, wait for data, and write a query that returns net cost by service for the project this month (remember to add back the
creditsarray). - Add an
env/teamlabel to the project and a second query that breaks spend down by that label. - Write a short note answering: what is the difference between this guardrail and a quota, and which would you rely on to prevent a runaway $10,000 bill from someone fat-fingering a 1,000-VM deployment? (Answer: the quota — it caps creation; the budget/automation reacts after spend, with a delay.)
Certification mapping
- Cloud Digital Leader (CDL): Cost management is squarely examinable — the billing account model, self-serve vs invoiced, budgets and alerts, the value of labels for attribution, the discount types (SUD, CUD, Spot, Free Tier), and the Free Tier vs $300 trial distinction all appear in the Digital transformation and Infrastructure & application modernisation domains. This lesson covers the cost portions of CDL end to end.
- Associate Cloud Engineer (ACE): Setting up a cloud solution environment tests linking billing accounts to projects, the two-sided permission, creating budgets and alerts (including Pub/Sub programmatic notifications), managing billing IAM roles, and enabling/querying BigQuery export — all hands-on skills you practised in the lab.
Glossary
- Cloud Billing account — the top-level object that holds a payment method and pays for usage; linked to projects.
- Project — the container for resources; must be linked to one billing account to incur charges.
- Self-serve account — card-paid, instant billing account for individuals/small teams.
- Invoiced account — monthly-invoice billing account with payment terms, for enterprises.
- Sub-account — a billing account whose charges roll up to a master account; used by resellers/large orgs.
- Link / billingEnabled — the connection between a project and its billing account; without it, paid services are blocked.
- Billing Account Administrator / User / Viewer / Costs Manager / Creator — the billing-account IAM roles (full control / link projects / read costs / manage budgets & exports / create accounts).
- Project Billing Manager — the project-side role needed (with Billing Account User) to link a project.
- Budget — a spend amount with threshold alerts; an alarm, not a brake by default.
- Threshold (actual / forecasted) — the percentage of the budget at which an alert fires, measured on spend so far or projected month-end spend.
- Pub/Sub budget notification — a JSON message published on threshold/data updates, used to drive automation.
- Cost report / cost table — the console views for exploring (grouped/filtered) and reconciling (itemised) spend.
- Label — a key/value tag on resources/projects, the primary mechanism for cost attribution.
- Billing export to BigQuery — writing usage/cost (standard, detailed) and pricing data to BigQuery for SQL analysis; not retroactive.
- SKU — the finest-grained billable line item; every charge maps to a SKU and a service.
- Gross vs net cost — charge before discounts (gross) vs after credits/discounts (net).
- Sustained-Use Discount (SUD) — automatic discount for steady use of predefined N-family compute.
- Committed-Use Discount (CUD) — 1- or 3-year commitment for a larger discount; spend-based (flexible $/hour) or resource-based (specific vCPU/RAM/region).
- Spot VM — deeply discounted but preemptible compute with no SLA; for fault-tolerant work only.
- Free Tier — always-on monthly free allowance on specific services; distinct from the one-off $300 trial.
- Quota — a technical cap on resource usage (rate or allocation); a real brake on creation, complementing budgets.
Next steps
- Google Cloud IAM, In Depth: Role Types, Policy Structure, Conditions, Inheritance & Recommender (
gcp-iam-deep-dive-roles-policies-conditions-recommender) — the next lesson: now that you control who can spend, master who can do what across the whole platform, including the Recommender that also surfaces cost waste. - GCP Cost Optimisation: The Architect’s Playbook — take the levers from this lesson (CUDs, SUDs, Spot, labels, export) and apply them to drive a real, expensive workload down to a predictable bill.
- Google Cloud Fundamentals: Resource Hierarchy, IAM and Pricing — revisit the hierarchy and pricing foundations that this billing deep-dive builds on.