# Billing export

> Turn on the Detailed usage cost export in Cloud Billing so LevelFour can analyze resource-level Google Cloud cost data.

Source: https://docs.levelfour.ai/connectors/gcp/billing-export


LevelFour reads your **Cloud Billing** data through the BigQuery billing export, the most detailed billing data Google Cloud produces. It breaks costs down to the individual resource, label, and SKU, and prices every recommendation against what you were billed rather than list rates.

Set it up once per Cloud Billing account, in the Cloud Billing console. Billing export is billing-account scoped, so a single export covers every project that pays through that billing account. You do not configure it per project.

> **Warning**
>
> Connect your projects first. Follow [Connect Google Cloud](/connectors/gcp) before this page. LevelFour reads costs only for projects you have already connected, so an export connected on its own produces no cost data.

> **Note**
>
> An organization connection ingests every connected project's costs from the export. A single-project connection ingests only that one project's costs, even though the export itself contains the whole billing account.

## What you enable

You enable the **Detailed usage cost export**: one row per SKU per resource per day, with resource-level detail and labels.

The export lands in a table named `gcp_billing_export_resource_v1_<BILLING_ACCOUNT_ID>` inside a BigQuery dataset you control.

> **Warning**
>
> Enable the **Detailed** export, not the Standard one. The Standard usage cost export drops the per-resource rows that LevelFour needs to attribute cost to individual resources. A Standard export connects, but it produces no savings recommendations and no realized savings.

Google Cloud offers two further exports on the same screen:

* **Committed Use Discounts.** Enable it if you hold committed use discounts and connected at the organization level. See [Committed Use Discounts export](/connectors/gcp/committed-use-discounts).
* **Pricing.** LevelFour reads it from the same dataset as the Detailed export. It holds your list rate for each SKU. Savings figures come from your bill, not from these rates.

## What it costs

The export itself is free. You pay only BigQuery storage for the export table: the first **10 GB per month is free**, and beyond that BigQuery active storage is about **$0.02 per GB per month**. LevelFour's queries run in LevelFour's own Google Cloud project, so the cost of reading the export is on LevelFour, not on you.

Costs in a non-USD billing account are converted to USD using the conversion rate Google includes in each export row. Everything you see in LevelFour is in USD.

## Prerequisites

* A finance or billing identity with **Billing Account Administrator** or **Costs Manager** on the Cloud Billing account you want to export.
* **BigQuery Admin** (or an equivalent) on the Google Cloud project that will hold the export dataset, so the console can create the dataset and the connect command can update its access list.

These are often different people from whoever connected your projects.

Billing-account IAM admin rights are useful but not required. Without them the connect command still grants LevelFour read access to your export dataset. It skips two optional billing-account roles and prints which ones.

## Set up the export

### Create a BigQuery dataset

In the project that will hold the export, create a BigQuery dataset (the Cloud Billing setup can also create one for you). A common name is `billing_export`. You cannot change the location later, so choose it now:

* Use a **US** or **EU** multi-region unless you have a specific data-residency requirement. Multi-region is the most broadly compatible location and matches how LevelFour reads the data.
* You cannot move a dataset after it is created, so if you pick the wrong location you have to make a new dataset and reconfigure the export.

Note which project holds this dataset. You need it when you run the connect command.

### Turn on the Detailed usage cost export

1. Open the **Cloud Billing** console and select the billing account you want to export.
2. Go to **Billing export**, then the **BigQuery export** tab.
3. Under **Detailed usage cost**, click **Edit settings**, choose the project and dataset from the previous step, and save.

> **Note**
>
> The Standard and Detailed tables can share a dataset. When both are there, the connect command picks the Detailed one.

### Wait for the first data

Google Cloud writes the first rows **24 to 48 hours** after you enable the export. When the export starts, it also backfills recent history, filling in **up to 5 days** of prior usage, so early cost views populate retroactively.

> **Note**
>
> Until the first load lands, the dataset exists but its tables are empty. That is expected.

### Connect the export to LevelFour

Open the **Connect Google Cloud** page in the dashboard and find the **Billing data (BigQuery export)** panel. Click **Generate billing connect command**, then **Copy**.

This is a different command from the one that connected your projects. Paste it as shown; there is nothing in it for you to fill in.

> **Warning**
>
> Run this from a Cloud Shell whose active project is the project that holds your export dataset. The script searches that project only. Set it first:
>
> ```bash
> gcloud config set project YOUR_EXPORT_PROJECT_ID
> ```

The script needs `gcloud`, `bq`, and `python3`, all of which Cloud Shell provides. If your identity can see more than one billing account, the script lists them and asks `Which billing account?`. Type the number of the account whose export lives in this project. To choose up front instead, run `export LEVELFOUR_BILLING_ACCOUNT_ID=YOUR_BILLING_ACCOUNT_ID` before you paste the command. To connect several billing accounts, run the command once for each.

The script then finds that account's export table and prints its name. A name starting with `gcp_billing_export_resource_v1_` is the Detailed export. A name starting with `gcp_billing_export_v1_` means the script found only the Standard export, so stop and turn on the Detailed one first.

Then the script asks you two questions:

1. `Continue? [y/N]` before granting `roles/bigquery.dataViewer` on the export dataset to your service account. Answer `y`.
2. `Cap this export table to 92 days to minimize BigQuery storage cost? LevelFour keeps full history. [y/N]` Answer `y` to bound your BigQuery storage, or press Enter to leave your table's retention alone. LevelFour re-reads only the recent window and keeps full history in its own database, so capping loses you no analysis.

