9 minute read

TL;DRWhen leaders say their product is too complex for continuous delivery, they are describing years of underinvestment in quality. Measure build, self-test, deploy and learn times, fund the constraint they expose, and accept that paying the debt down takes years and money.
This piece argues
  1. Complexity is an excuse, not a real blocker, for achieving continuous delivery in any software system. see why — jump to the section that argues this
  2. Any software system, regardless of complexity, architecture, or purpose, should be updated, tested, and deployed in a continuous flow without delays or manual interventions. see why — jump to the section that argues this
  3. Continuous delivery is achievable for every software product if the organisation is willing to invest time, effort, and money in enabling it.
What to do
  • Stop hiding behind “complexity” and commit organisational time, effort, and money to enable continuous delivery for your product.
  • Automate everything you can today and create a plan to rework your architecture until anything remaining can also be automated.
  • Adopt Trunk-Based Development, feature flags, and shift-left practices so code is always in a deployable state and feedback loops are short.

When a leader tells me their product is too complex for continuous delivery, they are not describing the software. They are describing what the organisation has chosen to fund. Complexity is the symptom. Years of underinvestment in quality are the cause. Leaders own that cause, and they can start reversing it without first committing to a transformation programme. There are real exceptions, and I deal with them below, but in my experience they are rarer than the people citing them think.

That is not an accusation aimed at engineers. The people writing the code did not decide how much time quality would get. Those decisions were made above them, usually without anyone saying them out loud, and the bill has been arriving ever since.

How complexity is manufactured

My position is simple. If you put people under pressure to deliver, they will increasingly and systematically decrease quality to meet whatever deadlines you give them. Quality is the only variable they control, so it is the one that gives.

Each shortcut is reasonable in isolation. A test skipped to hit a date. A branch kept alive because merging is painful. A manual deployment step nobody has time to automate. Together they become technical debt, and debt makes every release slower and riskier. Slow, risky releases get labelled “complexity”. That label then becomes the reason not to invest, which adds more pressure, which produces more shortcuts. Once you see the loop, “too complex” stops sounding like a fact about the product and starts sounding like a decision that keeps getting renewed.

What the loop looked like at Microsoft

Microsoft’s Developer Division, responsible for Visual Studio, Team Foundation Server and the tools that became Azure DevOps, is the clearest case I know. The figures that follow are ones I can vouch for from my time working with them. They are my report, not a published dataset.

Before 2010 the division ran a two-year release cycle and a four-year customer feedback loop. A customer could ask for something and wait four years to find out whether it had been understood. Quality was deferred to the end of each cycle, and getting Visual Studio 2010 out of the door meant fixing around 75,000 bugs. That number does not prove the cause on its own, but it shows what deferred quality looks like when it finally falls due.

That was the loop in full. Long cycles hid the debt. The debt made the next cycle longer. The product looked enormously complex, because by then it was.

What changed was not the product. The division chose to pay the debt down, deliberately, over several years. They moved to a three-week cadence; Microsoft describes that release rhythm in how Microsoft develops with DevOps. Feature delivery went from about 25 a year to 58 after the first year of investment, over 250 after four years, and settled at just over 300.

Be honest about what that took: years, not a quarter, and real money spent on engineering capacity that was not producing features while it was being spent. Anyone who sells you continuous delivery as a quick win is not describing what it took at Microsoft.

Where the claim stops

I am not claiming every product, regardless of context, can release every few minutes. The claim is narrower and harder to escape. Most products called “too complex” are carrying debt, and the debt can be paid down.

Regulated industries are the objection I hear most. Regulation usually governs what you release to customers and what evidence you keep, not how often you integrate and deploy. Separate deploying from releasing, so code can reach production switched off. Then build the compliance checks into the pipeline, so the evidence is produced on every change instead of being assembled by hand before an audit.

Safety-certified and hardware-bound products are genuinely harder. Certification cycles and physical manufacturing impose real limits. Even there, the software that sits behind the certified boundary usually suffers from the same loop, and the same measurement applies.

What would prove me wrong? An organisation that invested sustainably in these practices, over years, and still could not release on a cadence that matched its planning horizon, the length of time over which it can usefully commit to a plan, for reasons intrinsic to the product. I have not met one. That does not mean it cannot exist, and if you are in one, the measurements below will show it.

Measure four times first

Do not start with a transformation. Start by measuring. In 2018 Buck Hodges, from the Azure DevOps team at Microsoft, described four times that expose where the flow of work is stuck. Like the figures above, this is my report from working with that team:

  • Time to build: how long a developer waits, after a change, to know the code compiles on their own machine.
  • Time to self-test: how long the automated tests take to run locally after that build. Slow tests mean developers stop running them, which means defects are found late.
  • Time to deploy: how long it takes to get a build into production.
  • Time to learn: how long from deployment until you have usage data or feedback that tells you whether the change worked.

