[ Development ]

PostgreSQL Consulting & Performance Tuning

Postgres is rarely the problem. How it's used usually is.

Most slow PostgreSQL databases are not short on hardware. They are missing an index, running a query the planner cannot help, holding connections they do not need or carrying years of bloat. I find which one, fix it, and show you the before-and-after plan so you know it was the real cause.

Measured before and after · No changes without a rollback · Written findings

EXPLAINbefore any change
Measuredbefore and after
Rollbackplanned for every change
Writtenfindings you keep

[ Why teams call ]

What I usually find in a slow Postgres.

Almost never one dramatic mistake. Usually a handful of small ones that compound as the data grows.

Queries that got slow gradually

Fine at ten thousand rows, painful at ten million. A sequential scan the planner had no alternative to, or a sort spilling to disk because work_mem was never touched.

Too many indexes, and the wrong ones

An index on every column, none of them matching the actual WHERE and ORDER BY, and every write paying for all of them.

Connection exhaustion

Hundreds of idle connections from app servers and serverless functions, each costing memory, until Postgres starts refusing new ones at peak.

Bloat and vacuum falling behind

Autovacuum tuned for a small database, tables several times larger than their live data, and a transaction ID wraparound warning nobody has noticed yet.

Backups nobody has restored

A nightly pg_dump that has never been restored end to end, no point-in-time recovery, and no idea how long a restore would actually take.

Stuck on an end-of-life version

Postgres 11 or 12 out of support, an upgrade postponed because nobody is sure how long the downtime would be or what might break.

[ How it works ]

Measure, fix, prove it.

01  —  Days 1–2

Measure

Read-only access to pg_stat_statements, the slow query log and the configuration. You get a short written list of the queries costing the most total time, and why, before anything is changed.

02  —  Days 3+

Fix

Indexes built CONCURRENTLY, queries rewritten, settings adjusted — tested on a copy or staging first, applied in small steps, each with a rollback.

03  —  Handover

Prove & document

Before-and-after plans and timings for every change, the monitoring queries I used, and notes on what to watch as the data keeps growing.

[ What actually changes ]

What a PostgreSQL engagement covers.

Pick the part you need. A single slow endpoint is a perfectly good reason to get in touch.

Performance

  • Slow query diagnosis — pg_stat_statements to find what costs the most in total, EXPLAIN (ANALYZE, BUFFERS) to see why.
  • Indexing — composite, partial, covering and expression indexes that match real queries, and unused ones removed.
  • Schema design — data types, constraints, partitioning for large time-series tables, and JSONB used where it helps rather than everywhere.
  • Connection pooling — PgBouncer in transaction mode, sized to what the server can actually run, with the prepared-statement caveats handled.
  • Vacuum and bloat — autovacuum tuned per table, bloat measured and reclaimed, wraparound risk checked.
  • Configuration — shared_buffers, work_mem, effective_cache_size and checkpoint settings set for your workload, not left at defaults.

Operations & migration

  • Version upgrades — for example 12 to 16 or 17, via pg_upgrade or logical replication when downtime has to be minutes.
  • MySQL to PostgreSQL migration — schema translation, data type differences, application query changes and a verified cutover.
  • Replication — streaming replicas for reads and failover, with replication lag monitored.
  • Backups and PITR — pgBackRest or WAL archiving with point-in-time recovery, and a restore actually tested and timed.
  • Managed Postgres — RDS, Aurora and Supabase tuned through parameter groups, Performance Insights and sensible instance sizing.
  • Monitoring — the handful of metrics that warn you early: long transactions, lock waits, replication lag, dead tuples.

[ Example engagement ]

Dashboard queries from seconds to milliseconds.

A reporting dashboard on a growing orders table, timing out at peak. Three missing composite indexes, one rewritten query and PgBouncer in front of the app servers.

Illustrative example of a typical engagement. Figures vary with the state of your systems and are not a guarantee of a specific outcome.

3indexes added, 7 unused removed
94%less time in top 10 queries
0downtime during changes
4 daysfrom access to handover

[ Free · no obligation ]

Send me your slowest query.

Paste the query and its EXPLAIN ANALYZE output. You get an honest read on what is wrong and what fixing it would take — often in the same reply.

Send the query

[ Pricing ]

Straightforward pricing. $20/hour or fixed.

Tell me the number you have to work with. I'll tell you honestly what's achievable within it — and if it isn't enough, I'll say so before we start rather than halfway through.

Hourly rate $20/hoursmall jobs and ongoing work · fixed price for defined projects

Fixed project price

Scope agreed in writing, price agreed in writing, before any work starts. No hourly creep and no invoice you haven't already approved.

Monthly retainer

For ongoing work — maintenance, monitoring, updates and small changes. Month to month, cancel whenever, no minimum term.

$20/hour for small jobs

For a single bug, a short task or ongoing tweaks, where writing a full scope would cost more than simply doing the work. Billed in real time, reported in writing.

Budget too tight for the whole thing? I'll often suggest doing the highest-value part first and the rest later, rather than doing all of it badly.

[ Questions ]

Common questions.

What does PostgreSQL consulting cost?

Small, well-defined jobs — diagnosing a slow query, reviewing a schema, checking a backup setup — are billed hourly at $20 per hour. Larger work such as a version upgrade or a MySQL migration gets a fixed price, agreed in writing before I start, so the number does not move.

What access do you need?

For diagnosis, read-only access is usually enough: pg_stat_statements, the configuration and ideally a recent copy of the schema. Changes are applied through your normal process, or by me on staging first and then production with your sign-off.

Do we need a bigger server?

Sometimes, but usually not first. In most databases I look at, a few indexes, one or two rewritten queries and connection pooling buy far more than doubling the instance size — and cost nothing per month.

Can you upgrade us with minimal downtime?

Yes. pg_upgrade with --link keeps downtime to minutes for most databases. Where even that is too long, logical replication to a new cluster lets you cut over in seconds. Either way the upgrade is rehearsed on a copy first and timed.

Can you migrate us from MySQL to PostgreSQL?

Yes. The data transfer is the easy part; the real work is data type differences, case sensitivity, auto-increment versus identity columns and queries that relied on MySQL being lenient. I migrate on a copy, run your test suite against it and plan a cutover with a way back.

Do you work with RDS, Aurora and Supabase?

Yes. Managed Postgres removes the server administration but not the query, index and connection problems. Tuning goes through parameter groups and the provider's tooling rather than postgresql.conf, and I know where each one differs.

Can you work alongside our developers?

Yes, and that tends to give the best result. I explain why each query was slow and what the planner was doing, so your team avoids writing the next one. Changes arrive as normal migrations and pull requests.

Where are you based, and what hours do you work?

I work remotely with clients in the US, UK, Europe, Canada and Australia. Most of the work is asynchronous, and I overlap with your working hours for calls and for any change that touches production.

[ Let's talk ]

Send me the slow query.

Describe the symptom or paste the query and its plan. You'll get a straight answer on what is wrong and what fixing it costs — from the person who would actually do the work.