You have a token count from your application and a figure from GCP billing, and they disagree. This is expected, and the gap is structural rather than a bug in either system.
Understanding what each source is actually measuring saves a lot of time trying to make them match.
What GCP billing actually reports
Vertex AI does not have its own billing console the way OpenAI or Anthropic do. It bills through GCP, which means Gemini and Vertex spend arrives in the same structure as Compute Engine and BigQuery.
The unit is the SKU. For generative models, billing separates input tokens from output tokens and reports each as its own line with a quantity and a cost. That is genuinely useful — it means the input/output split, which drives most of the cost asymmetry, is visible without instrumentation.
What billing does not carry is any notion of a request. There is no request count, no per-prompt breakdown, and no application context. A SKU line tells you a model consumed a number of tokens on a day, in a project, and what it cost.
Why the numbers will not match
Four structural differences account for almost every discrepancy.
Aggregation. Billing rolls up by SKU, project and day. Your application logs individual calls. Any comparison finer than a day is comparing different things.
Failed and retried calls. A request that errors after the model generated tokens is still billed. If your application logs completions rather than attempts, retries are invisible on your side and present on the invoice.
Rounding. Billing applies its own rounding at the SKU line. On high volumes this is immaterial; on low volumes it is a visible percentage.
Timing. Billing attributes usage to the day it was processed, which for calls near midnight or during a backlog may not be the day your application logged them.
Chasing exact reconciliation is not a good use of time. Agreement within a few percent over a month is the realistic target.
What billing cannot tell you
The important limitation is not precision, it is attribution.
GCP billing cannot tell you which feature generated the spend, which user or customer it belongs to, or which prompt was expensive. Those are application concerns, and the only place they exist is in your own logs.
This is the single biggest practical difference between running Gemini through Vertex and running OpenAI or Anthropic directly. The direct providers offer project or API-key level separation in their own consoles; Vertex inherits GCP's attribution model, which is project and label based.
If you need per-feature attribution, you have to build it: separate projects per major workload, or labels applied consistently, or application-side cost logging keyed to the same identifiers.
Getting the data out properly
Three routes, in increasing order of usefulness.
The billing console is fine for a total and a trend. Filter to the Vertex AI service and group by SKU.
Standard billing export to BigQuery gives you queryable service-level cost. Enable it before you need it — GCP does not backfill export, so history begins when you turn it on.
Detailed billing export adds resource-level attribution and is what you want for anything beyond totals. Same caveat: no backfill, so enabling it during an incident gives you nothing about the incident.
A common and expensive discovery is that detailed export was never enabled, at the exact moment someone needs to explain a spike.
Separate projects are the cheapest attribution you will get
If you take one thing from this: put materially different AI workloads in different GCP projects.
Billing is project-aware by default. Labels drift, application logging requires discipline, and both need maintenance. Project separation gives you attribution in the billing data itself, permanently, with no ongoing effort.
It is a decision that is nearly free at the start and expensive to retrofit once workloads are entangled.
Where a cost tool fits
Reconciliation is not really the problem worth solving. The problem is that Vertex spend sits inside a GCP bill alongside everything else, while your OpenAI and Anthropic spend sits in two other consoles with different structures — so nobody holds the combined AI number and nothing has a baseline.
StackSpend reads GCP billing with read-only access, isolates Vertex and Gemini SKUs, and normalises them alongside direct-provider spend so model cost is comparable across providers. It will not reconcile to your application's request count, because nothing can — but it will tell you the day Gemini spend deviates from its own baseline, which is the question that actually matters.
FAQ
Why doesn't my Vertex AI token count match the GCP bill?
Billing aggregates by SKU and day, includes failed and retried calls that generated tokens, and applies its own rounding. Application logs count completions. Expect agreement within a few percent over a month, not exact matching.
Can I see Gemini cost per project in GCP?
Yes. GCP billing is project-aware, so filtering Vertex AI spend by project works without extra configuration. This is the main reason to separate significant AI workloads into their own projects.
Does GCP billing show per-prompt cost?
No. The finest granularity is the SKU — input and output tokens per model per day. Per-prompt or per-feature cost has to come from application-side logging.
Should I enable detailed billing export?
Yes, and now rather than later. Detailed export gives resource-level attribution, and GCP does not backfill it — enabling it during an incident produces no data about that incident.


