GCP Billing and Pricing

Why This Matters

Cloud Billing problems are usually not invoice problems first. They start as missing linkage, missing exports, missing attribution, or missing price interpretation. In bq-wh-nb, the billing link is healthy, but the export and attribution layers are incomplete. That means operators can estimate cost drivers and inspect public prices, but they cannot yet do invoice-grade reconciliation, amortized commitment analysis, or budget enforcement from BigQuery.

Conceptual Model

The billing account is healthy, but the export layer below it is still missing. That distinction matters because many teams wrongly treat “billing enabled” as equivalent to “FinOps ready.”


flowchart TD
    BA["Billing Account<br>0190CF-C61D5A-F08831<br>Agents Billing Account"] --> P["Project<br>bq-wh-nb"]
    P --> R["Resources<br>Compute Engine · BigQuery · Cloud Run · GCS"]
    BA --> E1["Standard usage export<br>not configured"]
    BA --> E2["Detailed usage export<br>not configured"]
    BA --> E3["Pricing export<br>not configured"]
    BA --> E4["CUD metadata export<br>not configured"]
    R --> Q["Current fallback surfaces<br>gcloud inventories · Pricing API · INFORMATION_SCHEMA"]

Archived Billing Topology

The archived billing topology is simple: one open billing account, one active linked project, and one identity with roles/billing.admin on the billing account.

Archived scope

  • Billing account billingAccounts/0190CF-C61D5A-F08831 is open and denominated in CZK.
  • Project bq-wh-nb is linked to that account and billingEnabled is true.
  • The current billing-account IAM policy exposes one explicit binding: roles/billing.admin for user:alexper.recovery@gmail.com.

PowerShell / Linux | gcloud | inspect billing account linkage

Use these commands to prove that a project can spend money and to confirm who can manage the financial control plane.

List accessible billing accounts

Run this before any budget, export, or billing-link change. It is typically triggered by use it during initial billing validation or when an operator is unsure which account funds the project. Run from any authenticated shell with gcloud configured. This is read-only. Establish the canonical billing account ID, display name, and account status.

FieldSource columnUnit / typeMeaning
nameCloud Billing account resource nameSTRINGImmutable account identifier used by APIs and gcloud.
displayNameBilling account metadataSTRINGHuman-readable account name shown in the console.
currencyCodeBilling account metadataSTRINGCurrency used for account pricing and invoices.
openBilling account metadataBOOLEANWhether the account is active for new charges.

This command returns the billing accounts visible to the active identity as JSON so the exact account IDs can be reused safely in later workflows.

gcloud billing accounts list --format=json
[
  {
    "currencyCode": "CZK",
    "displayName": "Agents Billing Account",
    "masterBillingAccount": "",
    "name": "billingAccounts/0190CF-C61D5A-F08831",
    "open": true
  },
  {
    "currencyCode": "CZK",
    "displayName": "My Billing Account",
    "masterBillingAccount": "",
    "name": "billingAccounts/01E212-1C5E05-99306D",
    "open": false
  }
]

The important result is not just the ID. It is that only one visible account is currently open, which removes ambiguity about where bq-wh-nb should be linked.

Run this before enabling paid APIs, creating exports, or investigating “billing disabled” service failures. It is typically triggered by use it whenever a project is new, recently moved, or suspected to be linked to the wrong payer. This is a read-only gcloud billing lookup against one project. Confirm that the project is linked to the expected billing account and that billing is enabled.

FieldSource columnUnit / typeMeaning
billingAccountNameProject billing infoSTRINGBilling account attached to the project.
billingEnabledProject billing infoBOOLEANWhether the project can accrue paid usage.
nameBilling info resource nameSTRINGAPI resource for the project billing record.

This command returns the archived billing linkage for bq-wh-nb.

gcloud billing projects describe bq-wh-nb --format=json
{
  "billingAccountName": "billingAccounts/0190CF-C61D5A-F08831",
  "billingEnabled": true,
  "name": "projects/bq-wh-nb/billingInfo",
  "projectId": "bq-wh-nb"
}

