Mert Özen Further With Every Line
Project Management Introduction to Product Management — #04

Prioritization Frameworks: RICE, MoSCoW, Kano and Cost of Delay

Mert Özen Nov 8, 2026 11 min 4 views
Prioritization Frameworks: RICE, MoSCoW, Kano and Cost of Delay

No single prioritization framework ranks all work correctly: RICE sees impact per effort but not time, CD3 sees urgency but rests on a CoD estimate. We rank Bookstore's six items both ways in TypeScript, see the payment SDK upgrade come last in RICE and first in CD3 and one confidence value reshuffle the order, and cover MoSCoW, Kano, WSJF and scoring technical debt.

Version note: The TypeScript code in this post was run with Node.js 24.22 (type stripping) and type-checked with TypeScript 6.0.3.

Guess First

The Bookstore team has six candidate pieces of work and not enough capacity to do them all next quarter. Two ideas from the cart abandonment work (guest checkout, shipping cost on the product page), saved cards for registered customers, wishlist sharing, faster catalog search, and one technical item: the payment provider has announced it will shut down the old SDK (Software Development Kit) version in three months, so the payment integration has to move to the new version.

The team decides to score with RICE (Reach, Impact, Confidence, Effort). Where do you think the payment SDK upgrade lands on this list? And consider this: where in RICE's formula do you write "in three months we won't be able to take payments"?

RICE: Reach, Impact, Confidence, Effort

RICE spread through a 2018 article by Sean McBride at Intercom. It has four factors. Reach is how many people or events it touches in a period; Intercom measures it as "how many customers will this affect in a quarter." Impact is the effect on each person, given on a fixed scale: 3 massive, 2 high, 1 medium, 0.5 low, 0.25 minimal. Confidence is how much you trust these estimates: 100% high, 80% medium, 50% low; below 50% is, in Intercom's words, a "total moonshot." Effort is the total work of product, design and engineering, in person-months.

The score is Reach × Impact × Confidence ÷ Effort: total impact per time worked. The article itself says the score is not a hard rule, and that lower-scoring work may go first because of dependencies or "table stakes" features. Keep that warning in mind; we'll see shortly why it matters.

Code: Same Backlog, Two Rankings

Let's model the six items in TypeScript. Writing RICE's scales as types blocks made-up in-between values like "Impact 1.7" at the compiler level. We add Cost of Delay and duration to the same data, because the second method will use them:

// RICE (Intercom) scales: impact 0.25-3, confidence 50%/80%/100%
type Impact = 0.25 | 0.5 | 1 | 2 | 3;
type Confidence = 0.5 | 0.8 | 1;

interface BacklogItem {
  id: string;
  title: string;
  reach: number;               // customers affected per quarter
  impact: Impact;
  confidence: Confidence;
  effortPersonMonths: number;  // total product + design + engineering effort
  costOfDelayPerWeek: number;  // thousand TRY per week, the weekly cost of waiting
  durationWeeks: number;       // calendar time, not person-months
}

const backlog: BacklogItem[] = [
  { id: "B1", title: "Guest checkout", reach: 12000, impact: 2, confidence: 0.8,
    effortPersonMonths: 3, costOfDelayPerWeek: 60, durationWeeks: 8 },
  { id: "B2", title: "Shipping cost on product page", reach: 30000, impact: 1, confidence: 0.8,
    effortPersonMonths: 0.5, costOfDelayPerWeek: 25, durationWeeks: 2 },
  { id: "B3", title: "Saved cards", reach: 8000, impact: 2, confidence: 0.5,
    effortPersonMonths: 3.5, costOfDelayPerWeek: 30, durationWeeks: 10 },
  { id: "B4", title: "Wishlist sharing", reach: 3000, impact: 0.5, confidence: 0.8,
    effortPersonMonths: 1, costOfDelayPerWeek: 3, durationWeeks: 3 },
  { id: "B5", title: "Payment SDK upgrade before v2 shutdown", reach: 0, impact: 0.25, confidence: 1,
    effortPersonMonths: 1.5, costOfDelayPerWeek: 120, durationWeeks: 4 },
  { id: "B6", title: "Faster catalog search", reach: 25000, impact: 1, confidence: 0.5,
    effortPersonMonths: 3, costOfDelayPerWeek: 20, durationWeeks: 6 },
];

