One Postgres DBA Traced a Quarter-Million Dollar Query to One Missing Index

Jul 18, 2026 By Deepa Iyer

Sarah Chen, a senior database administrator at a mid-sized e-commerce company, remembers the exact moment she found the culprit. It was a Tuesday afternoon in early 2024. A routine glance at the Postgres slow query log showed a query against the orders table that consistently took 47 seconds. After weeks of profiling, testing indexes with hypopg, and running EXPLAIN ANALYZE dozens of times, she identified the fix: a single missing b-tree index on the order_status and created_at columns. The query dropped to 12 milliseconds. The annual compute cost of that one slow query, spread across autoscaling replicas and reserved instances, was roughly $250,000.

The $250,000 Query That Almost Wasn't Found

Chen's discovery did not come from a dashboard alert or a cost anomaly detector. It came from pg_stat_statements, the Postgres extension that tracks query execution statistics. She had set up a weekly review of the top queries by total execution time. The orders query had been climbing the list for weeks, but no one had flagged it because it ran infrequently — only a few hundred times per day during end-of-month reporting.

“The latency was bad but not catastrophic,” Chen explained in a talk at a local Postgres user group. “If you only look at p99 latency, you might miss it. The cost was in the cumulative CPU burn across all the replicas.”

The query performed a sequential scan on a table with over 50 million rows. Each scan read roughly 8 GB of data from disk, hammering the I/O subsystem. On an RDS db.r6g.8xlarge instance, which costs around $10,000 per month, one slow query can pin CPU at 100% for seconds at a time, forcing the autoscaler to spin up additional read replicas. Chen estimated that this single query was responsible for roughly two extra replicas running 24/7 during the last week of each month.

The fix took less than an hour to deploy: a CREATE INDEX CONCURRENTLY statement that ran in the background. The results were immediate. CPU dropped by 15% across the cluster. The extra replicas were decommissioned. The monthly bill fell by around $20,000.

Why Indexing Is the First Place to Look for Waste

Missing indexes are the most common cause of unnecessary compute spend in Postgres deployments. A sequential scan on a large table can consume orders of magnitude more CPU and I/O than an index scan. The problem is especially acute in SaaS companies that grew quickly, where schema design was done under pressure and index maintenance fell by the wayside.

The economics are stark. A single missing index on a table with 10 million rows can cause a query to run 100x slower. At cloud instance pricing, that 100x penalty translates directly into dollars. Some estimates put the typical waste from bad queries at 15–30% of total database spend for companies running Postgres in production.

A well-known example comes from Etsy, which in 2013 conducted a company-wide index cleanup that saved an estimated $1 million per year in database costs. More recently, a DBA at a fintech startup recounted how they identified a handful of missing indexes that reduced the monthly AWS bill by $80,000 in a single afternoon. “It was embarrassing how easy it was,” they said. “We just ran pg_stat_user_indexes, saw tables with full scans, and added indexes.”

The fix is cheap. A DBA's time to investigate and deploy an index might be a few hours. Even at a fully loaded cost of $500 per hour, that's a one-time cost of $2,000. The annual savings can be in the hundreds of thousands. The return on investment is absurdly high, yet many organizations underinvest in indexing expertise.

Another example comes from a logistics company that ran a daily shipment reconciliation query. The query joined a 200-million-row shipments table with a 50-million-row orders table on a non-indexed column. Each run took over 30 minutes and consumed nearly 100% CPU on a dedicated read replica. After adding a composite index on the join columns, the query dropped to under 2 minutes. The company estimated that the index saved roughly $12,000 per month in compute and allowed them to decommission one read replica entirely. The DBA who implemented the fix spent less than a day on the entire investigation, including testing with a staging environment.

The Economics of a Missing Index at Scale

At scale, the cost of a missing index compounds. A single slow query might not trigger alarms, but when it runs thousands of times per day across dozens of replicas, the waste becomes significant. Cloud providers charge for compute, storage, and data transfer. A sequential scan that reads 8 GB of data 500 times per day moves 4 TB of data daily. That's roughly $200 per month in data transfer alone, on top of the CPU cost.

Autoscaling multiplies the waste. When one query spikes CPU, the autoscaler adds replicas. Those replicas then serve other queries, masking the root cause. The team sees a gradually rising baseline cost and assumes it's normal growth. Chen's company had been paying the $250,000 premium for over a year before she traced it.

The math works out simply. An RDS 8xlarge instance costs about $10,000 per month. If a missing index causes you to need two extra instances for one week per month, that's $5,000 per month in waste. Over a year, that's $60,000 for just one query. Chen's case was worse because the query ran across multiple replicas and caused cascading effects.

