The Friday Deploy
The plain English newsletter for people who run the business, not the tech stack. No jargon. Every Friday.
Database Performance Problems: When Queries Take Too Long
Your Rails application has been running fine for months. Then your developer sends you a message: “We’re seeing slow database queries. Some pages are taking 5-10 seconds to load. We need to add some indexes and optimise a few queries.”
You’re not sure if this is urgent or routine maintenance. Is this something that needs fixing today, or can it wait until next sprint? And how much is this going to cost?
Here’s what’s actually happening and how to make informed decisions about database performance.
What Database Performance Problems Look Like
You don’t need to understand SQL to recognise when something’s wrong. Here’s what slow database queries actually look like:
Pages that load slowly or time out. A product listing page that used to load in under a second now takes five or ten seconds. Your admin dashboard times out halfway through loading.
Performance that degrades at specific times. Everything works fine at 9am but crawls by lunchtime when traffic picks up. Or it’s fine all week but terrible on Sunday when you run reports.
Certain features are slower than others. Search takes forever while browsing works fine. Checkout is painfully slow while the homepage loads instantly. The pattern tells you which queries need attention.
These symptoms point to database queries that need optimisation.
Why Database Performance Matters to Your Business
Slow queries aren’t just annoying. They have measurable business impact:
Direct revenue loss. Research from Google found that delays in page load can significantly reduce conversion rates. While the specific impact varies by context (their study showed 0.1 seconds reducing search query engagement by up to 10%), the principle holds for e-commerce: if your checkout queries take five seconds instead of half a second, you’re losing sales. Every extra second costs money.
Wasted employee time. If business intelligence reports take 20 minutes to run instead of two, your analysts spend hours each week waiting instead of analysing. That’s expensive time you’re paying for but not getting value from.
Increased infrastructure costs. Inefficient queries force your database to work harder. You might be paying for more server capacity than you actually need just to compensate for slow queries.
Problems that compound as you grow. A query that’s acceptable with 1,000 records becomes unbearable with 100,000. Database problems that seem manageable today can prevent you from scaling tomorrow.
The Library Catalogue Analogy
Think of your database like a library with millions of books. When someone asks for information, the database needs to find the right records.
Without indexes: The database scans every record from start to finish, like searching for a book by checking every shelf in order. This works fine with 100 books but becomes painfully slow with 100,000.
With proper indexes: The database jumps straight to the relevant records, like using a library catalogue to find exactly which shelf holds your book. Fast with any size collection.
Most database performance problems come down to missing indexes or queries that aren’t written efficiently. The database is working much harder than it needs to.
Common Causes of Slow Queries
Missing Indexes
This is the most common database performance problem. When a column doesn’t have an index, the database must scan every single record to find matches.
Example in Rails:
# Slow: scans all 100,000 users
User.where(email: 'customer@example.com').first
# After adding index: finds user instantly
add_index :users, :email
Without the index, finding one user requires checking all 100,000 records. With an index, the database jumps straight to the right record.
Your developer can usually spot missing indexes by looking at which queries are slow. Adding indexes typically takes minutes to hours depending on table size (small tables are quick, large multi-million row tables can take longer), and can reduce query time from seconds to milliseconds.
Fetching Too Much Data
Sometimes queries request more data than necessary. This is like downloading an entire encyclopedia when you only need one paragraph.
Example:
# Slow: loads every column for 1,000 products
@products = Product.all
# Fast: loads only needed columns
@products = Product.select(:id, :name, :price)
If you’re displaying a product list that only shows name and price, there’s no reason to load descriptions, specifications, and inventory history. Fetching less data means faster overall response time (both from reduced database work and less memory allocation in your application).
N+1 Query Problems
We covered this in detail in N+1 Queries Are Killing Your Rails App: How to Find and Fix Them, but it’s worth mentioning here. N+1 problems happen when your application makes dozens or hundreds of separate database queries instead of one efficient query.
This compounds with scale. With 10 products on a page, 11 queries might be fast enough. With 100 products, 101 queries grinds to a halt.
Lack of Query Optimisation
As your application evolves, queries written for small datasets become inefficient with large datasets. A query that worked fine with 1,000 orders might slow down dramatically with 100,000 orders.
# Inefficient: loads records then calculates in Ruby
Order.where(status: "pending").map(&:total_price).sum
# Optimised: lets the database do the calculation
Order.where(status: "pending").sum(:total_price)
The first approach loads every pending order into memory, converts each to a Ruby object, extracts the price, then sums them. The second approach tells the database to calculate the sum directly using SQL’s built-in SUM() function.
With 10 orders, the difference is negligible. With 10,000 orders, the optimised version can be 100x faster because it avoids loading unnecessary data into memory.
Questions to Ask Your Developer
When your developer reports slow queries, here’s what to ask to understand the scope and urgency:
“Which queries are slow? Can you show me the actual numbers?”
There’s a big difference between a query taking 500ms instead of 50ms, versus one taking 10 seconds instead of 2 seconds. Ask for specific measurements.
Good answer: “The product search query is taking 3-5 seconds. It should be under 200ms. I can show you the logs.”
Red flag: “Everything is just really slow” without specifics.
“What’s causing it? Missing indexes or something else?”
Understanding the root cause helps you evaluate the fix. Missing indexes are straightforward. Architectural problems are more complex.
Good answer: “The orders table doesn’t have an index on customer_id, so filtering orders by customer scans all 50,000 records.”
Red flag: “The database is just old and slow” without investigation.
“How long will it take to fix?”
Most index additions and query optimisations take hours, not days. Major structural changes take longer.
Realistic: “Adding indexes will take about 4 hours. Optimising the three slowest queries will take another day.”
Suspicious: “We need two weeks” for simple optimisation (might indicate they’re tackling everything at once unnecessarily).
“What’s the risk if we do nothing?”
Some slow queries are annoying. Others will get worse as your data grows.
Helpful: “Right now it’s impacting the admin panel. In three months when we hit 100,000 records, it’ll start affecting customers too.”
Less helpful: “Everything will break” without explaining the timeline or specifics.
“How do we prevent this happening again?”
One-off fixes are fine, but if you’re constantly firefighting performance, something’s wrong with your development process.
Good sign: “We should add query performance checks to our code review process and set up monitoring to catch slow queries before they hit production.”
Concern: “We’ll just fix issues as they come up” (reactive rather than preventive).
What Fixing Slow Queries Costs
Most database performance fixes fall into three categories:
Quick wins (4-8 hours of developer time): Adding the right indexes is usually straightforward. Your developer identifies which columns need indexing, adds them, and verifies performance improves. This typically takes a few hours and can reduce query time from seconds to milliseconds (though some query patterns require specific index types to benefit).
Impact: Immediate, dramatic improvement for specific queries. Often fixes 80% of noticeable performance problems.
Query optimisation (1-2 days): Rewriting inefficient queries requires more time. Your developer needs to understand what the query does, identify why it’s slow, write a more efficient version, and test that it produces correct results.
Impact: Addresses problems that can’t be fixed with indexes alone. Particularly valuable for complex reports or searches.
Infrastructure changes (variable): If you’ve genuinely outgrown your database server, upgrading infrastructure costs money. Cloud hosting makes this straightforward (scale up your database instance) but not cheap.
Impact: Provides immediate relief while you work on proper optimisation. Scaling up your database server can buy you time to fix underlying query problems without customer impact. However, it’s treating the symptom rather than the cause.
When to consider: If you’re hitting CPU or memory limits consistently and need immediate relief, infrastructure upgrades work fast. But they should be temporary relief while you optimise queries, not a permanent solution to inefficient code.
When to Prioritise Database Performance Fixes
Not every slow query needs immediate attention. Here’s how to decide:
Fix immediately if:
- Customer-facing features are timing out or breaking
- Checkout, payment, or core transaction flows are affected
- Performance is degrading rapidly (getting worse by the hour)
- You’re losing measurable revenue from slow pages
Fix within the week if:
- Admin tools are slow but still functional
- Reports take much longer than they should
- Performance has noticeably degraded but workarounds exist
- The problem is stable rather than accelerating
Schedule for next sprint if:
- Only internal tools are affected
- Performance is slower than ideal but acceptable
- The problem only occurs during low-traffic periods
- You’re planning for growth and want to address it proactively
What about infrastructure upgrades?
Infrastructure upgrades (scaling up your database server) provide instant relief for performance problems. If you’re in crisis mode with customers complaining, upgrading can stop the pain immediately while you work on proper fixes.
However, be sceptical if your developer immediately suggests expensive infrastructure upgrades without first attempting query optimisation. Most performance problems can be solved with better queries and proper indexes at a fraction of the cost.
Use infrastructure upgrades for:
- Immediate relief during a performance crisis (buy time to optimise properly)
- Situations where you’re genuinely hitting hardware limits after optimisation
- Planning ahead for significant growth (scale before you hit limits)
- Consistent CPU or memory constraints that persist despite query optimisation
Get a second opinion before:
- Spending more than a few thousand dollars on infrastructure
- Upgrading without first attempting query optimisation
- Making infrastructure changes your primary performance strategy
An independent technical review can confirm whether you actually need more hardware or whether optimisation would solve the problem for much less money. Infrastructure should complement optimisation, not replace it.
Long-Term Prevention
Once immediate problems are solved, implement these practices to prevent recurrence:
Performance monitoring: Tools like Scout, New Relic, or Skylight (for Rails) automatically track slow queries in production. They alert you before problems affect customers. Setting these up costs a few hundred dollars monthly but prevents expensive performance crises.
Query review in code reviews: When reviewing new features, experienced developers specifically look for queries that might cause problems at scale. Catching inefficient queries before they reach production is much cheaper than fixing them later.
Load testing with realistic data: New features should be tested with production-scale data volumes before launch. A query that works fine with 100 test records might crawl with 100,000 real records.
Regular database maintenance: Automated tasks should update statistics, rebuild indexes, and clean old data. This prevents the gradual performance degradation that accumulates without maintenance.
The Bigger Picture
Database performance problems are common in growing applications. Queries written for small datasets become slow as your data volume increases. This is normal and expected.
If your developer proactively identifies slow queries and suggests specific fixes (adding indexes, optimising queries), that’s a good sign. They’re thinking about performance and scalability, not just delivering features.
The conversation shouldn’t end at “we have slow queries.” Better questions: Which queries specifically? What’s the business impact? What are the options and costs? How do we catch these earlier?
Most database performance problems can be fixed with a few hours of work. Adding indexes and optimising queries delivers immediate, measurable improvements. The key is prioritising based on business impact. Fix queries that affect revenue first, implement monitoring to catch new problems early, and you’ll prevent this from becoming a recurring crisis.
Read more Technical Deep Dives
Database, MySQL, Optimisation, Performance, PostgreSQL, Rails
Previous NextThe Friday Deploy
The plain English newsletter for people who run the business, not the tech stack. No jargon. Every Friday.