Database performance
Slow pages and a climbing database bill often come back to the same handful of queries. We find them, fix them, and show you before-and-after numbers from your own workload.
Start a projectWhat’s included
- Performance audit
- Slow query logs, pg_stat_statements or Performance Schema, query plans, index usage, lock waits and connection counts.
- Query and schema fixes
- Rewriting the queries that matter, and the N+1 patterns an ORM produces without anyone noticing.
- Index work
- Adding the missing ones, and dropping the unused and duplicate ones that slow every write.
- Connections and caching
- Connection pooling with PgBouncer or ProxySQL. Redis where it's worth the extra moving part, and not where it isn't.
- Right-sizing
- Instance class, storage and IOPS, read replicas. Often the answer is a smaller instance after the queries are fixed.
- Upgrades and migrations
- Major-version upgrades and engine moves, rehearsed on a copy first, with a rollback plan that has been tested.
- Backup and recovery check
- We restore your latest backup and time it. Many teams find out here that they've never done it.
How it usually runs
- 1. Measure
~1 week
Read-only access to metrics and query statistics. We don't change anything yet.
- 2. Fix
1–3 weeks
Changes in order of impact, each shipped through your normal review and deploy process.
- 3. Prove it
Same metrics, same time window, before and after. If a change didn't help, we say so and roll it back.
What you have at the end
- A ranked list of problems, each with how much it costs you now
- Fixes delivered as migrations and pull requests your team reviews
- Before-and-after measurements on the same workload
- Dashboards for the few metrics worth watching afterwards
One finding from a report, in the format we use:
Order history reads the whole orders table
- What we saw
WHERE customer_id = $1 ORDER BY created_at DESC LIMIT 20runs a sequential scan. The only index is oncreated_at. It’s the most frequent query on the account page.- Fix
CREATE INDEX CONCURRENTLY orders_customer_created_idx ON orders (customer_id, created_at DESC);- Measure
- p95 of this query on production traffic, same 24-hour window, before and after.
Tools and platforms
- PostgreSQL
- MySQL
- MariaDB
- SQL Server
- MongoDB
- Redis
- Amazon RDS & Aurora
- Cloud SQL
- PgBouncer
From our engineering notes
What went wrong, the code that fixed it, and what we do differently now.
Questions we get
What access do you need?
To start, read-only access to monitoring and query statistics. Write access comes later, through your own deploy process, never straight to production.
Should we just move to a bigger instance?
Sometimes that's right. More often a few indexes and query changes do more for less money. The audit tells you which.
Tell us what you're working on.
A few paragraphs is plenty. We'll read it, reply by email, and if it looks like a fit, set up a 30-minute Google Meet with an engineer.