Engineering can start measuring all four tomorrow without anyone’s approval. Do not mistake that for engineering owning the results. Build and self-test times are largely in engineering’s hands. Deploy and learn times usually depend on decisions leaders own: change approval boards, release windows, environment provisioning, whether anyone funded telemetry. If time to deploy is a month because of a monthly approval meeting, no amount of engineering effort fixes it.

These four times are not the only measures that matter, and they focus on the engineering part of the lifecycle. They are a good first move because they are cheap to collect and hard to argue with. They also connect directly to two Key Value Areas in Evidence-Based Management. Time to deploy and time to learn contribute to Time to Market. Slow build and self-test times are a direct drag on your Ability to Innovate, because every change costs more than it should.

Fund the constraint, then sequence the practices

The measurements will usually point at the largest constraint in the delivery pipeline; if none of the four is slow, look upstream, at portfolio, funding and approval decisions. Fund that constraint, not a general “DevOps initiative”. The practices that follow depend on each other, so the order matters.

Automation and fast self-test come first. Automate builds, tests, deployments, environments, certificates and secrets. If something cannot be automated today, plan the architectural change that makes it possible. Move quality checks, including security and performance, as close to the moment of writing code as you can, so problems are found in minutes rather than in a staging environment weeks later. Without fast, trustworthy tests, nothing else in this list is safe.

Trunk-based development comes second. Long-running branches, and promotion through branches, hide integration problems until the most expensive moment. Supporting several versions at once multiplies the load on everyone. Trunk-based development means everyone integrates continuously into a single shared branch; Microsoft’s summary of the shift is that everyone works in the main branch. Try this before the tests are fast and reliable, and main will be broken most of the time.

Feature flags come third. Once code integrates continuously, flags let you deploy unfinished or unproven work switched off, then expose it gradually. That is how you separate deploying from releasing. It is also how you test in production with real users and real data, rather than guessing which features matter.

Iterate over pain, throughout. Anything that is hard or error-prone, releasing included, should be done more often, not less. Repetition exposes the weak points and forces you to fix them. Avoiding the pain keeps it a permanent risk.

You also need a rule that stops the debt building up again. Microsoft’s teams use a bug cap, described in how Microsoft plans with DevOps: the number of engineers multiplied by five. If a team exceeds it at the end of a sprint, feature work stops until it is back under. That is one example of a remedy, not the only one. The point is that someone with authority has decided quality is not the variable.

How fast is fast enough

How short your release cycle needs to be is a business question, and the answer is your planning horizon, defined above. Ship slower than that horizon and you are always delivering answers to last season’s questions.

From what I have seen directly, the horizon varies enormously. For Starbucks point-of-sale it was around 48 hours. For Windows it was around 120 hours. For Facebook it was a few minutes. Those are illustrations, not targets. Work out yours, then compare it with your measured time to deploy and time to learn. The gap between them is the size of the problem.

Subscribe to Martin's articles

Writing since 2001

Articles, usually weekly on Mondays. One click to leave.

By subscribing you agree to the terms and privacy policy.

Your next step, and what it costs

This week, measure the four times on one product. Use whatever data you already have, even if it is rough. Put the numbers in front of the people who fund that product, and identify which of the slow times are caused by decisions leaders own and which are engineering work.

Then ask them to fund the single largest constraint, starting with any delay leaders own, because no amount of engineering effort removes it. How much capacity that takes is set by what the measurements show, not by a rule of thumb, but it means taking real capacity away from new features for a sustained period, and holding that line when the next deadline arrives. It will cost delivery in the short term. At Microsoft, the payback came over years, not months. The alternative is to keep paying the same bill in slow releases, production incidents and missed opportunities, and to keep calling it complexity.

Was this useful?

Checking…

Enjoyed this? One click, no account.

Checking…
Checking… Subscribe

Questions this answers

Is continuous delivery really possible for complex or legacy enterprise systems like ours?

Yes. The article argues that every software system—no matter how complex, archaic, or regulated—can achieve continuous delivery if the organisation is willing to invest time, effort, and money in automation, architecture modernisation, quality, and continuous improvement. It uses Azure DevOps, Starbucks, and Microsoft’s Developer Division as evidence that complexity is an excuse, not a real blocker.

What metrics should we use to measure and improve our software delivery velocity and DevOps performance?

You should measure four engineering-controlled flow metrics—Time to Build, Time to Self‑Test, Time to Deploy, and Time to Learn—alongside broader Evidence‑Based Management Key Value Areas: Current Value, Unrealized Value, Ability to Innovate, and Time to Market. Together these provide both a view of engineering flow bottlenecks and a balanced, outcome-focused view of product and organizational performance.

Also published on Scrum.org.