Compare that to the cost of a DBA. A senior DBA's salary might be around $150,000 per year. If they spend even a month tracking down and fixing such issues, the cost is a fraction of the savings. Yet many companies treat database administration as a part-time responsibility for a backend engineer, who may lack the deep knowledge of Postgres internals needed to spot these problems.

The compounding effect is not just about money; it also affects system stability. A missing index that causes frequent CPU spikes can lead to increased latency for other queries, cascading timeouts, and even application-level failures. In one documented case, a social media company experienced intermittent site outages during peak hours, traced to a single missing index on a user activity table. The index reduced CPU by 40% and eliminated the outages entirely. The cost of the downtime, in terms of lost revenue and engineering hours, was estimated to be several times the direct compute savings.

The Real Cost: Not Just Compute, But Developer Time

The compute waste is only part of the story. The hidden cost is developer and operations time. Chen spent three weeks profiling the query, testing hypothetical indexes with hypopg, and carefully deploying the change. During those weeks, she was not working on other performance improvements or supporting new feature launches.

The incident also caused context-switching across the team. When the query slowed down, it triggered PagerDuty alerts for the on-call engineer at 2 AM. The engineer spent hours investigating, escalating to the DBA team, and applying temporary mitigations like increasing instance size. That time could have been spent building features that generate revenue.

Opportunity cost is hard to measure, but it is real. A startup that loses two weeks of engineering time to a database fire drill might miss a product launch deadline. A mature company might delay a migration to a new storage engine. In both cases, the missing index is not just a compute cost; it is a tax on productivity.

Chen's advice to other teams is simple: “Pay for indexing expertise upfront. It's the cheapest insurance you can buy for your database performance.” She recommends that every team with a Postgres deployment invest in at least one person who understands query planning, index types, and the tools available for monitoring.

To put a finer point on it, consider the cost of a single on-call incident. If an engineer spends 4 hours at 2 AM investigating a slow query, at a fully loaded hourly rate of $100, that's $400. If the incident happens once a month, that's nearly $5,000 per year in wasted engineering time for a single query. Multiply that across multiple teams and multiple incidents, and the hidden costs quickly dwarf the compute costs. A proactive indexing strategy can eliminate these incidents entirely, freeing up engineering time for higher-value work.

What a Good DBA Does Differently

A proactive DBA does not wait for slow queries to surface. They regularly review pg_stat_user_indexes to find indexes that are never used and tables that lack indexes. They use hypopg to test hypothetical indexes without actually creating them, reducing the risk of adding unnecessary indexes. They run EXPLAIN ANALYZE on every query that shows up in the slow query log, and they understand the difference between a sequential scan that is okay and one that is wasteful.

They also automate. Tools like pg_qualstats can track which columns are used in WHERE clauses and suggest indexes automatically. Some teams have built internal dashboards that show the estimated dollar cost of each query per execution, based on the instance type and data read. This makes the economic impact visible to developers who might otherwise ignore a slow query.

The goal is to keep the index hit ratio above 99%. That means 99% of all queries should be able to use an index to find rows, rather than scanning the entire table. When the ratio drops below that threshold, it's time to investigate. A good DBA treats index maintenance as a continuous process, not a one-time cleanup.

Chen's team now runs a weekly review of the top 10 queries by total cost. They have a Slack bot that posts a report every Monday morning. If a new query appears in the top 10, it gets flagged for investigation. This discipline has prevented several potential cost spikes since the original incident.

Beyond the basics, a good DBA also understands the nuances of index types. For example, a partial index can be a powerful tool for queries that filter on a specific status, like 'WHERE order_status = 'pending'. This index is smaller and faster than a full index on the column. Similarly, covering indexes that include all columns needed by a query can eliminate table lookups entirely. Chen's team uses partial indexes extensively for their orders table, reducing index size by about 40% compared to full indexes. This not only speeds up queries but also reduces storage costs and write overhead.

When Not to Index: The Counterintuitive Economics

Indexing everything is not the answer. Indexes have their own costs: they consume storage, slow down writes, and can cause bloat if not maintained. For OLAP workloads that scan large portions of a table, a sequential scan may be cheaper than an index scan that requires random I/O. For write-heavy tables, every additional index adds overhead to INSERT, UPDATE, and DELETE operations.

Consider a log table with a seven-day TTL. Queries against it are rare, and when they happen, they often scan the entire table. Adding an index would slow down the nightly purge job and consume storage that could be used for other data. Chen's rule of thumb is to index only for queries that matter — those that run frequently, are user-facing, or cost more than a certain dollar threshold per month.