const rice = (i: BacklogItem): number =>
  (i.reach * i.impact * i.confidence) / i.effortPersonMonths;

// CD3: Cost of Delay Divided by Duration
const cd3 = (i: BacklogItem): number => i.costOfDelayPerWeek / i.durationWeeks;

function rank(items: BacklogItem[], score: (i: BacklogItem) => number): Map<string, number> {
  const sorted = [...items].sort((a, b) => score(b) - score(a));
  return new Map(sorted.map((item, index) => [item.id, index + 1]));
}

function report(items: BacklogItem[]): void {
  const byRice = rank(items, rice);
  const byCd3 = rank(items, cd3);
  console.log("id  title                                   RICE   rank |   CD3  rank");
  for (const i of [...items].sort((a, b) => byRice.get(a.id)! - byRice.get(b.id)!)) {
    console.log(
      `${i.id}  ${i.title.padEnd(38)} ${rice(i).toFixed(0).padStart(6)}  ${byRice.get(i.id)}    | ` +
      `${cd3(i).toFixed(1).padStart(5)}  ${byCd3.get(i.id)}`);
  }
}

report(backlog);

// False precision: how much does the order move when one estimate changes?
console.log("\nB3 confidence 0.5 -> 1 (someone 'feels sure'):");
report(backlog.map(i => (i.id === "B3" ? { ...i, confidence: 1 as Confidence } : i)));

Node.js 24 can run files that contain only erasable TypeScript syntax (types, interfaces, type annotations) directly; since we use no constructs that generate code at runtime, like enums, there's no separate build step. We still type-check with tsc; the erasableSyntaxOnly option in tsconfig.json makes the compiler warn us if we write syntax Node can't run:

{
  "compilerOptions": {
    "target": "es2022",
    "module": "nodenext",
    "strict": true,
    "noEmit": true,
    "erasableSyntaxOnly": true,
    "lib": ["es2022", "dom"]
  },
  "files": ["prioritize.ts"]
}

The real output:

$ npx tsc -p .
$ node prioritize.ts
id  title                                   RICE   rank |   CD3  rank
B2  Shipping cost on product page           48000  1    |  12.5  2
B1  Guest checkout                           6400  2    |   7.5  3
B6  Faster catalog search                    4167  3    |   3.3  4
B3  Saved cards                              2286  4    |   3.0  5
B4  Wishlist sharing                         1200  5    |   1.0  6
B5  Payment SDK upgrade before v2 shutdown      0  6    |  30.0  1

B3 confidence 0.5 -> 1 (someone 'feels sure'):
id  title                                   RICE   rank |   CD3  rank
B2  Shipping cost on product page           48000  1    |  12.5  2
B1  Guest checkout                           6400  2    |   7.5  3
B3  Saved cards                              4571  3    |   3.0  5
B6  Faster catalog search                    4167  4    |   3.3  4
B4  Wishlist sharing                         1200  5    |   1.0  6
B5  Payment SDK upgrade before v2 shutdown      0  6    |  30.0  1

Reading the Output

At the top, the two methods almost agree: shipping cost on the product page (B2) is first in RICE and second in CD3 (Cost of Delay Divided by Duration). It's cheap, touches many people and is directly tied to the cart abandonment problem; it comes out ahead whichever method you use. This is where frameworks help most: quickly confirming the obvious.

The real difference is at the bottom. The payment SDK upgrade (B5) is last in RICE with 0 points and first in CD3 with 30. From RICE's point of view this work offers no customer anything new; its reach is zero. But when the old SDK shuts down in three months, Bookstore won't be able to take any payments at all. There is nothing called "time" among RICE's four factors; it assumes it makes no difference whether work is done today or in six months. That's the answer to the opening question: RICE's formula has no place to write a deadline.

