GOne to Two

Chapter 7: The Disposable Build

12 min readThis chapter is still being written

The thing you built might not be worth fixing. It might be faster, cheaper, and better to throw it away and build it again.

Every instinct says no. You spent weeks on this. It works. People are paying for it. And I'm telling you to throw it away?

Maybe.

The Lean Startup taught a generation of builders to iterate. Build the MVP. Measure. Learn. Never throw away working software. Pivot, don't restart.

This was rational when building was expensive. An MVP cost fifty to a hundred and fifty thousand dollars and took months. Code was precious because code was expensive.

AI changed those economics. A feature that took five people three months in 2023 now takes one person days. But our instincts haven‘t caught up. We still treat code like it’s precious. We still try to fix what we have instead of rebuilding what we now understand.

The data is interesting. Whitespectre found that roughly 30% of AI-prototype code was salvageable for production. Seventy percent was throwaway. If you‘re replacing 70% of the code anyway, are you really “iterating”? Or is it a rewrite wearing a refactor’s clothes?

My friend Jarod Ferguson put it simply: the most important thing he learned from coding with AI was not to be afraid to start over.

That sentence rearranged something in my head.

The prototype is not the product. It's the lesson. You built it to learn what to build. Now build it again, on purpose, with everything you know.

Think about what‘s different the second time around. You know what the product actually needs to be — you’ve had customers. You know which architectural decisions matter — SSH tunnels? Not again. You can configure your AI tools with guardrails — issues first, one agent one branch, tests. You can bring people into the process. First time, lone wolf. Second time, you know you need other eyes.

The Apex story shows both paths.

The SSH tunnel architecture was a rebuild. Fourteen bug fixes in one month. Each fix addressed a symptom. The architecture was the disease. March 31, I replaced the entire system — SSH with SSM, warm pool with slot model. Seven days from decision to working replacement. The new architecture worked. The fix spiral stopped.

The config management system was a fix. Nine issues across twenty-one days, four partial rebuilds. Each patch addressed the immediate problem and created perfect conditions for the next one. Two processes writing to the same file with no ownership model — no amount of patching could fix that. It was structural. I should have thrown it away and rebuilt it week one. I didn't because I kept thinking I was “almost there.” I was never almost there.

But those are individual systems. The harder question — the one that keeps me up — is bigger. What happens when the whole product is the prototype?

Throughout my CTO career, I‘ve been the guy who preaches the throwaway prototype. Build cheap first. Learn what the thing actually needs to be — the true cost, the true scope, the true impact. Then build the real version with everything you now know. I’ve preached this to teams, to founders, to anyone who will listen. The prototype is the tuition. The product is what you build after you've paid it.

With Apex, I‘m watching myself violate my own principle in real time. We’re selling the prototype. Real customers, real money, real expectations — all running on architecture I know is temporary. Every onboarding, every feature request, every customer success call is building on a foundation I've spent my entire career telling people to throw away.

It feels like a values compromise. Not the dramatic kind — nobody‘s doing anything wrong. The slow kind, where every day the gap between what you believe and what you’re doing gets a little wider, and the cost of closing it gets a little higher.

So I start naming it. In conversations with the team, I start talking about “v1 and v2” of Apex. V1 is what we have — the prototype that became a product. V2 is what we build once we understand what Apex actually needs to be. The classic throwaway-prototype-then-real-product arc I've always believed in.

This freaks Dan and Roddy out. Dan hears “v2” and sees a six-month gap in the roadmap — he‘s got ten customers in his pipeline and a story to tell. Roddy runs the studio day-to-day; he hears “v2” and thinks about the commitments they’ve already made. And the conventional wisdom — which is usually right — is that you don‘t re-platform. You don’t throw away working software. You improve it incrementally. Customers don‘t care about your architecture. They care about whether the thing works tomorrow. “V2” sounds like “we’re going to disappear for six months and come back with something new.” That‘s not what I mean. But it’s what they hear.

And they‘re not wrong to be nervous. I’ve seen re-platforms kill companies. The Joel Spolsky warning about Netscape — they stopped shipping for years to rewrite from scratch, and the market left them behind. I agree with the principle. Don't re-platform.

But what do you do when you‘ve started adding customers to a prototype that’s already showing the architectural cracks that will eventually force a massive rewrite? The session bloat. The config system. The SSH tunnels. These aren‘t isolated bugs. They’re symptoms of prototype architecture running under production load. Every customer we add makes the eventual rewrite bigger and harder. The cost of v1 is compounding.

