Software projects rarely fail on a single day. They decline gradually, sending warning signs for months, and the signs are usually visible to anyone paying attention — including a non-technical founder who knows what to look for. Catching them early is the difference between a course correction and a rescue.
The signs worth acting on
Watch for these, especially in combination:
- Releases keep slowing down. Each new version takes longer than the last, and no one can quite say why. This is the clearest single signal that something structural is wrong.
- Small changes break unrelated things. A minor tweak in one area causes a failure somewhere nobody touched, which means the parts of the system are tangled together in ways the team can’t see or control.
- Nobody can estimate confidently. When “how long will this take?” is met with long pauses and wide guesses, the team has lost its grip on how the system actually behaves.
- The team is afraid to deploy. If shipping a change feels like a risky event rather than a routine one, the safety net of tests and automation isn’t there.
- Critical knowledge lives in one person’s head. If a single individual has to touch every change, the project has a bus factor of one and a bottleneck by design.
- The bug list grows faster than it shrinks. Fixing one thing reliably breaks another, so the backlog only ever climbs.
- The roadmap has quietly stopped. All the effort goes into staying upright (patching, firefighting, “stabilising”) and no new features ship for weeks.
Any one of these can have an innocent explanation. Several at once is a pattern, and the pattern is that the project’s foundations can no longer support the work being piled on them.
Symptoms are not causes
The mistake teams make is treating the visible symptom as the problem. The missed deadline, the embarrassing bug, the slow release: these are surface effects. Pushing harder on them, or adding people, usually makes things worse, because the cause is structural and untouched.
The causes tend to be unglamorous and consistent: no automated tests, so nothing catches a regression until a user does. No controlled way to change the data layer, so a single change can break the live product. Manual, undocumented deployment, so shipping depends on one person remembering the steps. An architecture that grew by accretion until no one understands the whole. Fix the symptom and it returns next week. Fix the cause and the symptoms stop on their own.
What to do when you see them
The response is not to add features faster or hire more people into the mess. It is, in order:
- Diagnose honestly. Read the actual state of the code, the infrastructure, and the way the team works, and separate what is genuinely dangerous from what is merely untidy.
- Stabilise before building. Get enough test coverage and deployment safety in place that the team can change things without holding its breath. This feels like a detour and is in fact the fastest route forward.
- Decide deliberately what to fix and what to replace. Some of a troubled system is recoverable with targeted work; some of it is fighting its own foundations and is better rebuilt. That judgement should follow the diagnosis, not precede it.
The earlier this happens, the cheaper it is. A project showing two or three of the signs above is far easier to recover than one that has been ignored until it can no longer ship at all. If the system you depend on is showing them, an honest diagnosis is exactly where our project rescue work starts.