Module 6: Moats And Defensibility

Why a feature is not a moat

Description

The five previous lessons covered the five paths that can actually reach 'moat'. This lesson does the opposite: it stops on the sixth type moatScore recognizes, 'feature', and precisely explains why its formula condemns it, by design, to never cross even the 'weak-moat' threshold. This isn't an oversight in the model — it's the module's complete thesis, isolated into a single type: a feature, no matter how long it took to build, is not the same as an advantage that's hard to erode.

This is probably the most uncomfortable lesson in the module for any engineering team, because it puts under the microscope exactly the kind of work a team tends to be proudest of: the well-built, well-polished feature, celebrated in the last demo. The lesson doesn't say those features are bad — it says, precisely, what kind of value they deliver, and what kind they don't.

Connection to the module. Lessons 3, 4, and 5 covered networkEffect, switchingCost, dataMoat, and scaleEconomies — the four paths, along with brand from lesson 2, that do reach moat. This lesson closes the type-by-type tour with the one that never gets there, and connects directly to module 4's differentiation: a real differentiation today —something that genuinely sets you apart from the competitor— can, with no contradiction at all, not be a moat, if anyone can copy it next quarter. Lesson 7 takes this same question and turns it into an architecture decision: the same initiative, built one way, stays at 'feature'; built another way, crosses into a real type.

An everyday analogy: the painted shield, again, with the exact test

The module opened with two castles: one with a moat, the other with a carved wooden gate and a hand-painted shield. This lesson installs the exact test that separates one from the other, the same one you already saw applied at the end of lesson 2 with the painted-puddle question: how long does a determined army take to cross it? A real moat has no short answer to that question — no matter how many soldiers they send, the water is still there. A gate, no matter how carved, has a very concrete answer: a battering ram, a weekend, maybe two. The beauty of the carving doesn't change that number one bit — a mediocre gate and a spectacular gate fall exactly as fast against the same battering ram, because what determines how much it resists isn't how pretty it looks, it's what material it's made of.

Worked example: three features, three build times, the same ceiling

We reuse moatScore unchanged and run it on three of Mercado's features, chosen on purpose to vary widely in how long they took to build — from a weekend to almost a full quarter. fasterCheckout is the backlog item you already know from module 1: a one-click checkout, copyable in a weekend. curatedDiscoveryAlgorithm is the curation algorithm behind curatedDiscovery —the differentiation module 4 celebrated as Mercado's central value proposition—, evaluated here purely as the code that ranks and filters the catalog, with no purchase data feeding it back yet: a competitor with a good engineering team could replicate the ranking logic in about three weeks. personalizedOnboardingFlow is a personalized welcome flow, with custom illustrations and several rounds of user research — the team that built it spent twelve full weekends on it, almost a quarter.

// Pedagogical model: scores the DURABILITY (0-10) of a competitive advantage.
// Reused unchanged from lesson 2 -- this lesson stops on the 'feature'
// type, the control group that never crosses the threshold.
function moatScore(advantage) {
  const { name, type } = advantage;
  let durability;
  let rationale;

  switch (type) {
    case 'networkEffect': {
      const { sides, localDecay } = advantage;
      durability = sides >= 2 ? 8 : 5;
      if (localDecay) durability -= 3;
      rationale = `network effect ${sides}-sided${localDecay ? ', with local decay' : ', no decay'}`;
      break;
    }
    case 'switchingCost': {
      const { depth } = advantage;
      const depthScore = { contractual: 3, habit: 5, dataAndWorkflow: 8 };
      durability = depthScore[depth] ?? 3;
      rationale = `switching cost of depth '${depth}'`;
      break;
    }
    case 'scaleEconomies': {
      const { fixedCostShare } = advantage;
      durability = Math.round(fixedCostShare * 10);
      rationale = `economies of scale with ${Math.round(fixedCostShare * 100)}% fixed cost`;
      break;
    }
    case 'dataMoat': {
      const { feedbackLoop, uniqueToUs } = advantage;
      durability = feedbackLoop ? 7 : 2;
      if (feedbackLoop && uniqueToUs) durability += 2;
      rationale = feedbackLoop
        ? `the data feeds a loop that improves the product${uniqueToUs ? ' and is exclusive' : ''}`
        : 'the data accumulates but doesn\'t feed back into the product';
      break;
    }
    case 'brand': {
      const { pricingPower } = advantage;
      durability = pricingPower ? 6 : 2;
      rationale = pricingPower
        ? 'the brand changes purchase behavior (tolerates price or friction)'
        : 'the brand is recognized but doesn\'t change purchase behavior';
      break;
    }
    case 'feature': {
      const { timeToCopyWeekends } = advantage;
      durability = Math.max(0, Math.min(3, timeToCopyWeekends));
      rationale = `feature copyable in ~${timeToCopyWeekends} weekend(s)`;
      break;
    }
    default: {
      durability = 0;
      rationale = 'unknown advantage type';
    }
  }

  durability = Math.max(0, Math.min(10, durability));
  const verdict = durability >= 7 ? 'moat' : durability >= 4 ? 'weak-moat' : 'not-a-moat';
  return { name, type, durability, verdict, rationale };
}