This is the minimum condition for paid services to work, but it says nothing about exports, budgets, or cost attribution maturity.

Inspect billing-account IAM

Run this before any export, budget, or account-level billing change that requires billing-account permissions. It is typically triggered by use it when a command fails with PERMISSION_DENIED and you need to separate missing IAM from missing API enablement. This reads the billing-account IAM policy. It requires access to read billing IAM. Verify which principals can administer billing-account resources.

FieldSource columnUnit / typeMeaning
roleIAM bindingSTRINGBilling-account role granted by the binding.
membersIAM bindingARRAYPrincipals that hold the role.

This command returns the billing-account IAM policy as JSON.

gcloud billing accounts get-iam-policy 0190CF-C61D5A-F08831 --format=json
{
  "bindings": [
    {
      "members": [
        "user:alexper.recovery@gmail.com"
      ],
      "role": "roles/billing.admin"
    }
  ],
  "etag": "BwY..."
}

The key operational takeaway is that the active user has billing-admin rights, so the current missing export state is not caused by obvious account-level IAM loss.

FlagSyntaxDescription
--format--format=jsonReturns machine-readable output so account IDs and policy fields can be captured exactly.

PowerShell / Linux | BigQuery / gcloud | verify export readiness and commitment state

Billing exports and commitment metadata do not appear automatically just because a project has BigQuery enabled. This section proves what is and is not present today.

List datasets in the active project

Run this before assuming billing export tables exist. It is typically triggered by use it when a note, query, or dashboard references gcp_billing_export_* and you need to verify the dataset first. This is a read-only BigQuery metadata listing in the active project. Confirm whether a billing-export dataset, pricing export, or CUD metadata export already exists.

FieldSource columnUnit / typeMeaning
kindBigQuery dataset metadataSTRINGReturned resource type.
idBigQuery dataset metadataSTRINGFully qualified dataset identifier.
locationBigQuery dataset metadataSTRINGDataset location, which matters for export backfill behavior.

This command lists all datasets visible in bq-wh-nb.

bq ls --format=prettyjson
[
  {
    "kind": "bigquery#dataset",
    "id": "bq-wh-nb:stoxx_bronze",
    "location": "europe-west1"
  },
  {
    "kind": "bigquery#dataset",
    "id": "bq-wh-nb:stoxx_silver",
    "location": "europe-west1"
  },
  {
    "kind": "bigquery#dataset",
    "id": "bq-wh-nb:stoxx_gold",
    "location": "europe-west1"
  }
]

There is no billing-export dataset here. That means there was no gcp_billing_export_v1_*, detailed usage table, pricing export table, or CUD metadata table to query in this project state.

Check for Compute Engine commitments

Run this before attributing savings to commitments or writing about effective VM pricing. It is typically triggered by use it when planning rightsizing or when cost analysis assumes committed-use discounts exist. This is a read-only inventory query against Compute Engine commitments. Confirm whether resource-based commitments are active in the project.

FieldSource columnUnit / typeMeaning
JSON array lengthCommand resultINTEGERNumber of commitments returned by the project inventory.

This command checks for Compute Engine commitments in the archived project.

gcloud compute commitments list --format=json
[]

The empty result means there are no visible Compute Engine commitments in bq-wh-nb, so list-price VM math should not be presented as amortized or commitment-backed math.

Check for BigQuery capacity commitments

Run this before discussing BigQuery editions, slot commitments, or reservation-backed spend. It is typically triggered by use it when a warehouse-heavy TCO model assumes dedicated slot capacity. This is a read-only BigQuery reservation inventory lookup in europe-west1. Confirm whether the project has any active capacity commitments for BigQuery.

FieldSource columnUnit / typeMeaning
Command status textbq CLI resultSTRINGHuman-readable summary of whether commitments exist in the selected location.

This command checks for BigQuery capacity commitments in the project region.