I don‘t resolve this cleanly. I want to tell you I found the right moment to do the rebuild, that I threaded the needle between Dan’s “keep shipping” and my “this needs a v2.” The truth is I‘m still working it out — replacing pieces of v1 with production-grade architecture one system at a time, keeping the product running while I rebuild the plane in flight. It’s not the clean break my instincts want. It's the messy middle that the product needs.

Diagnosing the Rebuild

The old rule of thumb was simple: if you've fixed the same system three times and it keeps breaking, the system is the problem. Rebuild it.

But that‘s too crisp. I’ve learned it needs more interrogation.

Three fixes doesn‘t mean anything by itself. You have to ask: is it the same root cause manifesting three times, or three different symptoms from three different problems? The SSH tunnel situation was one root cause — the architecture couldn’t handle connection instability — showing up as fourteen different symptoms. That‘s a rebuild. But if you’ve got three unrelated bugs in the same module, that's just software. Fix them and move on.

You also need to distinguish architecture from implementation. Is the design wrong, or is the code just buggy? A bad implementation of a sound architecture is a fix. A clean implementation of a broken architecture is a rebuild. The config management system wasn't poorly coded — the AI wrote perfectly reasonable file-locking logic. The problem was that two processes sharing one file with no ownership model is a broken design. No amount of better code fixes a broken design.

Here‘s the diagnostic I wish I’d had earlier: before you decide to rebuild, articulate the architectural flaw in one sentence. “The system uses SSH tunnels that can‘t recover from network interruptions.” “Two writers share one config file with no coordination protocol.” If you can say it clearly, you know what to fix in the rebuild. If you can’t articulate the flaw — if your sentence is vague, like “it‘s just messy” or “the code is hard to work with” — the rebuild will probably recreate the same flaw, because you haven’t actually identified what‘s wrong. You’ve just identified that you're frustrated.

Frustration is not a diagnosis. It's a symptom. And rebuilding to treat a symptom is exactly the mistake this chapter is supposed to help you avoid.

When Rebuilding Is the Wrong Call

I need to be honest about something: the advice in this chapter is dangerous. “Throw it away and rebuild” is the kind of thing that sounds liberating and can kill your company.

Most startup deaths from rewrites don't come from rewriting too little. They come from rewriting too much, too soon, for the wrong reasons. The sunk-cost fallacy gets all the press, but its mirror — the “clean slate” fallacy, where you convince yourself that starting over will magically solve problems that are actually unsolved — is just as deadly and much less discussed.

Here are the failure modes I‘ve seen, including some I’ve lived.

The most common is rebuilding when the real problem is requirements churn. If your product keeps changing shape because you haven‘t figured out what customers want, a rebuild won’t help. You‘ll rebuild the wrong thing with better architecture. I’ve watched founders burn six weeks on a “proper” rebuild only to discover — again — that the feature they rebuilt isn‘t what customers needed. The architecture was beautiful. The product was irrelevant. If your requirements are still shifting weekly, you’re not ready to rebuild. You're still in prototype mode. Stay there. Keep the messy code. Learn faster.

Then there‘s rebuilding to avoid the emotional work of understanding the existing code. The AI generated three thousand lines you only half-understand. Reading it feels like archaeology. Rebuilding feels like creation. Creation is fun. Archaeology is not. But the understanding you’re avoiding is exactly the understanding you need to rebuild well. If you can't explain why the current system does what it does — including the weird parts that are actually handling edge cases you forgot about — your rebuild will miss those edge cases.

I did this with a logging subsystem at Apex. The original code had what looked like redundant error handling — try/catch blocks wrapped in try/catch blocks, retries inside retries. It looked like the AI had panicked. I rebuilt it clean. Turns out those nested handlers were catching a real cascade failure in the cloud provider's API. My clean version crashed the first time that cascade happened. I ended up putting the ugly code back.

There‘s also the trap of rebuilding because the AI makes it feel free. Claude can regenerate a module in twenty minutes. But the cost was never just the code generation. It’s the testing, the integration, the edge cases you rediscover, the data migration, the bugs that take a week to surface. The AI made the code cheap. It didn't make the knowledge cheap.

And finally, rebuilding everything at once. Even when a rebuild is justified, doing it all in one shot is almost always wrong. The instinct — especially with AI, especially when you're frustrated — is to nuke the whole thing and start fresh. That instinct has killed more projects than bad architecture ever did.

The question is never “should I rebuild?” in the abstract. It‘s “have I identified a specific architectural flaw that I can name, that incremental fixes can’t address, and that I understand well enough to avoid repeating?” If yes, rebuild — carefully. If no, you‘re not rebuilding. You’re running away.