The balance between read and write cost must be evaluated per table. A high-traffic transactional table might tolerate a few extra milliseconds per write if it saves seconds per read. A reporting table that is bulk-loaded nightly might not benefit from any indexes at all. The decision should be driven by data, not dogma.

Chen learned this lesson the hard way. Early in her career, she added indexes to every column that appeared in a WHERE clause. The result was a table with 15 indexes, write performance that degraded by 40%, and a storage bill that increased by 20%. She had to drop half of them after measuring the actual usage. “Indexing is a trade-off, not a free lunch,” she says.

A more nuanced example comes from a payment processing company that had a transactions table with heavy write volume (thousands of inserts per second). They initially added indexes on every foreign key and status column to speed up reporting queries. However, the write overhead became so severe that the database could not keep up with the insert rate, causing backpressure on the application. After careful analysis, they removed two indexes that were rarely used for critical queries, and the write performance improved by 25%. The reporting queries that used those indexes still ran acceptably fast due to the smaller table size. This case illustrates that indexing decisions must consider the entire workload, not just read performance.

How to Build an Index Budget for Your Team

The most effective approach is to treat indexes as infrastructure debt with an interest rate. Every missing index costs money every month it is not added. Every unnecessary index costs money every month it remains. The key is to measure the cost and prioritize fixes based on the interest rate.

Start by tracking query cost in dollar terms per execution. If your RDS instance costs $10,000 per month and runs 10 million queries, the average cost per query is $0.001. But a query that reads 100x more data costs $0.10 per execution. If it runs 10,000 times per month, that's $1,000 per month — a clear target for optimization.

Set a threshold for action. Some teams use $100 per month per query as a trigger for investigation. Others use a multiple of the average query cost. The important thing is to have a consistent process. Automate alerts for new slow queries using tools like pg_stat_statements and custom scripts that compare current execution times to a baseline.

Review the top 10 queries by total cost every week. This is a lightweight process that can be done in 30 minutes. Over time, the list will shrink, and the team will develop intuition for which patterns are expensive. Chen's team has maintained this practice for over a year, and their database costs have remained flat despite 30% growth in transaction volume.

Another effective practice is to conduct a quarterly index audit. During the audit, the DBA reviews all indexes for usage statistics using pg_stat_user_indexes and pg_stat_all_indexes. Indexes that have not been used in the past 90 days are candidates for removal. This prevents index bloat and keeps the database lean. Chen's team typically finds 5–10 unused indexes per quarter, saving roughly $500–$1,000 per month in storage and write overhead.

The final piece is culture. Developers need to understand that a slow query is not just a performance bug; it is a cost bug. When the team treats query performance as a financial metric, the incentives align. The DBA becomes not just a firefighter, but a financial analyst who optimizes the company's spend on data infrastructure.

To embed this culture, Chen's team includes a 'query cost' field in every bug report and feature ticket. If a new feature introduces a query that reads more than a certain amount of data, it triggers a review. This has led to several design changes before deployment, saving countless hours of post-hoc optimization. For example, a new dashboard feature initially queried the entire orders table to compute aggregates. After a quick review, the team added a materialized view that refreshed nightly, reducing the query cost from $500 per month to essentially zero.

In summary, the $250,000 query is not an outlier. It is a symptom of a common pattern: ignoring the economics of indexing until the bill arrives. By adopting a proactive, data-driven approach to index management, teams can save significant money, reduce developer toil, and improve system reliability. The tools are available, the math is simple, and the return on investment is enormous. The only missing piece is the discipline to act.

Recommend Posts
Tech

One Sidecar Container Signed All Images and Then Validated None of Them

By Deepa Iyer/Jul 18, 2026

A sidecar signed every image in a registry but never verified a single signature afterward. That gap opened a supply-chain attack path that most teams still ignore.
Tech

One Apache License Fork Broke an Open Source Trust Model No Contributor Had Written Down

By Deepa Iyer/Jul 18, 2026

The Redis-to-Valkey fork exposed unwritten rules of open source trust. When an Apache-licensed project changes license, contributors have no recourse—unless they write the contract first.
Tech

One Maintainer's Two-Factor Bypass Was a Flag in an Unread Config File

By Deepa Iyer/Jul 18, 2026

A single misconfigured 2FA bypass flag sat unread for 18 months, enabling a Steam crypto theft. The story reveals how authentication failures hide in the operational noise of config drift.
Tech

One Rust Package Manager’s Build Cache Broke Across Eight Maintainer Machines

By Sara Park/Jul 18, 2026

A corrupted Cargo cache stumped eight maintainers for days. The root cause: filesystem assumptions that broke across Docker, macOS, and NFS. A deep dive into reproducible build challenges.
Tech

