01 / 06
Schema and index design
Normalisation where it earns its keep and denormalisation where it is measurably worth the write cost. Constraints that make invalid states unrepresentable rather than merely discouraged.
SERVICE · DATA
Most application performance problems are database problems, and most database problems are schema problems that were cheap to fix three years ago. We do the diagnostic work first — find the actual expensive query rather than the suspected one — then the schema, index, and migration work that makes the fix durable rather than temporary.
THE PROBLEM
Databases accumulate. A column added because a feature needed it, a table that duplicates another because joining was inconvenient at the time, a nullable field that means three different things depending on which code path wrote it, an index added during an incident and never reviewed. Individually these are all rational. Together they produce a report that times out, a migration nobody wants to run, and a growing set of queries that only work because of an index somebody added for a different reason. The other half of this problem is quieter: almost nobody has actually tested restoring from backup, so the recovery time objective on the disaster recovery document is a hope rather than a measurement.
A report or export that times out, and the workaround is to run it overnight.
The schema has been extended rather than designed for several years.
Nobody is confident about the restore path, because nobody has tested it.
Query performance changes after a deployment and nobody can attribute it.
WHAT WE DELIVER
Concrete engineering capabilities deployed as part of this service practice.
01 / 06
Normalisation where it earns its keep and denormalisation where it is measurably worth the write cost. Constraints that make invalid states unrepresentable rather than merely discouraged.
02 / 06
Execution plan analysis against real data volumes and real statistics, finding the query that actually costs the most rather than the one that feels slowest, then fixing it durably.
03 / 06
Version-controlled migrations that run in the pipeline, expand-and-contract sequencing for changes that cannot be applied atomically, and a rehearsed rollback for each step.
04 / 06
Read replicas where read load justifies them, backup schedules matched to a stated recovery point objective, and — the part usually missing — a restore that has actually been performed and timed.
05 / 06
Modelling the domain as it behaves rather than as the first screen displayed it, including temporal data, soft deletion, auditability, and the multi-tenancy boundary if there is one.
06 / 06
Moving between Microsoft SQL Server, MySQL, and PostgreSQL where there is a real reason to, with the dialect, data type, and stored procedure differences handled explicitly rather than discovered.
HOW WE WORK
Milestone-driven delivery, so integration problems surface in week two rather than in week ten.
01
Statistics from the running system: which statements consume the most total time, which tables are actually hot, what the plans look like, and where the waits occur. This routinely contradicts the team's expectation about what is slow.
02
A slow query is a symptom. The cause is a missing index, an unhelpful data type, a schema that forces a join, an object-relational mapper producing one query per row, or statistics that stopped reflecting the data. Each has a different fix and a different durability.
03
Index and statistics work first, because it is reversible and fast. Query rewrites next. Schema changes last, because they cost the most and, done in the right order, are often smaller than they first appeared.
04
Structural change through expand and contract: add the new shape, write to both, backfill, move reads, then remove the old. Longer on paper, and it does not need an outage or a night.
05
Backups verified by restoring them into a scratch environment and timing it. An untested backup is an assumption, and it is the assumption people discover is wrong at the worst possible moment.
TECHNOLOGY DEPTH
The libraries, runtimes, and services we standardise on for this work, and keep patched.
DELIVERABLES & OUTCOMES
We measure success by durable working software in your possession, not presentation slides.
A workload analysis naming the highest-cost statements with plans
Index and statistics changes with before-and-after measurements
Version-controlled migrations that run in the deployment pipeline
An expand-and-contract plan for each structural change, with rollback steps
A timed restore, with recovery objectives stated as measurements
Runbooks for maintenance, failover, and recovery
The report that timed out returning inside its window, for a reason you can explain
Schema changes that ship in a normal deployment rather than a maintenance night
A restore time that is a measurement rather than an estimate
Constraints that make the invalid states the application kept producing impossible
QUESTIONS & ANSWERS
Direct answers to common technical and engagement questions.
PostgreSQL by default for new work: the type system, extension ecosystem, and licensing position are hard to argue with. Microsoft SQL Server where the organisation is already operating it competently and the .NET integration is doing real work. MySQL where it is already in place and running well — migrating a healthy MySQL database purely on preference is rarely worth what it costs.
Often the first round, yes — indexes, statistics, and configuration frequently account for most of the initial gain, and none of that touches your code. Beyond that it depends. Where the application issues one query per row, the fix has to happen in the application, and no amount of database work will substitute for it.
Expand and contract. Add the new structure, write to both old and new, backfill in monitored batches, verify, move reads across, then remove the old structure in a later deployment. Each step is individually reversible, which is why it can run during business hours.
Yes. In Microsoft SQL Server estates a lot of genuine business logic lives there. Some of it should move into tested application code; some of it is set-based work that belongs exactly where it is. We make that judgement per procedure, with reasoning, rather than applying a rule.
We collect query statistics over a representative period, review plans and index usage, examine the schema and constraints, and check the backup and restore position. The output names the specific problems in priority order with the expected effort for each. It is written to be actionable without us, including by an internal database team.
Tell us what you're working on. We'll tell you honestly whether we're the right team for it.