1. Small changes take surprisingly long
When a change everyone expected to be quick takes a fortnight, the structure is fighting the business. That is the honest test for whether this is a rewrite case or just untidy code.
2. The business runs in spreadsheets alongside it
A parallel process in a spreadsheet is a specification for the software you don’t have. You are already paying for it, in salaries and errors — the awkward-shape signal.
The spreadsheet beside the system is the requirements document nobody wrote.
3. Only one person can deploy or fix it
A single point of failure with a holiday schedule. Whatever else is true, it is not production-ready until someone else can run it.
4. Problems reach you from customers first
If failures are reported rather than alerted, you are blind to everything that fails quietly — scheduled jobs and integrations especially.
5. Nobody can explain a decision it made
The system knows its current state and nothing about how it got there. That blocks disputes, audits, and any future automation — the instrumentation gap.
6. It has grown slower without anything changing
Data volume outgrowing the design shows up as gradual degradation. Usually queries and indexes rather than anything architectural — measure before concluding.
Any one of these is a specific, fixable problem. Together they are the case for attention — and none of them requires anyone to dislike the code.