const candidates = [
  { name: 'fasterCheckout', type: 'feature', timeToCopyWeekends: 1 },
  { name: 'curatedDiscoveryAlgorithm', type: 'feature', timeToCopyWeekends: 3 },
  { name: 'personalizedOnboardingFlow', type: 'feature', timeToCopyWeekends: 12 },
];

console.log('=== Three features, three build times, the same ceiling ===\n');
console.table(candidates.map(moatScore));

What to expect. Running the file with Node produces exactly this output:

=== Three features, three build times, the same ceiling ===

┌─────────┬──────────────────────────────┬───────────┬────────────┬──────────────┬─────────────────────────────────────────────┐
│ (index) │             name             │   type    │ durability │   verdict    │                  rationale                  │
├─────────┼──────────────────────────────┼───────────┼────────────┼──────────────┼─────────────────────────────────────────────┤
│    0    │       'fasterCheckout'       │ 'feature' │     1      │ 'not-a-moat' │ 'feature copyable in ~1 weekend(s)'         │
│    1    │ 'curatedDiscoveryAlgorithm'  │ 'feature' │     3      │ 'not-a-moat' │ 'feature copyable in ~3 weekend(s)'         │
│    2    │ 'personalizedOnboardingFlow' │ 'feature' │     3      │ 'not-a-moat' │ 'feature copyable in ~12 weekend(s)'        │
└─────────┴──────────────────────────────┴───────────┴────────────┴──────────────┴─────────────────────────────────────────────┘

Two results deserve full attention. The first is curatedDiscoveryAlgorithm: the differentiation module 4 celebrated as the heart of Mercado's value proposition —"you discover what you didn't know you wanted"— gets durability: 3 and 'not-a-moat' when evaluated as pure algorithm, without the purchase data feeding it back. This doesn't contradict module 4: a real differentiation, one that serves the segment better than the alternatives, is still a real differentiation — but "differentiated today" and "hard to copy tomorrow" are two different questions, and moatScore only answers the second one. A competitor with a good ranking-and-search team could, in a few weeks, build similar curation logic — Mercado's advantage on that front, alone, doesn't survive a serious attack (module 7, with strategicFilter, picks this distinction back up to decide what to build).

The second result, even more counterintuitive: personalizedOnboardingFlow, which cost the team twelve full weekends —almost a quarter of real work, with user research involved—, gets exactly the same durability: 3 as a three-weekend feature. The formula, Math.max(0, Math.min(3, timeToCopyWeekends)), has a hard ceiling at 3: it doesn't matter whether timeToCopyWeekends is 3, 12, or 50 — the result never rises above that. That's not a model error, it's exactly its point: how long something takes to build is not the same as how long it takes to defend. A competitor doesn't need to reproduce your entire twelve-weekend process, user research included — they just need to replicate the final result, the screen the user sees, and that, for almost any interface feature, happens much faster than it took to build it the first time.