bq ls --capacity_commitment --location=europe-west1 --format=prettyjson
No capacity commitments found.

This confirms that the current BigQuery posture is on-demand rather than reservation-backed.

FlagSyntaxDescription
--format--format=prettyjsonReturns structured BigQuery metadata.
--capacity_commitmentbq ls --capacity_commitmentSwitches the listing surface from datasets to BigQuery commitments.
--location--location=europe-west1Restricts the lookup to the region where current datasets live.

PowerShell | Cloud Billing Catalog API | query current list prices

The Pricing API is the list-price source when billing export is absent. It does not tell you what you were billed. It tells you what the public rate sheet says for a given SKU and region.

Query Compute Engine and disk list prices for europe-west1

Run this when you need a current public rate for a SKU that actually exists in the environment. It is typically triggered by use it during TCO modeling, rightsizing, or when a stale price table would be unsafe. This is a read-only REST call against the Cloud Billing Catalog API using an access token from the active gcloud identity. Retrieve public list prices for E2 core and RAM time plus the persistent disk types used by the current VMs.

FieldSource columnUnit / typeMeaning
descriptionSKU metadataSTRINGHuman-readable description of the SKU.
serviceRegionsSKU metadataARRAYRegions where the SKU applies.
tieredRatesPricing expressionARRAY / OBJECTPrice tiers for the SKU.
effectiveTimePricing metadataTIMESTAMPWhen the returned price becomes effective.

This PowerShell pipeline fetches the Compute Engine SKU catalog in CZK, filters it to the active region, and returns only the core, RAM, disk, and snapshot entries that matter for the archived project inventory.

$token = gcloud auth print-access-token
$headers = @{ Authorization = "Bearer $token" }
$service = "6F81-5844-456A"
$pageToken = $null
$skus = @()
 
do {
  $url = "https://cloudbilling.googleapis.com/v1/services/$service/skus?pageSize=5000&currencyCode=CZK"
  if ($pageToken) { $url += "&pageToken=$pageToken" }
  $response = Invoke-RestMethod -Headers $headers -Uri $url
  $skus += $response.skus
  $pageToken = $response.nextPageToken
} while ($pageToken)
 
$skus |
  Where-Object {
    ($_.serviceRegions -contains "europe-west1") -and (
      $_.description -eq "E2 Instance Core running in EMEA" -or
      $_.description -eq "E2 Instance Ram running in EMEA" -or
      $_.description -eq "Balanced PD Capacity" -or
      $_.description -eq "SSD backed PD Capacity" -or
      $_.description -eq "Storage PD Snapshot"
    )
  } |
  Select-Object description, serviceRegions,
    @{n="tieredRates";e={$_.pricingInfo[0].pricingExpression.tieredRates}},
    @{n="effectiveTime";e={$_.pricingInfo[0].effectiveTime}} |
  ConvertTo-Json -Depth 8
[
  {
    "description": "E2 Instance Core running in EMEA",
    "serviceRegions": ["europe-west1"],
    "tieredRates": {
      "startUsageAmount": 0,
      "unitPrice": { "currencyCode": "CZK", "units": "0", "nanos": 509871109 }
    },
    "effectiveTime": "2026-04-13T07:00:00Z"
  },
  {
    "description": "E2 Instance Ram running in EMEA",
    "serviceRegions": ["europe-west1"],
    "tieredRates": {
      "startUsageAmount": 0,
      "unitPrice": { "currencyCode": "CZK", "units": "0", "nanos": 68343520 }
    },
    "effectiveTime": "2026-04-13T07:00:00Z"
  },
  {
    "description": "Balanced PD Capacity",
    "serviceRegions": ["us-central1", "us-central2", "us-east1", "us-west1", "asia-east1", "europe-west1"],
    "tieredRates": {
      "startUsageAmount": 0,
      "unitPrice": { "currencyCode": "CZK", "units": "2", "nanos": 125050000 }
    },
    "effectiveTime": "2026-04-13T07:00:00Z"
  }
]

