LLenny's Podcast
← All frameworks
ProductivityJulia Schottenstein (dbt Labs)

Worse Is Better, Tech Debt Is a Champagne Problem

Ship the embarrassing version — you only earn tech debt if people actually use the thing

Difficulty
Easy
Time to result
~weeks to results
Steps
4
Confidence
95%

Two sayings Schottenstein repeats to combat engineering perfectionism. 'Worse is better' says perfect does not exist and good enough gets you to the only moment that teaches you anything: shipping. 'Tech debt is a champagne problem' reframes debt as evidence of success — you would be lucky to have it, because it means people are using the product. Together they form a permission structure to build the naive version deliberately and rebuild only when real scale forces it.

Origin

Julia Schottenstein's own sayings, used with her engineering team on dbt Cloud. She explicitly disclaims being a framework person; these are the two mantras she finds herself repeating to herself and to others.

Core principles

  • 01Perfect doesn't exist — go with good enough
  • 02Shipping is the moment you learn, and no amount of anticipation substitutes for it
  • 03Tech debt is a lagging indicator of adoption
  • 04You cannot build for scale you do not have
  • 05The naive version is a deliberate choice, not a failure

How to run it

  1. 1

    Name the perfectionism out loud

    When a team is over-engineering, say the two phrases. They are shorthand that gives engineers explicit permission to ship something they are a little embarrassed by, and shorthand is what actually changes behaviour in the moment.

    Pro tip Repeat them constantly. Their value is as a reflex, not as a one-time speech.

  2. 2

    Build the naive version on purpose

    For a v1, deliberately pick the dumbest architecture that gets the job done. dbt Cloud's first scheduler was a big old for-loop over a big old jobs table, checking each job in turn to see if it was time to run.

    Pro tip State explicitly what you are NOT building and why: dbt did not need a distributed scheduler with Go workers and RabbitMQ at launch, because they had no users.

    Watch out This applies to scale, not to correctness or data quality — dbt's simplicity was paired with a framework that made it hard to mess up.

  3. 3

    Ship, then learn what you could not anticipate

    You can try very hard to understand how people will use the product and iron out all the edges, but you cannot know until you ship. Treat launch as the start of learning, not the end of building.

  4. 4

    Rebuild only when real scale forces it

    When usage genuinely arrives, rebuild — repeatedly if necessary. The rebuild is paid for by revenue and informed by real usage patterns, which is why it is a champagne problem rather than a crisis.

    Pro tip Frame each rebuild internally as proof the earlier bet paid off, so engineers don't experience it as punishment for the naive v1.

    Watch out Do not use 'we'll rebuild later' to justify shipping something that produces wrong results. Naive is about architecture, not accuracy.

In the wild

The dbt Cloud scheduler's embarrassing for-loop

The initial version of the dbt Cloud scheduler was, in Schottenstein's words, pretty naive and slightly embarrassing: a big old for-loop over a big old jobs table, walking through each job asking whether it was time for that job to run, running it if so, continuing if not. Extremely simple, and it got the job done. What they deliberately did not build at launch was a distributed scheduler with Go workers and RabbitMQ, because they had no users to justify it.

The scheduler has since been rebuilt several times over because dbt now has meaningful scale — 8,000 companies use it and it manages 10 million runs per month. The rebuilds are the champagne problem: they exist only because the naive version got shipped and adopted.

Common mistakes

Building for a scale you don't have

A distributed scheduler with Go workers and RabbitMQ at launch is engineering for imaginary users. Every hour spent on it is an hour not spent learning what real users need.

Treating tech debt as a moral failure

Engineers experience debt as shame and pre-emptively over-build. Reframing it as evidence of adoption removes the incentive to gold-plate a v1.

Trying to anticipate every edge case before shipping

You genuinely cannot know how people will use the product until you ship it, so pre-launch edge-case work has a hard ceiling on its value.

Is it for you?

Best for

Product leaders and engineering managers on zero-to-one projects where a team's perfectionism is delaying a launch that would generate the learning they are missing

Not ideal for

Systems where a naive v1 is unsafe or incorrect rather than merely unscalable — data integrity, security, financial correctness, regulated domains

From the transcript

I'm not a big framework person but there's kind of two sayings that I find myself repeating or either to myself or to others and…

52:00

good enough because when you ship that's the moment when you get to learn a lot from your users and you just can't anticipate it

52:30

I try to remind the engineers like we would be so lucky to have tech tech debt because that means people are using the product

53:00

what we didn't need at launch was a distributed scheduler with gow workers and rabid mq we just didn't need it because we had no…

53:30

From the episode

M&A, competition, pricing, and investing

Julia Schottenstein (dbt Labs)