When I first started working on late software programs, I thought the problem was usually one of a few things: bad estimates, underperforming engineers, or unclear requirements. Sometimes it was. More often, the problem was structural — and no amount of additional effort was going to fix a structural problem.
Here’s what I’ve learned.
Why programs go late — the actual reasons
Scope isn’t controlled. Requirements change, stakeholders add features, and the team keeps absorbing changes without adjusting the timeline. By the time someone calls the program late, the original scope has grown 40% and the timeline hasn’t moved.
Coordination cost is invisible. Teams measure developer hours but not the time lost in handoffs, blocked tickets, unclear ownership, and waiting for decisions. In my experience, coordination overhead accounts for 20-40% of lost capacity in troubled programs.
Technical debt is being paid at runtime. Teams spending significant time on bugs, rework, and fragile deployments are paying interest on accumulated debt. The rate of delivery slows without any single obvious cause, and the team attributes it to “complexity.”
Leadership is optimizing for confidence, not reality. Status reports are green, stand-ups are positive, and nobody wants to be the person who says the program is in trouble. By the time the news surfaces, the timeline has slipped much further than it needed to.
What actually works
Get an accurate picture, fast
Before any intervention, you need to know what’s actually true. That means:
- What has shipped and what hasn’t
- What the real remaining scope is, including the informal commitments no one has written down
- Where the blockers actually are — not the reported blockers, the actual ones
- How the team is spending its time (estimate, don’t measure to the hour)
This usually takes less than a week if you’re willing to have direct conversations.
Separate the scope problem from the execution problem
Most late programs have both, but they require different interventions.
The scope problem is a stakeholder problem. Someone has authority to cut or adjust scope, and that conversation has been avoided. Have it. The alternatives — overtime, heroics, quality cuts — are slower and more damaging.
The execution problem is a process problem. Where does work stall? What’s the leading indicator that a ticket is going to slip? Fix the system, not the individuals.
Fix the feedback loop first
If you can’t tell in 24 hours whether work is on track, you can’t course-correct. Most troubled programs have feedback loops measured in days or weeks — which means by the time a problem surfaces, it’s already expensive.
Shorter iterations, daily visibility into blockers, and clearer definitions of done are usually available without any new tooling.
Reduce coordination overhead aggressively
Identify the five biggest sources of coordination friction and eliminate or reduce each one. Typical culprits:
- Handoffs between teams with unclear interfaces
- Approval processes that block progress but add little value
- Unclear ownership leading to repeated escalations
- Meetings that consume planning time without producing decisions
Don’t ask the team to go faster — ask them what’s slowing them down
This is a small reframe with a large impact. “Go faster” tells engineers the problem is effort. “What’s slowing you down?” tells them you’re treating it as a systems problem — which it usually is.
What doesn’t work
Adding headcount to a late program. Brook’s Law is real. New engineers require onboarding, increase coordination cost, and slow down the team in the short term. Adding people helps only if there’s clearly scoped, parallelizable work and enough capacity to onboard them properly.
Cutting quality. Deferring testing, skipping code review, and taking on more technical debt speeds you up for a few weeks and then slows you down for months. I’ve never seen this trade pay off.
Putting engineers on a performance plan mid-program. If someone is a genuine performance problem, that conversation has to happen — but it’s not a recovery strategy. It’s a distraction during a period when the team needs stability.
The honest conversation you probably need to have
In most late programs I’ve worked on, there’s one honest conversation that hasn’t happened: “We cannot deliver the original scope on the original timeline, and we need to decide what to cut.”
That conversation is uncomfortable. It involves telling someone something they don’t want to hear. But it’s faster, cheaper, and less damaging than the alternative — which is running the program into the ground while everyone pretends it’s still recoverable.
The sooner that conversation happens, the more options you have.