Your AI Bill Doesn't Stop When the Project Does
How GreenOps Scan finds idle and forgotten spend in Amazon Bedrock
Every team we've talked to has an AWS bill that includes at least one Bedrock line item nobody can fully explain anymore — a Provisioned Throughput purchased for a proof of concept that shipped or died months ago, a fine-tuned model nobody deleted, an agent someone built for a demo. Generative AI spend has a specific failure mode that regular compute doesn't: the resources are provisioned in advance of usage, not scaled to it, so "we're not using this anymore" and "we've stopped paying for it" are two completely different events unless someone remembers to connect them.
GreenOps Scan's bedrock module exists for that gap. Here's exactly what it checks, how it prices what it finds, and — just as importantly — where we're honest about the limits of that pricing.
What actually costs money in Bedrock (and what doesn't)
On-demand model invocations (the pay-per-token API calls most Bedrock usage looks like) scale with usage almost perfectly: no tokens sent, no charge. That's not where the waste hides. The waste hides in the small number of Bedrock features you provision ahead of demand:
- Provisioned Throughput — dedicated model capacity you commit to (with or without a term), billed by the hour whether or not a single request hits it
- Custom models — fine-tuned or continued-pretrained models incur a small ongoing storage charge for as long as they exist, independent of whether they're ever invoked
- Agents and Knowledge Bases — not directly billed per-resource, but they're a strong signal of unfinished or abandoned AI initiatives, and they often have paid infrastructure (vector stores, Lambda functions, data source connectors) sitting behind them
That's the shape of every check the module runs.
Check 1: Provisioned Throughput with zero invocations
This is the highest-value check, and often the highest-dollar finding in an entire scan. The module lists every Provisioned Throughput in the account via bedrock:ListProvisionedModelThroughputs, then pulls 30 days of AWS/Bedrock Invocations CloudWatch metrics for each one. If a Provisioned Throughput shows zero invocations across a full 30-day window, it's flagged.
The dollar estimate comes from the model unit count on the resource multiplied by an hourly no-commitment rate table we maintain per model family (Claude, Nova, Titan, Llama, Mistral, Cohere) — because Bedrock doesn't expose price via API, and rates vary by model and commitment term. When we recognize the specific model in the ARN, the finding gets medium confidence; when we don't, it falls back to a conservative default rate with low confidence rather than guessing silently. We'd rather under-claim savings than surprise you with a number that turns out wrong.
Provisioned Throughput commitments can run thousands of dollars a month for a single unit of a large model — this is routinely the single biggest number in a GreenOps report for teams experimenting with generative AI. It's also structurally easy to forget: someone provisions capacity to test throughput or latency for a launch, the launch is delayed or cancelled, and the capacity keeps billing by the hour indefinitely.
Check 2: Custom models with no Provisioned Throughput
A fine-tuned or custom model in Bedrock cannot serve inference on its own — it requires Provisioned Throughput to actually be invoked. So a custom model with no matching Provisioned Throughput is, by definition, unusable for inference right now, yet it still accrues a small storage charge every month it exists.
The module cross-references every custom model against the set of model ARNs backing active Provisioned Throughputs, and flags any custom model older than 7 days (to avoid flagging models still being set up) that isn't backing any of them. The dollar figure here is modest per model (storage cost, not compute cost) and reported at high confidence, since it's a fixed, known rate rather than an estimate — but it's a very clean signal of a fine-tuning experiment that was never connected to anything, or that finished being useful a while ago.
Check 3: Stale agents and empty knowledge bases
These two checks don't carry a dollar estimate — we report them as $0 with low confidence deliberately, rather than inventing a number for infrastructure that isn't billed per-resource. They're included anyway because they're the clearest indicator that an AI initiative stalled:
- Agents that reached a
PREPAREDstate (i.e., configured and ready to use) but haven't been updated in 30+ days are flagged as likely abandoned. - Knowledge Bases with zero data sources attached are flagged — a knowledge base with nothing to retrieve from can't be doing anything useful yet, or its data sources were removed and it was never cleaned up.
Neither finding is destructive to report on its own, but both are usually attached to real paid infrastructure one layer down — an OpenSearch Serverless collection backing a knowledge base, or a Lambda action group behind an agent — that a dollar-only scan would never surface, because the agent itself isn't the line item on your bill.
Why the carbon numbers matter here too
Idle Provisioned Throughput is exactly the kind of waste the "carbon" half of GreenOps' name is about: it's model-unit compute sitting reserved and (from AWS's side) very likely still running underlying instances, generating emissions, while producing zero output. We estimate the carbon impact of idle Provisioned Throughput using the same idle-compute emissions model we apply to over-provisioned EC2/ECS/RDS elsewhere in the scanner, scaled by model units — treated as a proxy for the underlying compute footprint, since AWS doesn't publish per-model-unit power draw. Custom model storage gets the same treatment via our storage emissions model. Like the dollar estimates, we'd rather flag this as a directional estimate than omit it, since "wasted AI capacity has a carbon cost too" is the point most cost-only tools miss entirely.
What we deliberately don't try to catch (yet)
To be transparent about scope: the module doesn't currently analyze on-demand token usage patterns (e.g., "you're calling an expensive model for a task a cheaper one would handle"), doesn't inspect prompt/response sizes, and doesn't cross model providers outside Bedrock. Those are genuinely harder, lower-confidence problems — better fits for prompt-engineering review than an infrastructure scanner — and we didn't want to ship a check that guesses at "is this the right model for the job" with fabricated confidence.
Try it against your own account
npx greenops-scan --profile your-profile --modules bedrock,ec2,rds
Every check above runs against read-only Bedrock and CloudWatch APIs — nothing it does can modify or delete a resource; even the remediation commands it suggests (like aws bedrock delete-provisioned-model-throughput) are printed for you to review and run yourself, never executed automatically. If you'd rather verify that guarantee with IAM rather than trust it, see our read-only AWS profile walkthrough first.
Tags: #Bedrock #GenerativeAI #AWS #FinOps #CloudCost #Sustainability #GreenOps
