Enterprise software projects don't fail at deployment. They fail at the architecture stage, usually in the first four weeks, when decisions are made quickly under deadline pressure with incomplete information. The code that gets written afterwards just makes the failure visible.
Failure mode 1: Designing for the demo, not the workload
The single most common architecture mistake we inherit from previous vendors is a system designed to handle the demo scenario, not the actual production workload. A CRM that performs fine with 50 test records doesn't tell you how it will behave with 2 million customer records and 200 concurrent users running heavy queries.
We catch this early by asking the client for their actual data volumes — current and projected three years out — and running load modelling before we write a schema. It adds a week to discovery. It prevents months of performance rework later.
Failure mode 2: Shared database, separate teams
Enterprise systems often start as a single application and grow into multiple features owned by different teams. If those features share a database schema without clear ownership boundaries, you get a system where no team can change their data model without coordinating with every other team.
The fix isn't necessarily microservices — that's often too much complexity too early. The fix is clear schema ownership: each feature owns its tables, communicates through defined APIs, and doesn't write directly to another feature's tables. This is achievable in a monolith and prevents the scaling problems that make microservices necessary later.
Failure mode 3: Authentication bolted on after the fact
We've inherited three systems in the past two years where authentication was added after the initial build. In each case, the permission model was inconsistent — some endpoints checked permissions, some didn't, and the rules were distributed across the codebase rather than centralised.
Authentication and authorisation must be designed as first-class architecture concerns, not added as a feature sprint after the core build. This means:
- Choosing an auth pattern (RBAC, ABAC, or a combination) in week one
- Implementing a single permission-checking layer that all routes use — no per-route custom permission logic
- Designing the role and permission model with the actual user types in mind, not abstract 'admin/user' binaries
- Testing auth boundaries as part of every feature, not as a separate security review at the end
Failure mode 4: No plan for schema migration
Enterprise applications live for 5–10 years. The schema you design today will be wrong by year two — not because the design was bad, but because the business requirements changed. Systems that survive this have a disciplined migration strategy from the start.
Our standard: every schema change ships with a migration file, migrations are reviewed like code, and rollback migrations exist for every deployment. This sounds obvious but a surprising proportion of enterprise systems we inherit have schema changes that were applied manually to production.
The architecture review we do before writing code
On every new project, we run a 5-day technical discovery that produces three outputs: a system context diagram, a data model with ownership boundaries marked, and a load model for the first 12 months of production. These three documents make most architectural mistakes visible before any code is committed.