These values are public list prices. They are suitable for forward modeling, but they are still not effective cost because they exclude credits, free tiers, and any future commitments.

Query BigQuery analysis and storage price tiers for europe-west1

Run this when you need current query or storage list prices for BigQuery in the project region. It is typically triggered by use it during TCO work or when validating whether current BigQuery usage is still inside the free tier. This is a read-only Pricing API lookup against the BigQuery service catalog. Retrieve the current analysis and storage tiers that apply to on-demand BigQuery usage in europe-west1.

FieldSource columnUnit / typeMeaning
descriptionSKU metadataSTRINGBigQuery cost dimension represented by the SKU.
tieredRates.startUsageAmountPricing expressionNUMERICUsage threshold where a tier starts.
tieredRates.unitPricePricing expressionMONEYPublic rate at that tier.
displayQuantityPricing expressionNUMERICDisplay quantity used for the returned unit.

This PowerShell pipeline pulls the relevant BigQuery SKUs for analysis and storage in europe-west1.

$token = gcloud auth print-access-token
$headers = @{ Authorization = "Bearer $token" }
$service = "24E6-581D-38E5"
$pageToken = $null
$skus = @()
 
do {
  $url = "https://cloudbilling.googleapis.com/v1/services/$service/skus?pageSize=5000&currencyCode=CZK"
  if ($pageToken) { $url += "&pageToken=$pageToken" }
  $response = Invoke-RestMethod -Headers $headers -Uri $url
  $skus += $response.skus
  $pageToken = $response.nextPageToken
} while ($pageToken)
 
$skus |
  Where-Object {
    ($_.serviceRegions -contains "europe-west1") -and (
      $_.description -eq "Analysis (europe-west1)" -or
      $_.description -eq "Active Logical Storage (europe-west1)" -or
      $_.description -eq "Long Term Logical Storage (europe-west1)"
    )
  } |
  Select-Object description, serviceRegions,
    @{n="tieredRates";e={$_.pricingInfo[0].pricingExpression.tieredRates}},
    @{n="displayQuantity";e={$_.pricingInfo[0].pricingExpression.displayQuantity}},
    @{n="effectiveTime";e={$_.pricingInfo[0].effectiveTime}} |
  ConvertTo-Json -Depth 8
[
  {
    "description": "Analysis (europe-west1)",
    "serviceRegions": ["europe-west1"],
    "tieredRates": [
      {
        "startUsageAmount": 0,
        "unitPrice": { "currencyCode": "CZK", "units": "0", "nanos": 0 }
      },
      {
        "startUsageAmount": 1,
        "unitPrice": { "currencyCode": "CZK", "units": "159", "nanos": 378750000 }
      }
    ],
    "displayQuantity": 1,
    "effectiveTime": "2026-04-13T07:00:00Z"
  },
  {
    "description": "Active Logical Storage (europe-west1)",
    "serviceRegions": ["europe-west1"],
    "tieredRates": [
      {
        "startUsageAmount": 0,
        "unitPrice": { "currencyCode": "CZK", "units": "0", "nanos": 0 }
      },
      {
        "startUsageAmount": 10,
        "unitPrice": { "currencyCode": "CZK", "units": "0", "nanos": 425010000 }
      }
    ],
    "displayQuantity": 1,
    "effectiveTime": "2026-04-13T07:00:00Z"
  }
]

The tier data matters more than a copied price table. It shows that query spend is free until the first 1 TiB, and active logical storage is free until the first 10 GiB, after which public list pricing applies.

FlagSyntaxDescription
pageSize?pageSize=5000Pulls enough SKU rows to filter region and description locally.
currencyCode?currencyCode=CZKReturns prices in the same currency as the billing account.
ConvertTo-Json -Depth 8ConvertTo-Json -Depth 8Preserves tiered pricing arrays in the final output.

Export Types and Current State

Billing export maturity is not about one table. It is about which export family is enabled and what analytical questions each family can answer.