Deep dive: why "we have feature X" is never, on its own, a complete answer

The vocabulary mistake lesson 2 named —confusing "good" with "durable"— has, in the feature type, its most common and most costly form in practice. When a product team presents the quarter's roadmap with a list of new features and calls it, without further qualification, "our competitive advantage," it's mixing two questions the whole module works to keep separate: does this improve the product today? —almost always yes, and that's fine, good features improve the product—, and does this stay an advantage after a competitor decides to copy it? —the question moatScore answers, and for the feature type the answer is, by design, always no.

This doesn't mean features don't matter. It means they play a different role in strategy than a moat does. A good feature solves a real user problem today, attracts and retains until someone copies it, and can be the entry point to a real moat if, over time, it connects to one of the five mechanisms — if curatedDiscoveryAlgorithm starts feeding back with purchaseData, it stops being a copyable feature and becomes part of a data moat (lesson 7 shows exactly this transformation). But as long as it stays just the algorithm, with no data loop behind it, it's still door decoration: well made, useful, and with no moat underneath.

It's also worth noting why the model's ceiling is exactly 3, not 0: a feature copyable in one weekend (durability: 1) and one copyable in three (durability: 3) do have a real difference —the first is lost almost immediately, the second gives a bit more of a window—, but neither one, not even the three-weekend one, reaches the threshold of 4 that defines 'weak-moat'. The model allows the feature type to have some internal gradation —so you can compare features against each other—, while guaranteeing that none of them, no matter how well built, gets confused with a structural advantage.

Common mistakes

Presenting a roadmap feature list as "our moat." What happens: in a quarterly review, the product team shows next semester's feature roadmap under the title "how we're going to defend against the competition," without distinguishing which of those features connect to a real mechanism and which are simply good, copyable improvements. Why it happens: a roadmap full of features feels like concrete, visible progress, while naming the moat mechanism behind each one requires a level of analysis rarely done in the planning meeting. How to spot it: for every roadmap feature presented as "competitive advantage," ask which moatScore type it belongs to — if the answer is "none, it's just a good improvement," the "moat" label is misapplied. How to fix it: split the roadmap into two honest columns — features that improve the product today, and the (probably very few) that also deepen one of the five real mechanisms — and communicate each with its correct name.

Measuring build effort as if it were defense effort. What happens: someone defends a feature as "hard to copy" by citing how much time, how many people, or how much research it took to build, without noticing that copy time has no necessary relationship to how long the original took to build. Why it happens: it's intuitive to think that something that cost a lot of effort must be hard to replicate — but building something for the first time, with no example to copy, almost always takes much longer than reproducing an already-visible, already-proven result. How to spot it: if the argument for an advantage's durability is "it took us X months to build," instead of naming a network, switching-cost, data, scale, or brand mechanism, the argument is measuring the wrong thing. How to fix it: always use timeToCopyWeekends —how long a well-funded competitor would take to replicate the visible result, not the process— as the right question, exactly as in this lesson's example.

Abandoning a real differentiation just because it isn't a moat. What happens: upon discovering that curatedDiscoveryAlgorithm scores 'not-a-moat' in moatScore, the team concludes that Mercado's entire differentiation —curation— "doesn't matter" and deserves less investment, confusing "not a moat yet" with "not worth it." Why it happens: seeing a 'not-a-moat' in a model's output feels like a final verdict, when it's actually a snapshot of the current state of a mechanism that can evolve. How to spot it: if the conversation jumps straight from "this isn't a moat" to "let's stop investing in this," without asking "what would it take for it to become one?", half the analysis is being missed. How to fix it: for any real differentiation that scores 'not-a-moat', explicitly ask what mechanism —almost always dataMoat, connecting the algorithm to a real data loop— could turn it into a durable advantage, and treat that as the real engineering priority, not the abandonment of the initiative.

Exercises