The second part of the program shows false precision. With confidence at 50%, saved cards (B3) has a RICE score of 2,286 and ranks fourth. When someone in the meeting says "I think we're sure about this" and sets confidence to 100%, the score jumps to 4,571 and the item overtakes catalog search. No new information arrived; only one person's feeling changed. That a single number for confidence can lift an item from the middle of the list shows why this factor must come from evidence: without an interview, data or a test result, don't go above 50%.

Cost of Delay and CD3

Cost of Delay (CoD) comes from a question: what do we lose if we do this a week later? In "The Principles of Product Development Flow" (2009), Donald Reinertsen puts this question at the center of economic decisions in product development; Joshua Arnold and the team at Black Swan Farming are known for writing that turns the concept into practice. CoD combines value and urgency in a single number: work that loses 60 thousand TRY a week should come before work that loses 3 thousand TRY a week.

CD3 divides CoD by the duration of the work. The logic: if two items have the same CoD, finishing the short one first reduces the total loss, because while you wait for the long one, the short one's loss keeps adding up too. At Bookstore the payment SDK upgrade carries a risk of 120 thousand TRY a week (orders lost after the shutdown date) and takes four weeks; its CD3 is 30. Guest checkout's CoD is high too (60 thousand TRY a week), but it takes eight weeks; its CD3 is 7.5.

Where these numbers come from is both CD3's strength and its weakness. Its strength is moving the discussion from "which is more important?" to "what does delaying this by a week cost?"; that question lets you speak the same language as finance and sales. Its weakness is that a CoD estimate is still an estimate. But at least the estimate's assumptions ("if the old SDK shuts down, we lose this many orders a day") are written down and open to debate. Arnold's writing also draws attention to urgency profiles, which describe how CoD changes over time: the SDK upgrade's CoD is low until the shutdown date and very high after it.

SAFe's (Scaled Agile Framework) WSJF (Weighted Shortest Job First) is a variant of the same idea: it computes CoD from relative scores for user and business value, time criticality, and risk reduction/opportunity enablement, and divides by job size. Using relative points instead of currency makes it easier to apply, but loses some of the clarity of "what does a week's delay cost?"

MoSCoW and Kano

Not every prioritization has to produce a number. MoSCoW is a categorization method Dai Clegg developed at Oracle in 1994, later popularized through DSDM (Dynamic Systems Development Method): Must have, Should have, Could have, Won't have (this time). It's good for discussing scope in a fixed-date delivery: for the 27 November campaign, "coupon entry is a Must, A/B testing the campaign banner is a Could." Its weakness is that everything drifts into "Must"; without a capacity limit on the Must category, the categories separate nothing.

The Kano model, introduced by Noriaki Kano in 1984, classifies customer satisfaction by whether a feature is present. Must-be features annoy customers when missing and go unnoticed when present: the order confirmation e-mail. One-dimensional (performance) features raise satisfaction the better they are: delivery speed. Attractive features aren't expected but delight when present: being able to preview a chapter of a book. Indifferent features don't matter to anyone, and reverse features annoy some users. Kano determines the categories with a questionnaire of paired questions for each feature: "how would you feel if this feature were present? if it were absent?"

Kano's most useful warning for developers is that categories drift over time: today's attractive feature becomes tomorrow's must-be as competitors build it too. Showing the shipping cost on the product page is something many big e-commerce sites do, so for Bookstore's customers it is already close to a must-be; its absence is noticed.

MethodWhat it producesWhere it works bestBlind spot
RICEImpact/effort scoreComparing ideas aimed at many usersTime and deadlines, platform work
CD3 / WSJFCost of delay/duration scoreRanking work with different urgencyThe CoD estimate itself
MoSCoWCategoryScope negotiation for a fixed-date deliveryEverything becoming a Must
KanoSatisfaction categoryUnderstanding which features are expected and which differentiateSurvey cost, categories drifting

How Do You Score Technical Debt and Platform Work?

