TL;DR: Secrets Manager costs $0.40 per secret per month plus $0.05 per 10,000 API calls — small numbers that compound through orphans (services deleted, secrets not), duplicates (three names for the same RDS password), over-rotation (daily cadence where policy says 90 days — 13× the rotation failure risk for zero security gain), and un-cached readers. Most accounts halve this line in an afternoon, and the operational-risk reduction is worth more than the dollars.
The numbers
- $0.40/secret/month (replicas bill as full secrets — 400 secrets replicated to a second region is 800 secrets); $0.05 per 10k API calls
- Field example: a 3-year-old account with 400 secrets found 160 never accessed, 80 dormant 6+ months, 40 exact duplicates → bulk soft-delete took the bill from $160 to $64/month, nothing broke
- Un-cached reads are the sleeper: one secret read 100×/sec around the clock ≈ $1,300/month in API calls alone
- The cautionary tale: daily rotation + a transient API failure = a 45-minute partial outage; the fix was slower rotation (90d) plus a failure alarm and post-rotation synthetic test
Do this
-
Inventory with last-access:
aws secretsmanager list-secrets --include-planned-deletion \ --query 'SecretList[*].[Name,LastAccessedDate,RotationEnabled]' --output table -
Soft-delete the dead (not accessed in 90+ days, no live IAM consumers):
delete-secret --recovery-window-in-days 30— recoverable for a month, so the sweep is low-risk. -
De-duplicate deliberately: pick a canonical naming scheme (
/<env>/<service>/<credential>), migrate consumers one at a time, delete copies after a confirmed rotation cycle. Never sweep duplicates in one pass. -
Right-size rotation cadence: 60–90 days for database credentials (PCI's ceiling is 90), 30 for high-privilege admin creds, manual-by-policy for third-party API keys (their rotation needs side effects), and IAM roles instead of stored AWS keys — a stored access key is an architecture smell. Before touching cadence: add a CloudWatch alarm on rotation-Lambda failures and a synthetic test that exercises the new credential after each rotation.
-
Cache the hot readers: the AWS Parameters-and-Secrets Lambda extension (or in-app caching) turns per-invocation reads into one per ~5 minutes.
-
Move non-rotating, non-replicated config to SSM Parameter Store — Standard tier is free (SecureString still encrypts via KMS). Sane split: Secrets Manager = rotating/replicated credentials; Parameter Store = everything else. Mind Parameter Store's tighter API throttles — cache regardless.
Gotchas
- Rotation ≠ protection against current compromise — it invalidates past leaks. Cadence should match how long a leaked credential stays useful, not "as often as possible."
- Unmonitored rotation is silent risk: failed rotations park secrets in
Pendingwith no alarm unless you build one. - Rotation Lambdas that only bump the version (consumer never gets the new password) defeat the whole point — verify end-to-end once.
- Replication doubles storage billing — keep always-on replicas for the truly critical secrets; periodic DR-drill replication may cover the rest.
- A secret deleted late in the month still bills the month.
Skip this if
- Your secret count is tiny and tagged with owners — you're already the happy path; just check rotation cadences.
- Compliance explicitly mandates aggressive cadence for a data class — then keep it, with the failure alarm and synthetic test treated as mandatory, not optional.
- The dominant cost is API calls from one hot service — fix caching first; inventory hygiene can wait.