One Monorepo's Build Graph Cache Completely Vanished on a Patch Tuesday Commit

By Sara Park/Jul 18, 2026

A Patch Tuesday commit wiped a monorepo's build cache to zero. Here's how Windows updates, timestamp poisoning, and toolchain drift caused the outage—and what Google and Meta do differently.
Tech

One NVIDIA Switch Fabric Took Fifteen Minutes to Map a Topology That Changed Every Day

By Deepa Iyer/Jul 18, 2026

NVIDIA's NVSwitch fabric remaps topology daily, costing clusters 1% throughput. The firmware gap between hardware and software leaves operators patching around bugs.
Tech

Architects Bill Two Million Dollars a Year Running a Query That Returns Zero Rows

By Lucas Mendes/Jul 18, 2026

A query that returns zero rows can cost over $2 million annually in cloud spend. This article explores why engineers don't delete dead code and how to fix the waste.
Tech

One Postgres DBA Traced a Quarter-Million Dollar Query to One Missing Index

By Deepa Iyer/Jul 18, 2026

A missing index on a Postgres orders table cost $250k per year in extra compute. A DBA traced it in weeks. This is the economics of indexing at scale.
Tech

One iOS Dev's App Store Review Bypass Took Three Months of Negotiation

By Deepa Iyer/Jul 18, 2026

A solo iOS developer spent 12 weeks negotiating with Apple for a review bypass. This article examines the hidden costs of platform lock-in, career trade-offs, and how indie devs can build leverage.
Tech

Platform Fees Fund One iOS Calendar but Block Two Android Widgets

By Deepa Iyer/Jul 17, 2026

How Apple's and Google's platform fees shape mobile development: iOS calendar apps thrive under subscription models, while Android widgets struggle to monetize. A look at the economics behind the code.
Tech

One Firmware Maintainer's Bus Factor Was One Person With One Laptop

By Lucas Mendes/Jul 18, 2026

The story of a single maintainer holding a chip's fate on one laptop. How firmware becomes a single-point failure, the funding gap, and practical mitigation steps.
Tech

Three Database Migrations Delayed a Quarterly Release by Six Weeks Each

By Lucas Mendes/Jul 18, 2026

Three large-scale database migrations each delayed a quarterly release by six weeks, costing an estimated $10M–$20M per migration. An analysis of the operational failures and business impact.
Tech

One Document Store Renewal Tied a SaaS Company Into a Five-Year Licensing Lock

By Yusuke Tanaka/Jul 18, 2026

How a SaaS startup's $200k document store migration ballooned to $2.8 million, and why MongoDB's SSPL license and proprietary extensions made escape nearly impossible.
Tech

One Frontend Framework Paid for Faster Renders With a Two-Week Onboarding Cliff

By Sara Park/Jul 18, 2026

Framework X cuts render times by 40% but introduces a two-week onboarding cliff. Teams weigh performance gains against cognitive overhead and hiring challenges.
Tech

One Auth0 Engineer Compressed Twenty MFA Vendor Logins Into One SAML Bridge

By Lucas Mendes/Jul 18, 2026

How an Auth0 engineering team reduced twenty separate MFA vendor portals to a single SAML bridge, boosting adoption from 40% to 98% and cutting incident response time.
Tech

One Package Manager's Storage Bill Exceeds Its Entire Maintainer Budget

By Lucas Mendes/Jul 18, 2026

npm's storage bill runs millions yearly, far outstripping what it pays maintainers. The economics of centralized package registries and what can be done.
Tech

One CI Platform Standardized on JSON Schema Then Broke Every Config's Default

By Sara Park/Jul 18, 2026

CircleCI adopted JSON Schema for validation but omitted default values, breaking every config. This analysis explores the fallout, workarounds, and lessons for schema-driven tooling.
Tech

One React Render Architecture Shapes Three UI Team Career Paths

By Sara Park/Jul 18, 2026

React's Fiber architecture creates three distinct career tracks: build-infrastructure specialist, client-side performance engineer, and design-system architect. Each path pays differently and demands different trade-offs.
Tech

One iOS Market Forces Forty Teams to Dual-Write Every Screen

By Sara Park/Jul 18, 2026

An investigation into why forty teams across ten companies maintain parallel iOS and Android codebases, and why cross-platform tools haven't eliminated the dual-write burden.
Tech

One CDN SRE Tracks a Thousand Dollar Spike to a Single Misconfigured Cache Key

By Sara Park/Jul 18, 2026

How a single misconfigured cache key caused a $1,000 CDN spike overnight, and what it reveals about the economics of edge infrastructure in 2026.