,

Vertex AI Cost Governance and FinOps (Google Cloud Gen AI Series, Part 26)

Read a Vertex AI bill line by line, then cut it with model tiering, context caching, Batch mode, and provisioned throughput judged against a real break-even. With budgets, billing export, and label-based attribution.

Google Cloud Gen AI Series · Part 26 of 30

A Vertex AI bill is easy to start and hard to read. The console hands you a number, not the reason it moved. This part is about reading that bill line by line, then bringing it down without breaking the product on top of it.

Who this is for: You run or pay for a Gemini workload on Vertex AI and you want the monthly cost predictable. I assume you have read Part 6 on Vertex AI pricing and know on-demand from provisioned throughput. No FinOps background needed. FinOps just means running cloud spend as a shared engineering and finance practice instead of a monthly surprise, and I define every other term on first use.

Key takeaways

Output tokens and the 200,000 token long-context threshold are where most Gemini bills quietly grow, not the base input rate.

The cheapest lever is picking the right model tier. Caching a repeated prompt prefix and moving non-urgent traffic to Batch mode come next, and both need no code rewrite.

Provisioned throughput and committed use discounts only win once you have steady, high utilization. Below the break-even you pay for idle capacity.

Where the Vertex AI bill actually comes from

Vertex AI is not one price. A single Gemini application touches half a dozen billable lines, and the one that hurts is rarely the one you watched during the demo. Model inference is billed per token, split into input (what you send) and output (what the model writes back). Output is the expensive half. On Gemini 2.5 Flash, output runs about eight times the input rate, so a chatty assistant that returns long answers costs far more per call than the token count of the question suggests.

Then there is the long-context surcharge. On the Pro tier, input pricing doubles once a single request crosses 200,000 tokens. It is a hard step, not a gentle slope. Stuff a large retrieved document set into one prompt and you can cross that line without noticing, and every request over it bills at the higher rate. Around inference sit the supporting costs: embeddings for retrieval, grounding requests when you ground on Google Search, storage for tuned model artifacts and cached content, and the usual BigQuery, Cloud Storage, and network egress that a RAG system leans on. A Generative AI Scale Unit, or GSU, is the throughput unit you reserve when you buy provisioned capacity, and each GSU-hour bills whether or not you send traffic through it.

Here is the token pricing I work from for the Gemini 2.5 family, real-time against Batch mode. Google rotates model generations often, so confirm the current tier on the pricing page before you commit a budget to it.

ModelInput real-timeOutput real-timeInput BatchOutput Batch
Gemini 2.5 Pro (up to 200k)$1.25$10.00$0.625$5.00
Gemini 2.5 Flash$0.30$2.50$0.15$1.25
Gemini 2.5 Flash-Lite$0.10$0.40$0.05$0.20
Table 1. Gemini 2.5 token pricing per million tokens. Batch mode is a flat 50 percent off both directions. Rates verified July 2026 on the Vertex AI pricing page.

Three habits that quietly inflate the bill

Before any clever optimization, I look for waste, because waste is free to remove. Three patterns show up on almost every bill I review. First, retries without backoff. A client that retries a timed-out call immediately can bill two or three full generations for one user request, and the model does not refund the tokens it already produced. Cap retries and add jitter. Second, an uncapped output length. If you never set a maximum output token limit, a model that decides to ramble bills you for every token of it, and output is the pricey side. Set a ceiling that matches the answer you actually want. Third, grounding on every call. Grounding on Google Search or your own index adds a per-request charge, and plenty of calls do not need fresh retrieval at all. Gate it behind a check rather than running it by default. None of these need a rewrite. They need a config review, and they usually pay back within the hour.

Four cost levers, ranked by payback

Every optimization I reach for falls into four buckets, and I use them in this order because that is roughly the order of payback per hour of effort.

1. Right-size the model. This is the biggest lever and the one teams skip. Most production traffic does not need Pro. Flash costs a fraction of Pro and handles classification, extraction, summarization, and most RAG answers cleanly. Route Pro only to the requests that genuinely need deeper reasoning. Why recommended: the price gap between tiers is larger than any discount you can negotiate. When not: do not downgrade the tier that a human-facing feature depends on without an eval, because a cheaper wrong answer is not cheaper. Validate first with a side-by-side eval on your own prompts.

2. Cache the repeated prefix. Context caching stores a prompt prefix you send on every call, a system prompt and few-shot examples and a fixed knowledge block, and bills the cached portion at a steep discount instead of full input rate on each request. Cached input on Gemini 2.5 Pro drops to roughly $0.13 per million tokens, close to 90 percent off the standard input rate, with a small per-hour storage fee on top. When not: caching a prefix that changes every call just adds storage cost for nothing. Validate first that your prefix is genuinely stable across requests.

