TechLead
Lesson 13 of 30
5 min read
Project Management

Backlog Management and Prioritization

Master product backlog management, refinement, INVEST criteria, and prioritization frameworks including MoSCoW, RICE, WSJF, and Kano

Product Backlog vs. Sprint Backlog

The Product Backlog is an ordered list of everything that might be needed in the product. It is the single source of requirements and is continuously refined. The Sprint Backlog is a subset of product backlog items selected for the current sprint, plus the team's plan to deliver them.

Aspect Product Backlog Sprint Backlog
OwnerProduct OwnerDevelopment Team
ScopeEntire product visionOne sprint's work
LifespanEntire product lifecycleOne sprint (2-4 weeks)
Detail LevelTop items refined, bottom items roughAll items have tasks and estimates
ChangesContinuously updatedLocked during sprint (with exceptions)

Backlog Refinement

Backlog refinement (formerly called "grooming") is an ongoing activity where the team reviews, clarifies, estimates, and orders backlog items. It typically consumes 5-10% of the team's capacity. The goal is to ensure that the top of the backlog is always "ready" for Sprint Planning.

INVEST Criteria for User Stories

Well-written user stories satisfy the INVEST criteria:

  • I - Independent: Can be developed and delivered independently of other stories
  • N - Negotiable: Details can be discussed; it is not a rigid contract
  • V - Valuable: Delivers value to the user or business
  • E - Estimable: Team can estimate the effort required
  • S - Small: Can be completed within a single sprint
  • T - Testable: Has clear acceptance criteria that can be verified

Prioritization Frameworks

// RICE Scoring Calculator
interface RICEScore {
  itemId: string;
  title: string;
  reach: number;       // How many users per quarter
  impact: number;      // 0.25 (minimal), 0.5 (low), 1 (medium), 2 (high), 3 (massive)
  confidence: number;  // 0-100 percentage
  effort: number;      // Person-months
  score: number;       // (Reach * Impact * Confidence) / Effort
}

function calculateRICE(
  reach: number,
  impact: number,
  confidence: number,
  effort: number
): number {
  return (reach * impact * (confidence / 100)) / effort;
}

// Example: Prioritizing features
const features: RICEScore[] = [
  {
    itemId: 'F-001',
    title: 'One-click checkout',
    reach: 50000,
    impact: 2,
    confidence: 80,
    effort: 3,
    score: calculateRICE(50000, 2, 80, 3) // = 26,667
  },
  {
    itemId: 'F-002',
    title: 'Product recommendations',
    reach: 100000,
    impact: 1,
    confidence: 60,
    effort: 5,
    score: calculateRICE(100000, 1, 60, 5) // = 12,000
  },
  {
    itemId: 'F-003',
    title: 'Dark mode',
    reach: 30000,
    impact: 0.5,
    confidence: 90,
    effort: 1,
    score: calculateRICE(30000, 0.5, 90, 1) // = 13,500
  },
  {
    itemId: 'F-004',
    title: 'Advanced search filters',
    reach: 40000,
    impact: 1,
    confidence: 70,
    effort: 2,
    score: calculateRICE(40000, 1, 70, 2) // = 14,000
  }
].sort((a, b) => b.score - a.score);

// WSJF (Weighted Shortest Job First) — SAFe prioritization
interface WSJFScore {
  itemId: string;
  title: string;
  businessValue: number;    // 1-10
  timeCriticality: number;  // 1-10
  riskReduction: number;    // 1-10
  jobSize: number;          // 1-10 (relative effort)
  wsjf: number;             // (BV + TC + RR) / Job Size
}

function calculateWSJF(
  businessValue: number,
  timeCriticality: number,
  riskReduction: number,
  jobSize: number
): number {
  const costOfDelay = businessValue + timeCriticality + riskReduction;
  return costOfDelay / jobSize;
}

// ICE Scoring (simpler alternative to RICE)
interface ICEScore {
  impact: number;      // 1-10
  confidence: number;  // 1-10
  ease: number;        // 1-10
  score: number;       // impact * confidence * ease
}

// Kano Model Classification
type KanoCategory = 'must-be' | 'one-dimensional' | 'attractive' | 'indifferent' | 'reverse';

interface KanoFeature {
  name: string;
  category: KanoCategory;
  description: string;
}

const kanoFeatures: KanoFeature[] = [
  { name: 'Login works', category: 'must-be', description: 'Expected — absence causes dissatisfaction, presence does not delight' },
  { name: 'Page speed', category: 'one-dimensional', description: 'Linear — more speed = more satisfaction' },
  { name: 'AI product recommendations', category: 'attractive', description: 'Unexpected delight — absence is ok, presence delights' },
  { name: 'Comic Sans font option', category: 'reverse', description: 'Would actually reduce satisfaction' },
];

Prioritization Frameworks Comparison

Framework Best For Complexity Key Metric
MoSCoWRelease scoping, stakeholder alignmentLowMust / Should / Could / Won't
RICEProduct teams with data on reachMedium(Reach x Impact x Confidence) / Effort
WSJFSAFe teams, time-sensitive workMediumCost of Delay / Job Size
KanoUnderstanding user delight vs expectationMedium-HighMust-be / Performance / Attractive
ICEQuick scoring for growth experimentsLowImpact x Confidence x Ease

Backlog Health Checklist

  • Top 2 sprints are refined: Items in the top 15-20 have acceptance criteria, estimates, and are ready for Sprint Planning
  • No zombie items: Items that have been sitting for 6+ months are either promoted or removed
  • Single ordering: The backlog has ONE priority order, not multiple "high priority" items
  • Right-sized: Total backlog is manageable (50-150 items). More creates noise.
  • Aligned with roadmap: Top items map to current quarter's OKRs or roadmap themes

Continue Learning