The traditional software agency model works like this: a client has an idea, the agency writes a proposal with a scope document and a fixed price, both parties sign, the agency builds the software, and the client receives a deliverable at the end. This model has been the default for decades. It is also fundamentally misaligned with how good software actually gets built.
The problem is not that agencies are incompetent or that clients are unreasonable. The problem is structural. The incentives baked into the traditional model push both parties toward behaviors that produce worse software, slower timelines, and adversarial relationships. Understanding these structural flaws is the first step toward a better way of working.
The Fixed-Scope Trap
Fixed-scope contracts require defining what will be built before building begins. This sounds reasonable — you would not hire a builder to construct a house without blueprints. But software is not construction. In construction, the design is complete before building starts, the materials are well-understood, and the finished product matches the blueprint within tight tolerances. In software, you discover what needs to be built as you build it.
The first version of a feature is almost never right. Users interact with it in unexpected ways, edge cases emerge, and the client’s understanding of their own requirements evolves. In a fixed-scope contract, these discoveries create a change order process: the client describes what they actually need, the agency scopes the change, provides a quote, and the client decides whether to pay for it. This process is slow (days to weeks per change order), expensive (the agency marks up change orders because they are out-of-scope), and adversarial (both parties argue about whether a request is a “change” or a “clarification” of the original scope).
The result is that clients either pay significantly more than the original estimate (the “real” cost was always higher — the fixed price just deferred the reckoning) or they accept a product that matches the original spec but does not actually solve their problem. Neither outcome is good.
The deeper issue is that fixed scope incentivizes the agency to build exactly what was specified, not what the client needs. If the agency discovers mid-project that a different approach would be better, they face a choice: do the right thing (which means renegotiating scope, absorbing cost, or eating the margin) or do the specified thing (which is easier, billable, and wrong). The financial pressure almost always wins.
Related: What Ship It Actually Means in Software Development
The Handoff Problem
In the traditional model, the agency builds the software and then hands it off to the client. This handoff is where value goes to die.
The agency’s developers understood the system because they built it. They know why that weird if-else clause exists in the payment module (it handles a specific edge case with partial refunds on annual subscriptions). They know that the cron job must run before the reporting dashboard updates. They know that the third-party API has an undocumented rate limit that requires a specific backoff strategy. This knowledge lives in their heads, and no amount of documentation transfer can fully capture it.
The client receives a codebase they did not write, with architectural decisions they do not understand, and a deployment process they have never run. If something breaks on a Saturday night, they are calling the agency — which may or may not be available, and which will charge emergency rates for the privilege.
Some agencies mitigate this with maintenance contracts: ongoing support agreements where the agency remains available for bug fixes and minor enhancements. But this creates its own misalignment. The agency is now incentivized to build software that is complex enough to require ongoing support — not consciously or maliciously, but through subtle choices. Using a proprietary framework the client’s team does not know. Over-engineering an architecture that requires specialist knowledge to maintain. Choosing tools that lock in the dependency.
The cleanest indicator of an agency’s integrity is whether their clients could fire them and maintain the software with a different team. If the answer is no, the agency has built a dependency, not a product.
The Talent Allocation Shell Game
Traditional agencies sell a team composition in the proposal: a senior architect, two mid-level developers, a designer, and a QA engineer. The client evaluates the agency partly on the quality of these individuals. Then the project starts, and the senior architect is on three other projects simultaneously. The “mid-level developers” are actually junior developers being billed at mid-level rates. The designer who wowed in the pitch is not the designer doing the work.
This is not universal, but it is common enough to be a pattern. The economics make it almost inevitable. The agency wins the deal on the strength of its senior talent, but senior talent is scarce and expensive. Deploying senior people full-time on every project would destroy the agency’s margins. So senior people do the proposals, the architecture, and the client-facing presentations, while less experienced developers do the majority of the actual building.
The client usually does not notice until quality issues emerge weeks or months into the project. The code does not match the architectural vision presented in kickoff. Simple features take longer than expected. Bugs appear in areas that should have been straightforward. By this point, raising the issue creates an uncomfortable conversation about who is actually doing the work, and the project is already behind schedule.
The Utilization Treadmill
Agency economics are driven by utilization — the percentage of billable hours relative to total available hours. A healthy agency targets 70-80% utilization. Below that, they lose money. Above that, people burn out.
This utilization pressure creates perverse incentives. Agencies are motivated to keep developers billable at all times, which means: starting projects as soon as possible (even if proper planning has not been done), staffing projects with whoever is available rather than whoever is best suited, and keeping projects going as long as possible rather than delivering efficiently.
The agency that finishes a project in 8 weeks when it was estimated at 12 weeks has just created a 4-week gap in their revenue. The agency that finishes in 14 weeks has 2 extra weeks of billable time. Time-and-materials contracts partially correct this by aligning billing with actual effort, but they create the opposite problem: the client bears all the risk of overruns, and the agency has no financial incentive to be efficient.
The utilization treadmill also makes it difficult for agencies to invest in quality. Time spent on code reviews, refactoring, testing, documentation, and knowledge sharing is non-billable time that reduces utilization. The agency that skips these practices is more profitable in the short term, even though the software they produce is worse.
What a Better Model Looks Like
We do not claim to have solved all of these problems, but we have structured our practice to avoid the worst of them.
Weekly capacity, not fixed scope. We commit to a weekly delivery cadence with full transparency on hours. The client sets priorities. We build in priority order and deliver working software every week. If priorities change — and they always change — we adjust without a change order process. The client pays for time and gets working software, not a document that says the software will work someday.
Same team, always. The people you meet in the initial conversations are the people who build your software. We are a small studio by design. We do not have a bench of interchangeable developers. If we do not have capacity, we say so and discuss timeline. We would rather delay a start date than staff a project with the wrong people.
Built-in exit readiness. Every project produces documentation, runbooks, and a clean codebase that the client’s team (or any competent developer) can take over. We use mainstream technologies (Next.js, PostgreSQL, Tailwind, Vercel) specifically because they have large talent pools. We do not want our clients to need us. We want them to choose to work with us because we deliver value, not because they are trapped.
Shared ownership of outcomes. We track metrics that matter — user adoption, performance benchmarks, uptime — and we are accountable for those outcomes, not just for delivering features. If the software we build does not get adopted, that is our problem to solve, not just the client’s.
Direct access to builders. Every conversation the client has is with someone who writes code or designs interfaces. There is no project manager playing telephone between the client and the development team. This eliminates the information loss that plagues larger agencies and means the client’s feedback is heard by the person who can act on it immediately.
This model is not for everyone. Clients who need a 50-person team, a rigid SOW, and a fixed price should work with a traditional agency. Clients who want to build something great with a small team that cares about the outcome — that is what we do.