Skip to content

Engineering

Shipping fast without breaking things

Michael Wayman · Sep 8, 2026 · 4 min read

Small changes passing through three automatic checks on the way to a release.

Most people assume that shipping fast means cutting corners, and that shipping carefully means moving slowly. After more than a decade of building production software, I have found the opposite to be true. The teams that ship the fastest are the ones that can change their software without being afraid of it.

Fear is what slows teams down. If every release might break something in a way nobody can predict, releases become rare, large and stressful, and that makes them riskier still. The way out is not more caution. It is a better safety net. Here is what goes into the one I build on every project.

Keep every change small

A small change is easy to review, easy to test and easy to undo. When something goes wrong after a small release, there are only a few places to look. When something goes wrong after a huge one, you are debugging a month of work at once.

I aim to merge to the main branch every day or two, even when a feature is not finished. Unfinished work stays invisible to users, and the code keeps moving in small steps with everyone else's. The alternative, a long-lived branch that lands all at once, is where most painful surprises come from.

Let the machine do the boring checks

Every change should pass the same automated checks before it can ship: formatting, type checking, tests, and a real build. None of this is glamorous, and all of it pays for itself the first time it catches a mistake at two in the afternoon instead of two in the morning.

Static typing deserves a special mention. At a previous company I led an effort to add types across a large Python and React codebase. It did not add features, but it removed an entire category of production regressions and made new engineers productive sooner, because the code explained itself. On a new project, I turn on the strictest reasonable settings from day one, when it costs almost nothing.

Tests work the same way. I do not chase a coverage number for its own sake. I write tests around the parts of a system where a mistake would be expensive: money, permissions, data migrations and anything with tricky rules. Those tests are the ones that let you change the code with confidence.

Separate deploying from releasing

Deploying code and turning a feature on for users do not have to be the same moment. A feature flag lets you ship the code quietly, switch it on for yourself, then for a few customers, then for everyone, and switch it off again in seconds if something looks wrong.

const flags = { newCheckout: false } as const

export function checkoutFlow(user: User) {
  // Ship the code now, turn it on for a few users later.
  return flags.newCheckout || user.isBetaTester
    ? renderNewCheckout()
    : renderCurrentCheckout()
}

This idea is simple, and it changes the emotional weight of a release. Nothing is irreversible, so nobody has to hold their breath.

Make problems visible quickly

No safety net catches everything. What matters then is how fast you find out. I set up error reporting, basic performance monitoring and a few alerts on the things that hurt most, such as failed payments or failed sign-ins, before the first release.

I also make rolling back boring. Every deploy should be reversible with a single command, and the team should have practiced it. The best time to learn how to roll back is not during an incident.

Use AI assistants, but deliberately

AI coding tools have made me faster, and I use them every day. They also make it easy to produce a lot of plausible code that nobody has thought hard about. My rule is to write down what I want first, in a short specification that explains the behaviour and the edge cases, then let the assistant help with the implementation and review every line as if a new colleague wrote it. The checks above apply to generated code exactly as they apply to mine.

What this means if you hire me

You should expect small, frequent releases you can see and try, a preview of the work at any time, and a system that keeps its own guard rails up after I leave. Speed comes from that foundation, not from skipping steps.

If you have a product that feels risky to change, or a team that has slowed down for fear of breaking things, that is exactly the kind of problem I like to help with. Get in touch and tell me where it hurts.

Have a project in mind? Let us talk.

Get in touch