Export surfaceWhat it containsWhen you need itArchived state in removed projectOperational implication
Standard usage cost exportDaily usage cost rows by service, SKU, project, credits, and invoice monthBaseline spend trends, cost by service, project, or labelNot configuredThere is no invoice-grade cost history to query in BigQuery.
Detailed usage cost exportRicher usage rows with more resource attribution detailPer-resource drill-down, stronger reconciliation, and deeper attributionNot configuredResource-level cost analysis is blocked.
Pricing exportPublic list-price data in BigQueryInternal calculators and point-in-time price referencesNot configuredPrice analysis must use the Pricing API or the public price list instead.
CUD metadata exportCommitment subscription metadata and coverage contextCommitment utilization and amortization analysisNot configuredYou cannot do defensible CUD coverage analysis from BigQuery yet.

Billing Export Is Still Missing

bq-wh-nb has BigQuery enabled, but it does not have a Cloud Billing export dataset. Until that changes, this project cannot support invoice-grade cost trends, cost-by-label queries, or budget-validation SQL.

Enable Export With The Correct Dataset Strategy

  • If you want the first export to backfill current and previous month data, use a supported multi-region dataset (EU or US) on the first enablement.
  • If you create the export dataset in a supported region such as europe-west1, export starts from the enablement date forward and does not backfill earlier usage.
  • Do not manually insert rows into billing-export tables after export is enabled; Google can overwrite managed export tables.

Current product note: pricing and export nuances

Current Cloud Billing documentation distinguishes more clearly between usage export, pricing export, and the pricing table report. Pricing export data is generated daily, includes a pricing_as_of_time anchor, and pricing changes are not retroactively added to earlier days. Billing export datasets also still have operational constraints such as managed-table ownership and unsupported CMEK configurations.

Attribution and Pricing Interpretation

Archived inventory shows partial attribution maturity. Current Compute Engine instances carry labels such as app and env, but the BigQuery datasets stoxx_bronze, stoxx_silver, and stoxx_gold did not expose any labels field in their captured dataset metadata. That means cost ownership was stronger on VM inventory than on warehouse inventory.

Pricing interpretation also needs discipline:

  • List price is what the Pricing API returned in this note.
  • Effective price is what you actually pay after credits, discounts, taxes, and free-tier offsets.
  • Current project state shows no Compute Engine commitments and no BigQuery capacity commitments, so there is no evidence of commitment-backed pricing in bq-wh-nb.
  • Safe conclusion today: use archived list-price evidence plus current pricing docs for forward planning, but do not describe them as amortized, discounted, or invoice-accurate.

Current product note: list price versus effective price

Current Cloud Billing surfaces now make the separation between public list price and account-specific effective price more explicit. Use the Pricing API and pricing export when you need current public SKU math, but use billing export rows, price table reporting, and invoice data when the question is what the account actually paid after credits, commitments, or negotiated discounts.

Recommendations / Production Rules

  • Treat billing linkage, billing export, pricing export, and attribution as four separate maturity checks.
  • Never write cost SQL until you have proved the target billing-export dataset exists.
  • Use the Pricing API for current public rates when the chapter needs exact list pricing, especially in a non-USD billing account such as CZK.
  • Separate list-price estimates from effective-cost analysis in every note and dashboard.
  • Enable standard usage export before building budgets, anomaly queries, or chargeback logic; otherwise every downstream control plane becomes guesswork.
  • Label datasets, buckets, and long-lived compute resources consistently before month-end reconciliation matters.

Quick Reference

QuestionArchived answer
Which billing account funds bq-wh-nb?billingAccounts/0190CF-C61D5A-F08831 (Agents Billing Account)
Is billing enabled?Yes
What currency applies?CZK
Is Cloud Billing export configured in BigQuery?No
Are Compute Engine commitments present?No
Are BigQuery capacity commitments present?No
What should be used for current public prices?Cloud Billing Catalog API / Pricing API