3. Batch the non-urgent work. Batch mode runs the same models at 50 percent off both input and output, with results returned asynchronously rather than in real time. Nightly summarization, backfills, evaluation runs, and document enrichment do not need a synchronous response. Move them and you halve their line item. When not: anything a user is waiting on. Validate first that the job tolerates a delayed, queued result.

4. Commit only what is steady. Provisioned throughput reserves dedicated capacity, and committed use discounts trade a one or three year spend commitment for a lower rate, up to around 50 to 55 percent off compute. Both reward predictable, high volume and punish spiky, low volume. I treat these last, after the workload has settled. More on the break-even below.

Worked example: monthly cost after each lever 5 million requests per month on Gemini 2.5 Flash, 2000 input and 400 output tokens each 0 2000 4000 6000 8000 USD per month $8,000 Baseline $6,400 Plus Batch 40% $5,200 Plus caching
Figure 1. Two levers, no model downgrade, cut this workload about 35 percent. Numbers are worked below.

Worked example

Take a support assistant on Gemini 2.5 Flash: 5 million requests a month, about 2,000 input tokens and 400 output tokens per call. Input is 10,000 million tokens at $0.30, so $3,000. Output is 2,000 million tokens at $2.50, so $5,000. Baseline is $8,000 a month.

Now move 40 percent of that traffic, the overnight ticket triage that nobody waits on, to Batch mode at half price. That slice was $3,200 and becomes $1,600, a $1,600 saving. Then cache the 1,500 token shared prefix on the real-time traffic, which trims roughly $1,200 more.

New run rate is about $5,200. No tier change, no product change, roughly 35 percent off. The caching figure is an estimate and moves with your prefix stability, so treat it as a range and measure yours.

Line itemBeforeAfter
Real-time input, 10,000 M tokens$3,000$1,900
Real-time output, 2,000 M tokens$5,000$3,300
Batch slice (40% of traffic)includedhalved
Monthly total$8,000~$5,200
Table 2. The same bill, before and after batching and caching. Split shown per direction for readability.

When is provisioned throughput worth it?

Provisioned throughput sells you a reserved slice of model capacity measured in GSUs, billed per GSU-hour whether you use it or not. Published rates land in the range of $42 to $158 per GSU-hour depending on model and region, and a one-month or one-year commitment shaves 20 to 45 percent off that. The catch is the idle risk. You pay for the reservation around the clock, so a unit that sits quiet overnight is money you spent on nothing.

The question is not whether provisioned is cheaper per token, it is whether your sustained utilization clears the break-even. Third-party analysis puts that point near 12 to 15 percent of the capacity you reserve, meaning if you keep a GSU busy at least that fraction of the time, the reservation beats paying on-demand for the same throughput. Below it you are subsidizing idle capacity. Plot the effective unit price and the shape is a falling curve that crosses the flat on-demand line at the break-even.

Provisioned break-even against on-demand Effective unit price falls as you keep the reserved capacity busy 0 0.20 0.40 0.60 0.80 USD per M tokens 0% 25% 50% 75% 100% Sustained utilization of reserved capacity On-demand flat Break-even ~13% Provisioned
Figure 2. Below roughly 13 percent sustained utilization, on-demand wins. The exact break-even varies by model and region.
My take: I do not buy provisioned throughput on a new workload. I run it on-demand for a month, read the utilization from billing export, and only then decide. Reserving capacity before you know your real duty cycle is the fastest way to turn a variable bill into a fixed one that is larger.

Wire billing export before you need it

The billing console is fine for a glance and useless for an investigation. It cannot tell you which project, which SKU, or which team drove a spike, and it keeps only a shallow history. The fix is to export Cloud Billing data to BigQuery on day one, before you have a fire to fight, because the export only captures data from the moment you enable it forward. Turn it on late and the month you most want to analyze is the month you cannot.

Once export runs, detailed usage cost lands in a BigQuery dataset you can query per service, per SKU, per label. Google also offers a FOCUS-aligned export, an immutable dataset normalized to the FinOps Open Cost and Usage Specification, which is worth enabling if you report across more than one cloud. Pair the export with a budget so you get alerted, not just informed after the fact.

# Create a monthly budget scoped to Vertex AI with three alert thresholds
gcloud billing budgets create 
  --billing-account=0X0X0X-0X0X0X-0X0X0X 
  --display-name='Vertex AI monthly' 
  --budget-amount=10000USD 
  --filter-services=services/VERTEX_AI_SERVICE_ID 
  --threshold-rule=percent=0.5 
  --threshold-rule=percent=0.9 
  --threshold-rule=percent=1.0,basis=forecasted-spend

