Abstract network of connected geometric points
← Back to articles

When Customer Demos Become Permanent Debt

Software Development, Technical Debt, Agile, Project Management

The room was silent, save for the syncopated rhythm of fingers hammering keyboards and the occasional rattle of a half-empty energy drink can. The customer demonstration was tomorrow, and with dawning horror, the team realized they had nothing that truly worked. The silence was eventually broken by a fateful suggestion: “What if we just hardcode it for now? Just to show the flow.” Heads nodded wearily. It was a desperate measure, but it was something. In unison, they spoke the ritual words that would seal their fate: “Don’t worry, it’s just for the customer preview.” With that, a curse was spoken. Everyone in that room knew the chilling implication: the fragile, duct-taped version would work, albeit barely. The customer would inevitably love it. And then, somehow, that precarious code, intended only as a temporary sketch, would slither its way into the main codebase. It always does.

The Fatal Allure of the Early Demo

Every development team understands the magnetic pull of wanting to showcase progress — to put something tangible into a customer’s hands. This rush carries an addictive optimism, framed as agility and responsiveness. And to be fair, early demos do play a vital role in shaping better products. Customers love them, executives applaud them, and even developers feel a momentary high from delivering something concrete.

But deep down, behind the smiles and applause, the truth lingers. To achieve that fleeting moment of success, essential steps were skipped: tests were ignored, fundamental abstractions were bypassed, and the team whispered “just for now” as a shield against the inevitable consequences. The meeting ends, the stakeholders are happy, and the developers return to their desks to stare at the technical mess they just willed into existence.

From Temporary Sketch to Immortal Codebase

In theory, a preview is meant to be disposable — a quick sketch, a scaffold to be torn down and rebuilt properly later. In practice, however, it achieves a kind of immortality. The day after the triumphant demo, the team fully intended to clean up the code. But another urgent request arrived. A new deadline loomed. That single preview feature, the one with the half-baked API and copy-pasted logic, suddenly needed "just a few tweaks" to go live for a small pilot group.

Weeks bled into months. The promised refactor ticket was never opened. Before anyone realized it, the entire release pipeline had begun to depend on code that had started life as a desperate demo hack. The team had normalized the compromise. When new developers joined and inquired why things were architected in such an odd manner, the veterans would sigh and repeat the same tired mantra: “That was just for a customer preview.”

The Heavy Price of "Forever"

This technical compromise, often called “preview debt,” doesn’t explode into a disaster; it seeps in quietly. It begins as a few oddities — strange coupling, a bit of duplicated logic. Nothing major. Then, months later, when the team attempts to implement a major change, they realize everything depends on that old hack. The robust abstraction that was skipped is now a necessity, and the fake data service is inexplicably feeding production code.

That is when the true weight of the situation hits: the team isn’t maintaining a product; they are maintaining a preview that simply refused to die. It is impossible to move fast when the foundation of the product is built on shifting sand. Preview debt’s danger extends beyond the lines of code; it poisons the team’s culture by setting a dangerous precedent.

Once that shaky feature is shown, it becomes real in everyone’s mind. The customer doesn’t see the duct tape; they see a feature and begin asking for it elsewhere. Product managers add it to the roadmap, and the sales team incorporates it into their pitch decks. The temporary preview, never meant to be a standard, becomes the standard. Internally, the team learns the most dangerous lesson of all: “It worked last time.” They pulled it off once, so they can pull it off again — each temporary solution becoming another permanent ghost in the machine.

Breaking the Cycle of Compromise

Escaping this cycle is less about striving for technical purity and more about demanding honesty from everyone involved. The first step is a commitment to radical transparency with stakeholders: clearly state, “This is a demo, not a deliverable. It is a limited prototype and will require proper development time before it can be considered production-ready.”

Second, be honest with the team and yourself: acknowledge that “This is debt, not sustainable progress. We must plan for its cleanup,” and then actually schedule the time to do it.

  • Aggressively Label Code: Use comments like // TODO: DEMO_DEBT: [Date] - This hack must be refactored.
  • Dedicated Tracking: Create a "tech-debt-preview" ticket before the demo even happens and prioritize its cleanup immediately after.
  • Isolation: Wall off preview code behind feature flags until it’s properly rebuilt for production.
  • Empower “No”: Leadership must be empowered to delay a demo rather than allow a poison pill to enter the codebase.

The Long Shadow of the Ghost

The codebase is a graveyard of good intentions. Every so often, a developer stumbles across a line marked by a comment like: // TODO: temporary fix for preview build (March 2021). They sit there, wondering if the person who wrote it truly believed they would return to fix it. The truth is, they always meant to. But intent fades, deadlines shift, and the ghosts stay.

Our systems are full of these quiet reminders of the day we chose expedience over craftsmanship. They whisper in every regression, every brittle test, and every frustrated new hire who asks, “Wait, why is it built like this?” All the veterans can do is sigh, shake their heads, and answer: “It was just for a customer preview.”

So, the next time those words are spoken, pause. Because what is really being said is: “This will be part of your life forever.” And if you listen closely, you can already hear the ghost of previews past, waiting patiently to join the codebase.