How Much Does AWS Secrets Manager Cost?

Secrets Manager bills $0.40 per secret a month plus API calls, and the total climbs faster than it looks like it should. Here's where the money actually goes.

Published August 29, 2026 · Last updated September 4, 2026

You went looking for the thing that jumped on last month's bill, and it turned out to be Secrets Manager — a service you use to store a few database passwords and API keys. It doesn't feel like it should cost real money. There's no compute, no storage in the usual sense, nothing that sounds metered by the gigabyte. And yet the line item is climbing every month, and nobody on the team can point at the one thing that changed.

Why does Secrets Manager cost anything at all?

Secrets Manager has exactly two charges, and neither is what people expect from an AWS bill:

  • $0.40 per secret, per month — a flat storage-like fee for every secret you keep, whether or not anything ever reads it.
  • $0.05 per 10,000 API calls — every GetSecretValue, every rotation, every DescribeSecret your application or the console makes.

There's no free tier that makes this go away long-term. AWS gives new accounts up to $200 in general Free Tier credits for their first six months, but that's a one-time account-wide allowance across every service, not a standing Secrets Manager exemption — once it's used up, both charges above apply from the first secret.

Forty cents doesn't sound like a bill. The reason it turns into one is the multiplication most teams don't do up front: the total is secrets times environments times regions. A service with 10 secrets, deployed to dev, staging, and prod, is already 30 secrets — $12/month before a single API call. Replicate any of those secrets into a second region for latency or failover, and each replica is a separate secret resource billed at the same $0.40/month rate in the region it lands in, because a replica is what it says it is: a full secret with its own ARN, not a pointer back to the original.

Why is my bill bigger than "secrets × $0.40" suggests?

Because the API-call side rarely stays small once an application is actually running. The pattern that inflates it almost every time: code that calls GetSecretValue on every request, or on every cold start of every container, instead of fetching the secret once and holding it in memory.

Run that math for a moderately busy service. A container fleet that calls GetSecretValue once per request at 50 requests per second is making roughly 4.3 million calls a day — about 130 million a month. At $0.05 per 10,000 calls, that's $650/month, for a value that changes maybe once a quarter. The storage side of that same secret costs 40 cents. The API calls cost more than a thousand times as much, and it's the part almost nobody checks first.

A second, quieter driver: secrets nobody deleted. A staging environment that got torn down, a service that got replaced, a rotation Lambda that keeps a secret alive because it still runs on schedule even though nothing reads the value anymore. None of these show up as a spike — they're a flat $0.40/month each, added to a pile that only ever grows.

How do I find out what's actually driving the number?

Start with Cost Explorer, filtered to Secrets Manager and grouped by Usage Type. That split tells you in one screen whether the storage charge or the API-call charge is the bigger number — which decides whether you're hunting for dead secrets or a chatty caller.

To find secrets nobody has touched recently, list every secret with its last-accessed date and sort by staleness:

aws secretsmanager list-secrets \
  --query 'reverse(sort_by(SecretList, &LastAccessedDate))[].[Name,LastAccessedDate]' \
  --output table

A secret with a LastAccessedDate from six months ago, sitting in an account where nothing was decommissioned that recently on paper, is worth a closer look before you assume it's still load-bearing.

To find the caller running up the API-call side, CloudTrail has every GetSecretValue event with the identity that made it:

aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=EventName,AttributeValue=GetSecretValue \
  --start-time "$(date -u -d '24 hours ago' +%Y-%m-%dT%H:%M:%SZ)" \
  --max-results 50 \
  --query 'Events[].[EventTime,Username]' \
  --output table

If the same Lambda function or EC2 role shows up dozens of times an hour, that's your $0.05-per-10,000 problem, not a storage problem.

How do I bring the bill down without breaking anything?

Cache the value instead of re-fetching it. This is the highest-leverage fix, because it attacks the meter that's usually 10–1,000x the storage charge. Fetch the secret once at startup (or once per rotation, using the rotation Lambda's own event to invalidate a cache), hold it in memory, and stop calling GetSecretValue on the request path entirely.

Delete secrets with no recent access and no code reference. Each one you remove is $0.40/month gone immediately — small individually, real in aggregate once a few dozen accumulate across environments nobody audits.

Stop replicating secrets you don't need in every region. A replica is a full secret at the full rate in its own region. If only one region actually serves traffic that needs a given secret, it doesn't need a standing replica anywhere else — you can call the primary Region's endpoint directly instead.

Move config that doesn't need rotation to Parameter Store. Systems Manager Parameter Store's Standard tier is free for standard parameters, with Advanced parameters at $0.05/parameter/month — both cheaper than Secrets Manager's $0.40. The trade-off is real: Secrets Manager gives you automatic rotation, resource policies, and native integration with RDS, Redshift, and DocumentDB credentials, none of which Parameter Store does natively. If a value is a static API key or a feature flag with no rotation requirement, Parameter Store is the cheaper, correctly-scoped tool. If it's a database password that needs to rotate on a schedule, keep it in Secrets Manager.

What else should I check while I'm in here?

If the secrets driving your bill are read from inside a VPC — a Lambda function or an EC2 instance in a private subnet calling secretsmanager.amazonaws.com — check how that traffic leaves the subnet. By default it routes out through a NAT Gateway, which meters every one of those calls' response bytes at the NAT data-processing rate on top of the Secrets Manager API charge itself. A Secrets Manager interface VPC endpoint removes the NAT hop for that traffic entirely; it isn't free, but at any real call volume it's cheaper than paying the NAT per-GB fee for traffic that never needed to leave AWS's network in the first place.

If that Lambda function sits behind API Gateway, the same "fetch once, cache it" fix does double duty: every invocation is already paying an API Gateway per-request charge before it ever calls GetSecretValue, so a function re-fetching the secret on every cold start is stacking two per-request meters for a value that rarely changes. See what API Gateway costs at scale for how that request charge adds up on its own.

The rotation Lambda itself is worth a second look too. It's easy to forget it exists once it's working, and it writes to a CloudWatch log group like everything else — one with no retention policy set, quietly accumulating years of rotation logs nobody will ever read. That's the same never-expire default covered in why is CloudWatch so expensive, and it's common enough behind a rotation setup that it's worth checking the log group's retention while you're already looking at this secret.

If you switched a secret from the default AWS-managed key to a customer-managed KMS key — usually to get a custom key policy or cross-account sharing — that decision doubles the per-call meter you just diagnosed above: every GetSecretValue now also triggers a KMS Decrypt call, billed separately from Secrets Manager's own $0.05-per-10,000 API charge. See how much does KMS cost to run for the rest of that bill, and the same caching fix that cuts both meters at once.

More broadly, this kind of per-resource creep — a few cents here, a forgotten replica there — is exactly the pattern behind the rest of what an AWS bill accumulates; the broader pass over what else drives an AWS bill up works through it region by region.

How do I catch this before it becomes a real number?

Secrets Manager cost almost never shows up as a spike — a new secret, a new replica, one more service calling GetSecretValue too often, each looks tiny on the day it's added. It's the accumulation over a year of small, individually-reasonable decisions that turns into a line item somebody has to explain. That's the harder half to catch by hand, because there's no single moment that looks wrong.

Connect your AWS account read-only, and Parsivex's daily anomaly checks compare every service's spend — Secrets Manager included — against its own trailing baseline, so a genuine jump (a caching bug that starts hammering GetSecretValue, a batch of secrets replicated into every region by mistake) gets flagged the next morning instead of at month-end. For how those daily checks and severity thresholds work, see cost anomaly alerts, or read how scans work for what a connected account scan reads across the rest of your bill.