B5 scoring zero in RICE isn't an exception, it's a pattern. Technical debt, infrastructure and platform work don't touch a customer directly, so they always end up last in user-focused frameworks, until the day an incident happens. Three approaches work.

The first is expressing this work as Cost of Delay. A risk like "if the payment SDK shuts down, 120 thousand TRY a week" makes visible what RICE can't see. The same can be done for quieter debt: "changing this module in the order service adds three days to every feature on average" states the cost of delay in developer time.

The second is allocating capacity. Many teams reserve a fixed share of their capacity (15–20% is a common start) for technical work and leave prioritization within that capacity to the engineers. That removes the need to race every technical item against product work one by one.

The third is tying technical work to an outcome. "Move catalog search to Elasticsearch" is an output; "bring the search results page's p95 (95th percentile) response time from 1.8 seconds to 400 milliseconds" is an outcome, and it can be related to product metrics.

HiPPO and the Role of the Framework

HiPPO (Highest Paid Person's Opinion), the opinion of the highest-paid person in the room, is the most powerful informal prioritization method. The general manager's one-click checkout request in the previous posts is a HiPPO example. This is where frameworks show their real value: not to reject the idea, but to judge it by the same rules as the other ideas. When one-click checkout goes into RICE, its reach is only registered customers with a saved card, and that information takes the discussion out of the hierarchy.

But frameworks don't decide; they support the decision. Bringing a RICE table to a meeting as "this is the order, discussion over" just replaces the HiPPO with a table. The table exists to make assumptions visible and to steer the discussion toward the numbers with the most uncertainty.

In Production

Keep scores as living numbers, not one-off ones. The reach of the shipping-cost-on-the-product-page idea should come from the real visitor count we'll measure with events in post 07; when a measurement replaces a guess, the score is updated. Scores filled in once in RICE fields of a backlog tool and never touched again carry wrong information a few months later.

Ask the team for effort, not one person. RICE's denominator is total work in person-months, and the best source for that estimate is the team that will do the work. Effort and the duration in CD3 are not the same: work three people do in one month is three person-months of effort but one month of duration.

Check how sensitive the ranking is. As in our code, changing an uncertain parameter within a reasonable range and seeing whether the ranking changes tells you which decision is robust and which is fragile. Gather more evidence for a fragile decision.

Common Pitfalls

The first pitfall is false precision: writing confidence as 80% without evidence, giving impact a value that isn't on the scale like 1.5, debating scores down to the decimal. A RICE score is an estimate of an estimate; the difference between 4,167 and 4,571 is meaningless next to the uncertainty of the inputs.

The second is using the framework to end the discussion. If "RICE says so" stops people from discussing the assumptions behind the numbers, the framework works against its purpose.

The third is forcing all work into a single framework. User-facing ideas, fixed-date obligations and technical debt can't be compared with the same formula. In the Bookstore example, putting RICE and CD3 side by side made B5 visible, which neither showed on its own.

The fourth is using scoring as a substitute for discovery. If you don't know an idea's impact, learn it with a cheap assumption test as in post 03 instead of scoring it. Prioritization is making the best decision with the information you have; it isn't covering missing information with a number.

A Small Experiment

★☆☆ Raise B6's (catalog search) confidence in the program from 0.5 to 0.8. How does the RICE ranking change? What evidence would justify that change?

★★☆ Add a third ranking to the program: WSJF. Give each item a 1–10 score for user-business value, time criticality and risk reduction, and divide the sum by job size. Does the ranking look more like CD3 or like RICE?

★★★ Pick six items from your own team's backlog, at least one of them technical debt. Score them with both RICE and CD3 and find the item where the two rankings diverge the most. Write a paragraph on why they diverge and discuss it with your team.

We've decided what comes first. In the next post we'll talk about how to communicate these decisions to stakeholders: why dated feature roadmaps keep slipping, Now-Next-Later and outcome roadmaps, and Shape Up's appetite idea, through Bookstore's roadmap for the first half of 2027.