The single biggest reason software projects fail
It is not bad developers. It is not bad tools. It is bad scope.
Bad scope means starting to build before understanding the full problem. It means the first requirements document is also the last one. It means discovering that two core features contradict each other on week six.
We have been called in to rescue dozens of failed projects. The pattern is almost always the same: someone started building before the thinking was done.
Here is the framework we use to scope every project we take on.
Step 1: Separate the problem from the solution
The first thing most clients bring us is a solution: "we need a mobile app" or "we need a dashboard." We push back and ask: what is the problem?
A mobile app might be the right answer. But it might also be a three-field web form. We will not know until we understand the problem.
Before writing a single requirement, answer these four questions:
- What process is currently broken, slow, or manual?
- Who is affected, and how often?
- What does the current workaround cost in time or money?
- What does success look like — specifically?
This exercise typically cuts proposed scope by 30-40%. Features that seemed essential become optional. The real bottleneck becomes obvious.
Step 2: Define what is in scope, out of scope, and deferred
Every scope document needs three columns, not one.
In scope is what gets built in this phase. Be specific: "user can submit a request form" not "user management."
Out of scope is what you are explicitly not building. Write this down. It will save you from arguments later. "Notifications are out of scope for v1" is a contract, not a comment.
Deferred is what you want eventually but not now. This keeps the wishlist alive without polluting the current project.
This three-column structure forces prioritization conversations to happen before they are expensive.
Step 3: Estimate by complexity category, not hours
Hourly estimates for software are fiction. Nobody knows how long something takes until they are building it.
What you can estimate with confidence is complexity category:
- Simple: One data model, no external integrations, CRUD operations. Example: a basic form that saves to a database.
- Medium: Multiple models with relationships, one or two integrations, custom logic. Example: a booking system with calendar sync.
- Complex: Real-time features, complex business logic, multiple integrations, high data volume. Example: a multi-tenant SaaS billing platform.
Price complex features generously. Price simple features exactly. Never confuse them.
Step 4: Define milestones, not a launch date
Single launch dates are single points of failure. One delay cascades into everything.
Structure delivery in milestones, each with:
- A specific deliverable (what can the client see and test)
- Acceptance criteria (what does "done" mean)
- A payment milestone (aligns incentives)
Three to five milestones is the right number for most projects. More than that and tracking overhead exceeds the value.
Step 5: Nail down the data model before UI
This is the most violated rule in software scoping. Clients want to see mockups. Developers want to show mockups. But the UI is a consequence of the data model, not the other way around.
Before designing a single screen, answer:
- What are the core entities? (user, order, property, appointment, etc.)
- What are the relationships between them?
- What data must be stored vs. computed?
A solid data model catches requirement conflicts early. Two features that seem independent often share a table — and if those features were specced without talking to each other, you have a problem.
Step 6: Identify every external dependency
APIs that might be rate-limited. Payment processors that take a week to provision. Government databases that are down 30% of the time.
External dependencies are scope multipliers. One integration that fails blocks everything downstream.
Map every external system the project depends on. Confirm access before signing a timeline.
The anti-patterns to avoid
The moving target: Scope that changes every week. Avoid it by locking requirements per milestone, not per project.
The 10% feature: The single feature that is "only 10% of the work" but accounts for 60% of the delays. Identify and time-box these early.
The undefined user: Requirements written without a specific user in mind. Every requirement should name the user it serves.
The integration assumption: Assuming a third-party API will behave as documented. It often will not. Build in buffer.
Good scoping is not glamorous work. It is the difference between a project that ships and one that does not.