# The 30-Point Database Cost Review Checklist

*A self-assessment from AKS Engineering — aks.rajivonai.com*

The same checklist we run at the start of a Database Cost & Reliability Review. Work
through it against one production database. For each item, mark **OK / Needs work /
Unknown**. "Unknown" is itself a finding — it usually means an observability gap.

> **How to use this:** score honestly, total your "Needs work" and "Unknown" counts, and
> use the 30/60/90 planning section at the end to sequence fixes. Read-only access is
> enough to answer most of these. Engine examples lean PostgreSQL/Aurora/MySQL.

---

## A. Cost (1–4)
1. **Instance right-sizing.** Are CPU, memory, and connection utilization consistent with the instance class? Sustained low utilization (e.g. <20% CPU at peak) signals oversizing.
2. **Idle / non-prod waste.** Are dev/staging/test instances running 24/7 when they only need business hours? Any orphaned instances or clusters nobody owns?
3. **Pricing model fit.** Are you on on-demand for steady-state workloads that would suit reserved/committed pricing? Are storage and I/O pricing tiers understood?
4. **Storage & I/O cost drivers.** Do you know what drives storage and I/O charges (Aurora I/O, provisioned IOPS, GP3 vs io2)? Is allocated storage far above used?

## B. Performance (5–9)
5. **Slow / expensive queries identified.** Is `pg_stat_statements` (or equivalent) enabled and reviewed? Do you know your top queries by total time and by calls?
6. **Index effectiveness.** Are there unused indexes (write overhead, no read benefit) and missing indexes (frequent sequential scans on large tables)?
7. **Connection management.** Is connection count healthy, and is pooling in place (PgBouncer/RDS Proxy)? Connection storms drive latency and cost.
8. **Cache hit ratio.** Is the buffer/cache hit ratio healthy? A low ratio often points to undersized memory or inefficient queries — and to I/O cost.
9. **Lock / contention hotspots.** Any recurring lock waits or long-running transactions blocking others?

## C. Reliability (10–13)
10. **Failover tested.** Has automatic failover actually been tested, not just configured? Do you know the real RTO?
11. **Multi-AZ / HA posture.** Is the HA configuration appropriate to the availability target — and not over-provisioned beyond it?
12. **Single points of failure.** Any critical path depending on one instance, one AZ, or one undocumented component?
13. **Capacity headroom.** Enough headroom (CPU, connections, storage growth) to survive a realistic traffic spike without an incident?

## D. Storage (14–16)
14. **Bloat & dead tuples.** For PostgreSQL: is table/index bloat measured? Is autovacuum keeping up, or are dead tuples inflating storage and scan cost?
15. **Storage growth trend.** Is storage growth tracked and forecast? Anything growing unboundedly (logs, audit tables, soft-deleted rows)?
16. **Data retention & archival.** Is old/cold data archived or tiered, or is everything sitting on hot, expensive storage forever?

## E. Replication (17–19)
17. **Replica purpose & utilization.** Does each read replica earn its cost (real read traffic), or were some added "just in case" and now sit idle?
18. **Replication lag visibility.** Is replication lag monitored and alerted? Do you know your normal lag and your threshold?
19. **Read/write split correctness.** Is read traffic actually routed to replicas, or is the primary carrying load the replicas were paid for?

## F. Backup & Recovery (20–22)
20. **Backups exist and are automated.** Automated backups + appropriate retention for every production database?
21. **Restores are tested.** Has a restore actually been performed and timed recently? An untested backup is a hope, not a recovery plan.
22. **PITR & RPO understood.** Is point-in-time recovery available where needed, and does the team know the real RPO?

## G. Observability (23–25)
23. **Metrics coverage.** Core metrics (CPU, memory, connections, IOPS, replication lag, cache hit ratio) collected with adequate retention to see trends?
24. **Query-level insight.** Can you see query-level performance and cost (slow-query log, `pg_stat_statements`, Performance Insights or equivalent)?
25. **Alerting on the right signals.** Do alerts fire on leading indicators (lag, connection saturation, storage runway, replication health) — not just "instance down"?

## H. Security (26–28)
26. **Encryption at rest & in transit.** Storage encryption and TLS enforced for connections?
27. **Access & credential hygiene.** Least-privilege roles, no shared superuser creds for apps, rotation in place? Public accessibility disabled where it should be?
28. **Audit & change visibility.** Is there a record of who changed what (config, schema, access)? Can you reconstruct a change that caused an incident or cost spike?

## I. Automation (29)
29. **Toil & manual operations.** Which routine operations (scaling, cleanup, vacuum tuning, snapshot management, non-prod shutdown) are manual and error-prone, and could be automated to reduce risk and cost?

## J. Action Planning (30)
30. **Findings are prioritized and owned.** Are issues triaged by impact × effort × risk, with owners and dates — or is the list just a backlog nobody sequences?

---

## Scoring & 30/60/90-day planning

| Result | Count |
|---|---|
| OK | ___ / 30 |
| Needs work | ___ / 30 |
| Unknown | ___ / 30 |

> **A high "Unknown" count is your most important signal.** It means you can't currently
> answer basic cost and reliability questions about your own database — start with
> observability before chasing optimizations.

**First 30 days — Stop the bleeding & see clearly**
- Fix anything in **Unknown**: enable `pg_stat_statements`, slow-query logging, and core metric collection.
- Capture quick, low-risk wins: shut down idle non-prod, remove orphaned instances, confirm backups exist.
- Validate the scary basics: confirm restores work and failover is configured.

**Days 31–60 — Right-size & reduce structural waste**
- Act on right-sizing and pricing-model findings backed by the utilization data you now have.
- Address replica utilization and read/write routing.
- Begin bloat/vacuum and index cleanup where evidence is clear.

**Days 61–90 — Harden & automate**
- Close remaining reliability gaps (failover testing, headroom, SPOFs).
- Automate the recurring toil you identified (non-prod scheduling, snapshot lifecycle).
- Establish a baseline and a re-review cadence so you can prove the changes worked.

---

### Want a senior engineer to run this for you?
A full **Database Cost & Reliability Review** quantifies each opportunity against your
actual usage, ranks findings by impact and effort, and delivers a sequenced plan — with
the evidence behind every line.

**→ Book a 30-minute scoping call at aks.rajivonai.com**

*This checklist is provided for informational purposes. Apply changes through your normal
testing and change-management process; validate every change against your own
environment.*