# Top Vertex AI SKUs over the last 30 days, from the billing export table
SELECT
  service.description AS service,
  sku.description     AS sku,
  ROUND(SUM(cost), 2) AS cost_usd
FROM `PROJECT.DATASET.gcp_billing_export_v1_XXXXXX`
WHERE service.description = 'Vertex AI'
  AND _PARTITIONTIME >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
GROUP BY service, sku
ORDER BY cost_usd DESC
LIMIT 10;

Expected output: the budget command returns the created budget resource name, and the query returns up to ten rows ranked by spend, so you see whether output tokens, provisioned throughput, or grounding is the top SKU. Failure mode: if export is not enabled yet the query fails with a not-found on the table, and the budget filter silently matches nothing if the service id is wrong, so confirm it against the SKU listing first.

Disclaimer: Creating budgets and enabling export are read and notify actions, safe to run in production. Changing model tiers, turning on caching, or moving traffic to Batch does change live behavior, so stage those behind an eval and a canary before you roll them out.

Budgets, alerts, and the anomaly dashboard

A budget in Cloud Billing tracks actual spend against a planned number and fires alerts at thresholds you set, on both actual and forecasted cost. Wire the alerts to a Pub/Sub topic and you can drive automation off them, throttling a job or paging a channel, rather than relying on someone reading an email. On top of budgets, the Anomalies dashboard reached general availability and now ships root-cause detail with thresholds that retrain daily against your own pattern, which catches the slow creep that a fixed threshold misses. The FinOps Hub rounds it out with recommendations and a savings view. The loop that keeps a bill honest looks like this.

flowchart LR
  A[Vertex AI usage] --> B[Billing export to BigQuery]
  B --> C[Looker Studio dashboard]
  C --> D[Budgets and alerts]
  D --> E[Anomaly dashboard]
  E --> F[FinOps Hub recommendations]
  F --> G[Act: cache, batch, rightsize]
  G --> A
Figure 3. The FinOps loop. Export feeds dashboards, dashboards feed alerts and anomaly detection, recommendations drive action, and action changes usage. It never stops running.
Gotcha: A budget does not cap spending. It watches and alerts. If you need a hard stop you have to build it, wiring the budget Pub/Sub message to a function that disables billing or throttles the workload. Teams learn this the expensive way when a runaway job blows past 100 percent and the only thing that happened was an email.

Attribute cost with labels, or fly blind

A total is not actionable. Which team, which feature, which environment is. Labels are the key-value tags you attach to resources, and they flow straight into the billing export, so a query can split Vertex AI spend by team, by product surface, or by prod against dev. Without them you get one number and a shrug. With them you can do showback, telling each team what they spent, and eventually chargeback, actually billing it back. Set a labeling standard early, enforce it in your deployment pipeline so nothing ships unlabeled, and the FOCUS export gives you a normalized schema to report on. This is boring work that pays for itself the first time finance asks why the bill moved and you answer in one query instead of a week.

Where I start on a Vertex AI cost review

If you inherit a Vertex AI bill and have one afternoon, spend it in this order. Turn on billing export to BigQuery and a labeling standard first, because everything else depends on data you can only collect going forward. Then read the SKU breakdown and check the obvious two: are you on Pro where Flash would do, and are you paying the long-context surcharge on prompts you could trim. Cache any stable prefix. Push the non-urgent jobs to Batch. Leave provisioned throughput and committed use discounts until you have 30 days of utilization to justify them, because a commitment made on a guess is a commitment you regret. Do that and the bill stops being a monthly surprise and starts being a number you can predict and defend.

Governance is the other half of this. Part 27 picks up responsible AI, audit, and the controls that keep a governed workload defensible. If you do one thing after reading this, enable billing export today so next month you can actually see where the money went. For a cross-cloud comparison, the same discipline on the AWS side lives in the Bedrock cost governance part.

Google Cloud Gen AI Series · Part 26 of 30
« Previous: Part 25  |  Guide  |  Next: Part 27 »

References

About The Author


Discover more from Journal of Intelligent Infrastructure – By Dr Pranay Jha

Subscribe to get the latest posts sent to your email.

Leave a Reply

Your email address will not be published. Required fields are marked *

Architect’s Toolkit

About the Author

Dr. Pranay Jha is a Cloud and AI Consultant with 18+ years of experience in hybrid cloud, virtualization, and enterprise infrastructure transformation. He specializes in VMware technologies, multi-cloud strategy, and Generative AI solutions. He holds a PhD in Computer Applications with research focused on Cloud and AI, has published multiple research papers, and has been a VMware vExpert since 2016 and a VMUG Community Leader.

Discover more from Journal of Intelligent Infrastructure - By Dr Pranay Jha

Subscribe now to keep reading and get access to the full archive.

Continue reading