The Strangler Fig: Rebuilding Without the Cliff

There‘s a pattern from legacy software migration called the strangler fig, named after the tropical trees that grow around a host tree, gradually replacing it until the original is gone. It’s the safest way to rebuild, and most founders I talk to have never heard of it.

The idea is simple: don't replace the old system in one shot. Build the new thing alongside the old. Route some traffic to the new system. Verify it works. Route more traffic. When the new system is handling everything and you trust it, tear down the old one.

This sounds obvious when you say it out loud, but it‘s the opposite of what most people do. Most people plan a “migration weekend” — shut down the old, bring up the new, pray. That’s not engineering. That's gambling.

Here‘s what the strangler fig looks like in practice. Take the Apex SSH-to-SSM migration. The way I actually did it was a hard cutover — March 31, rip out SSH, drop in SSM. It worked because the new architecture was sound and I’d tested it. But it was a seven-day white-knuckle ride, and if it had failed, customers would have been dead in the water.

Why didn‘t I use the strangler fig? Honestly — I didn’t know the pattern existed. And the speed pressure was real. Dan was selling. Customers were waiting. I chose the riskier path because the riskier path was faster, and speed was the drug I was on. In retrospect, the “luxury” of running both systems would have cost me two extra weeks and bought me the ability to sleep.

The strangler fig version: keep SSH running, build SSM alongside it, route new sessions to SSM, let existing sessions drain on SSH, tear down the old infrastructure when the last session closes. Same outcome, fraction of the risk.

The strangler fig works especially well in the AI era because building the new system alongside the old is fast. The AI can generate the new module while the old one keeps running. You‘re not choosing between “working but broken” and “nothing while we rebuild.” You’re running both, and the new one has to earn its place.

Not every rebuild can use this pattern. Sometimes the old and new architectures are incompatible at a deep level. But more often than you‘d think, you can find a seam — an API boundary, a queue, a routing layer — where you can split traffic. Look for that seam before you commit to a hard cutover. It’s almost always there.

The Hidden Cost: Data and State

There‘s one more thing founders consistently underestimate about rebuilds, and it’s the thing that has nothing to do with code.

Rebuilding the code is cheap. Migrating live customer data without losing anything is expensive.

Your prototype has been running in production. Customers have created accounts, saved configurations, built workflows, accumulated history. That data lives in database schemas your new architecture might not share, in file formats your new system might not read, in implicit state that exists only because the old system happened to work a certain way. A rebuild that loses customer data isn‘t a rebuild. It’s a catastrophe.

Before you commit to a rebuild, map every piece of state your system holds. Every database table, every config file, every cached value, every external integration that stores a reference to your system. Then plan how each one migrates. If the migration plan is longer than the rebuild plan, that's a signal — maybe incremental is the right call after all, or maybe the strangler fig is the way to go, where you migrate data gradually instead of all at once.

The code is disposable. The data is not.

The Fix-or-Rebuild Decision

This doesn't mean rebuild everything. The fix-or-rebuild question only applies to systems actively causing pain. For each problem area:

Is the problem in the implementation or the architecture? Implementation — fix it. Architecture — the fix spiral is waiting for you with a warm cup of coffee and a list of 2am commits.

How much would you change? Less than 50%, iterate. More than 70%, rebuild. The middle is judgment, and you‘ll get it wrong sometimes. That’s fine.

What's the fix spiral telling you? Same area of code showing up in your fix commits? Closing issues that immediately spawn new issues? Stop patching. Start designing.

Can you name the flaw? If you can articulate what‘s architecturally wrong in one sentence, you’re ready to rebuild. If you can't, keep fixing until you can.

Can you strangle it? If you can run old and new in parallel, do. The strangler fig is almost always safer than the big bang.

The deeper insight — the one Jarod pointed me toward — is about the relationship between the builder and the build.

We get attached. Especially to code we sweated over, debugged at 2am. Throwing it away feels like admitting we failed.

But the code was never the valuable thing. The understanding you gained by building it — what the product needs to be, what the architecture should look like, where the edge cases hide — that's the valuable thing. The code was the vehicle for learning.

The learning is permanent. The code is disposable. Mostly. Some learning lives in the code itself: the edge case a try/catch block handles that nobody remembers discovering, the workaround for a vendor API quirk that isn‘t documented anywhere. Every rebuild carries the tax of rediscovering what the old system knew. The question isn’t whether you‘ll pay that tax. It’s whether the architectural improvement is worth the cost.

The first build was the prototype for your understanding. The second build is the product.