Anything other than `y` or `Y` counts as no. The dataset grant is already applied by the time the second question appears, so declining the cap does not undo the connection. To set the expiration yourself instead, see [Capping storage yourself](#capping-storage-yourself).

The script then tries to grant two optional read roles on the billing account itself, `roles/billing.viewer` and `roles/recommender.billingAccountCudViewer`. The first one also lets LevelFour read your budgets. Both need billing-account IAM admin. If you do not have it the script prints `Could not grant <role> (needs billing-account IAM admin); skipping.` and carries on.

Finally it reports the dataset and table back to LevelFour, which confirms the service account can read the export before marking it connected. The command stays valid for 30 days and is safe to re-run.

## Capping storage yourself

If you would rather set the partition expiration before you connect, or your finance team manages BigQuery retention centrally, run it yourself once the table exists:

```bash
bq update --time_partitioning_expiration 7948800 \
  YOUR_PROJECT_ID:billing_export.gcp_billing_export_resource_v1_YOUR_BILLING_ACCOUNT_ID
```

`7948800` seconds is 92 days.

## Confirming it worked

Open **Connect Providers > Google Cloud** in the dashboard. The **Billing data (BigQuery export)** panel summarizes which billing accounts are connected.

> **Success**
>
> Within about two days of enabling the export, your billing account shows as connected and resource-level cost breakdowns appear in your cost views.

## Export status reference

The **Billing data**, **Committed Use Discounts**, and **Pricing** panels all use the same status labels:

| Status            | Meaning                                                                                     |
| ----------------- | ------------------------------------------------------------------------------------------- |
| Not connected yet | LevelFour has no access to this export. Run the connect command, or enable the export first |
| Setting up        | LevelFour has access and is waiting for the first data to land                              |
| Connected         | LevelFour is reading the export. The panel shows when it last synced                        |
| Action needed     | Something on your side is blocking the read, usually a missing grant or a missing export    |
| Sync error        | The last read failed. The panel shows the reason Google Cloud returned                      |

If you have several billing accounts, the panel shows the least-ready status across all of them, so a partially connected setup never reads as fully connected.

## Removing access

Remove the dataset access entry and the two billing-account roles. Use the address the connect script printed; see [Finding your service-account address](/connectors/gcp#finding-your-service-account-address) if you no longer have it.

To drop the dataset read grant, save the dataset's access list:

```bash
bq show --format=prettyjson YOUR_PROJECT_ID:billing_export > policy.json
```

Remove the entry whose `"userByEmail"` is the service-account address from `policy.json`, then write the list back:

```bash
bq update --source policy.json YOUR_PROJECT_ID:billing_export
```

Then drop the billing-account roles, if they were granted:

```bash
SA="PASTE_THE_ADDRESS_THE_SCRIPT_PRINTED"

for ROLE in roles/billing.viewer roles/recommender.billingAccountCudViewer; do
  gcloud billing accounts remove-iam-policy-binding YOUR_BILLING_ACCOUNT_ID \
    --member="serviceAccount:$SA" --role="$ROLE"
done
```

To also remove the project and organization roles, see [Removing access](/connectors/gcp#removing-access).

## Troubleshooting

### No BigQuery billing export for billing account

`No BigQuery billing export for billing account <ID> in project <PROJECT>.`

Either the export is not on yet, its first data has not landed yet, your Cloud Shell is pointed at a different project than the one holding the dataset, or you picked a billing account that exports somewhere else. Run `gcloud config set project YOUR_EXPORT_PROJECT_ID`, run the command again, and pick the billing account that exports into that project.

### No billing account is visible to your gcloud identity

The identity running the command cannot see any billing account. Run `gcloud billing accounts list` to confirm, and use an identity with **Billing Account Administrator** or **Costs Manager**.

### bq (the BigQuery CLI) is required

`bq (the BigQuery CLI) is required. Open this in a Cloud Shell.`

Run the command in Cloud Shell, which ships `gcloud`, `bq`, and `python3`.

### The script stops on a bq error and the panel stays at Not connected yet

A failed read or update on the dataset stops the script before it reports back, so LevelFour never hears about the connection. Confirm you have **BigQuery Admin** on the project holding the dataset, then re-run.

### The dataset tables are still empty after two days

Confirm the Detailed usage cost export is enabled on the correct billing account, that the dataset is in a US or EU multi-region, and that the billing service has write access to the dataset. The first export can take the full 24 to 48 hours.

### You get a permission error when enabling the export

You need **Billing Account Administrator** or **Costs Manager** on the billing account, and **BigQuery Admin** on the project that holds the dataset. Have whoever owns billing complete this step.

### The panel shows Connected, but there are no savings recommendations

Check that you enabled the **Detailed** export, not the Standard one. Only the Detailed export carries the per-resource rows LevelFour needs.

If you connected the Standard export, turn on the Detailed one, wait for its first rows, then run the connect command again. LevelFour switches to the Detailed table.

### The command fails on the IAM binding

If your organization enforces **Domain Restricted Sharing** (`iam.allowedPolicyMemberDomains`), the policy blocks the grant until you allowlist LevelFour's Cloud Identity customer ID. See the Domain Restricted Sharing note in [Connect Google Cloud](/connectors/gcp#run-the-connect-command-in-cloud-shell).

## Next

* [Committed use discounts](/connectors/gcp/committed-use-discounts) is the second export, which fills in commitment term, dates and status
* [Costs](/resources/costs) is how the ingested cost data comes back over the API