Exercise 1 — Classify the claim. A colleague says: "our advanced search filter took a whole team six months, and nobody else in the market has it yet — that's our moat." Using this lesson's criterion, do the time and temporary exclusivity described add up to calling it a moat? What follow-up question would you ask?

See solution

They don't add up. The argument describes how much it cost to build the filter and how long it's been the only one in the market with it — neither of those is what moatScore measures. The right follow-up question is "if MegaStoreGenerico decided to copy exactly this function next quarter, with its own engineering team looking at the already-built final result, how many weekends would it take them?" — probably much less than the original six months, because copying a visible result is structurally faster than inventing it from scratch. That nobody else has it yet is a temporary window, not a moat — the same mistake lesson 2 named with "we were first."

Exercise 2 — Predict before running it. Without running code, using this lesson's feature formula (durability = Math.max(0, Math.min(3, timeToCopyWeekends))), predict the durability and verdict of these two advantages: { name: 'quickWin', type: 'feature', timeToCopyWeekends: 0 } and { name: 'megaProject', type: 'feature', timeToCopyWeekends: 40 }. Then verify by running moatScore on both objects.

See solution

quickWin with timeToCopyWeekends: 0: Math.min(3, 0) = 0, then Math.max(0, 0) = 0durability: 0, verdict: 'not-a-moat' (a feature so simple a competitor copies it the same day). megaProject with timeToCopyWeekends: 40: Math.min(3, 40) = 3, then Math.max(0, 3) = 3durability: 3, verdict: 'not-a-moat', exactly the same result as curatedDiscoveryAlgorithm with only 3 weekends. The point of the exercise, confirmed with extreme numbers in both directions: the entire range of timeToCopyWeekends —from 0 to 40, from one day to almost a year— collapses to just four possible durability values (0, 1, 2, or 3), and none of the four ever leaves 'not-a-moat' territory.

Exercise 3 — From feature to moat. Take fasterCheckout (durability: 1 as a feature). Propose, in two or three sentences, how that same initiative could be redesigned to connect to one of the five real moat types —not as a more polished feature, but as a different architecture decision— and what moatScore type would result.

See solution

There's no single correct answer — the exercise previews lesson 7's whole topic. A reasonable proposal: instead of just saving the payment method for one-click use (which is what makes it copyable in a weekend today), the checkout could learn from each buyer's purchase history —most likely shipping address based on what they're buying, preferred payment method based on the amount, related-product suggestions at the last step— connecting to the same data loop as purchaseData. That would move fasterCheckout from the feature type to the dataMoat type, with feedbackLoop: true — not because the one-click button itself changes, but because the decision of what to show in that click now depends on a data loop a competitor can't copy just by looking at the screen.

Summary and next step

In this lesson you closed the type-by-type tour with the control group: 'feature', whose formula has a hard ceiling of 3 —well below the 'weak-moat' threshold— no matter how long it took to build. You saw that a real differentiation, curatedDiscoveryAlgorithm's, can coexist with "not a moat" without any contradiction, and that confusing build time with defense time is, perhaps, the most common and most expensive mistake in the entire moat conversation.

Before moving on you should be able to: explain why the feature type never crosses the moat threshold regardless of timeToCopyWeekends, distinguish "real differentiation" from "real moat" with your own example, and propose, for any given feature, which mechanism from the other five types could turn it into a durable advantage.

Lesson 7 takes exactly that last question and turns it into the central topic: the engineer's role in building moats — the same initiative, built with one architecture decision or another, crossing that threshold or not.

Resources

  • Jeff Jordan (a16z), "So You Want to Compete Against Amazon?" — a16z.com/so-you-want-to-compete-against-amazon. The same article cited in the module's introduction, now relevant on a specific point: why copying a giant's visible features is, almost always, faster and cheaper than it took the giant to build them the first time. In English.
  • Investopedia, "Economic Moat" — investopedia.com/terms/e/economicmoat.asp. Morningstar's economic moat definition explicitly excludes product advantages a competitor can replicate in a short timeframe — the same criterion, in different words, that this lesson's feature type models with a hard ceiling. In English.