DevOps 2 September 2026 5 min read

What a broken deploy actually costs

A file-by-file deploy left a client site live but unstyled for part of an afternoon. The fix took minutes. The lesson was about what 'deployed' means when a transfer can stop halfway.

A deploy either happened or it did not. That is the assumption most teams work under, and it is wrong for a large category of hosting.

If your deployment copies files one at a time — FTP, rsync without staging, anything that writes into the directory the web server is reading from — then there is a window where the site is neither the old version nor the new one. It is a mixture. And a mixture is a state nobody designed or tested.

How it goes wrong

A deploy that stops partway through leaves the site in a mixed state that still looks healthy from the outside. We hit this on a client staging site: the deploy ran, the connection was throttled partway through, and the transfer stopped after the HTML had been replaced but before the stylesheet was.

The result was a live site serving new markup that referenced a stylesheet the server no longer had. Every page returned 200. Monitoring that checks for a 200 saw nothing wrong. The site was unreadable.

Two details made it worse than it needed to be. The deploy tool kept a state file on the server recording what it believed it had uploaded, so the next run skipped files it thought were already there. And two deployers — a CI job and a local script — were writing to the same directory, each with its own idea of the current state.

The three fixes, in order of value

Deploy to a new directory and switch. Upload the whole build to a fresh folder, then repoint the web root. The switch is one operation, so there is no partial state. Rolling back becomes repointing at the previous folder. This is the fix that removes the class of problem rather than reducing it.

Have exactly one deployer. Either CI deploys or a person does, never both. Two processes writing the same directory with independent state files will eventually disagree, and the disagreement surfaces as missing files.

Check what a user would see, not what the server returns. A 200 proves the server answered. Fetch the deployed page, confirm the stylesheet it references actually returns 200, and confirm a string you expect is present. That check would have caught this in seconds.

Why this bites small teams specifically

Large deployments solved it years ago — containers, blue-green, atomic symlink swaps. Small businesses on shared hosting are exactly where file-by-file transfer is still normal, and where nobody is watching the site at 4pm on a Tuesday.

The cost is not usually revenue. It is that you find out from a client, which changes what they believe about everything else you have built.

The version worth adopting today

If you cannot change how you deploy, add the one cheap thing: after deploy, fetch the homepage, extract the CSS URL from the markup, and request it. If either fails, alert. That is ten lines and it catches most of what partial transfers do.

If you can change how you deploy, deploy to a directory and switch. Everything else here becomes unnecessary.


We build and maintain deployment pipelines for small teams on hosting they already have. If yours is a script somebody runs and hopes about, tell us what it does.

Building something like this?

Tell us what you're trying to do and we'll tell you honestly what it involves.

Start a conversation