DEV Community

전규현 (Jeon gyuhyeon)
전규현 (Jeon gyuhyeon)

Posted on

Cumulative Flow Diagram: The Truth Burndown Can't Show

Want to understand project status at a glance?

Burndown chart? Good.
Burn-up chart? Better.
But if you don't know Cumulative Flow Diagram (CFD),
You're only seeing half the project.

CFD X-rays the project's health status.
Where bottlenecks are, where work gets stuck,
And even when it will end, all in one graph.

Today, let's learn how to properly utilize this powerful tool.

What is CFD?

Simply put, it's a cumulative graph of task status over time.

Task Count
100 |                    ■■■■■■■■■ Done
    |               ■■■■■░░░░░░░░ Testing
    |          ■■■■■░░░░░░░░░░░░░ In Progress
    |     ■■■■■░░░░░░░░░░░░░░░░░░ To Do
    |■■■■■░░░░░░░░░░░░░░░░░░░░░░░ Backlog
  0 |________________________________
    Day 1   5   10   15   20   25   30
Enter fullscreen mode Exit fullscreen mode

The height of each colored band represents the number of tasks in that status.

5 Secrets CFD Tells

1. WIP (Work In Progress) at a Glance

def analyze_wip(cfd_data, day):
    """Calculate WIP for specific date"""
    in_progress = cfd_data[day]['in_progress']
    testing = cfd_data[day]['testing']
    review = cfd_data[day]['review']

    total_wip = in_progress + testing + review

    if total_wip > team_size * 2:
        return "⚠️ Excessive WIP! Bottleneck occurring"
    else:
        return "✅ Maintaining appropriate WIP"
Enter fullscreen mode Exit fullscreen mode

Band widening = WIP increasing = Danger signal

2. Immediate Bottleneck Discovery

// Bottleneck pattern detection
const bottleneckPatterns = {
  testing_bottleneck: {
    symptom: 'Testing band keeps widening',
    cause: 'QA resource shortage',
    solution: 'Test automation or add QA personnel',
  },

  review_bottleneck: {
    symptom: 'Review band thickening',
    cause: 'Code review delay',
    solution: 'Add reviewers or pair programming',
  },
};
Enter fullscreen mode Exit fullscreen mode

If a specific band keeps widening, that stage is the bottleneck.

3. Throughput Measurement

# CFD slope = Throughput
def calculate_throughput(cfd_data, start_day, end_day):
    completed_start = cfd_data[start_day]['done']
    completed_end = cfd_data[end_day]['done']

    days = end_day - start_day
    throughput = (completed_end - completed_start) / days

    return f"{throughput:.1f} tasks/day"

# Example: 50 completed in 10 days = 5 tasks/day
Enter fullscreen mode Exit fullscreen mode

The steeper the Done line slope, the faster the team works.

4. Lead Time Prediction

Drawing a horizontal line in CFD shows lead time.

    |     ■■■■■■■■■■■■■■■■■■■ Done
    |  ■■■░░░░░░░░░░░░░░░░░░░ Testing
    | ■░░░░░░░░░░░░░░░░░░░░░░ In Progress
    |■━━━━━━━━━━━━━━━━━━━━━━━> This task's journey
    |░░░░░░░░░░░░░░░░░░░░░░░░ To Do
    └────────────────────────
     ↑Start                  ↑Complete
     └──── 15 days (Lead Time) ───┘
Enter fullscreen mode Exit fullscreen mode

5. Project Completion Prediction

def predict_completion(cfd_data):
    """When will it end at current velocity?"""

    remaining_work = cfd_data['backlog'] + cfd_data['todo']
    current_velocity = calculate_weekly_velocity()

    weeks_needed = remaining_work / current_velocity
    completion_date = today + timedelta(weeks=weeks_needed)

    # Consider uncertainty
    best_case = completion_date - timedelta(weeks=weeks_needed * 0.2)
    worst_case = completion_date + timedelta(weeks=weeks_needed * 0.3)

    return {
        "expected": completion_date,
        "best_case": best_case,
        "worst_case": worst_case
    }
Enter fullscreen mode Exit fullscreen mode

Reading CFD Patterns: Healthy Team vs Problematic Team

Healthy CFD

Ideal Pattern:
- Each band maintains constant thickness
- Done line steadily rising
- Overall parallel line form
Enter fullscreen mode Exit fullscreen mode

Problematic CFD Patterns

1. Staircase Pattern

    |      ■■■■■
    |      ■    ■■■■■
    | ■■■■■         ■■■
Enter fullscreen mode Exit fullscreen mode

Cause: Batch processing
Solution: Switch to continuous flow

2. Flat Done Line

    |─────────────────── Done not rising
Enter fullscreen mode Exit fullscreen mode

Cause: Not completing
Solution: Remove blockers, redefine Definition of Done

3. Expanding Band

    |     ▲ Testing area keeps widening
    |    ■■■
    |  ■■░░░■■
    | ■░░░░░░░■
Enter fullscreen mode Exit fullscreen mode

Cause: Specific stage bottleneck
Solution: Strengthen resources for that stage

Practice: Implementing CFD

Simple CFD Generation Code

class CumulativeFlowDiagram {
  constructor(tasks) {
    this.tasks = tasks;
    this.states = ['Backlog', 'Todo', 'InProgress', 'Testing', 'Done'];
  }

  generateData() {
    const dates = this.getDateRange();
    const data = [];

    dates.forEach((date) => {
      const dayData = {
        date: date,
        counts: this.getTaskCountsByState(date),
      };
      data.push(dayData);
    });

    return this.cumulativeSum(data);
  }

  cumulativeSum(data) {
    // Convert each state to cumulative
    return data.map((day) => {
      let cumulative = 0;
      const result = { date: day.date };

      this.states.forEach((state) => {
        cumulative += day.counts[state];
        result[state] = cumulative;
      });

      return result;
    });
  }

  detectBottlenecks() {
    // Detect sections where band width increases
    const warnings = [];

    this.states.forEach((state) => {
      if (this.isBandWidening(state)) {
        warnings.push({
          state: state,
          message: `Tasks accumulating in ${state} stage`,
        });
      }
    });

    return warnings;
  }
}
Enter fullscreen mode Exit fullscreen mode

Making CFD in Excel

You can easily make it in Excel:

Date    | Backlog | Todo | InProgress | Testing | Done
--------|---------|------|------------|---------|------
Day 1   |    50   |  0   |     0      |    0    |   0
Day 2   |    45   |  5   |     0      |    0    |   0
Day 3   |    40   |  8   |     2      |    0    |   0
Day 4   |    35   | 10   |     3      |    2    |   0
Day 5   |    30   | 12   |     4      |    2    |   2

→ Visualize as stacked area chart
Enter fullscreen mode Exit fullscreen mode

CFD Utilization Tips

1. Update Daily

CFD must be updated daily to be meaningful.
Automation is even better.

2. Analyze with Team

Weekly Friday CFD Review:

- Where was this week's bottleneck?
- Did processing speed change?
- Next week's prediction?
Enter fullscreen mode Exit fullscreen mode

3. View with Other Metrics

weekly_metrics = {
    "cfd_analysis": analyze_cfd(),
    "velocity": calculate_velocity(),
    "cycle_time": measure_cycle_time(),
    "burndown": check_burndown()
}

# Comprehensive health score
health_score = calculate_project_health(weekly_metrics)
Enter fullscreen mode Exit fullscreen mode

Little's Law and CFD

You can see Little's Law directly in CFD:

Average Lead Time = WIP / Throughput

Example: WIP 20, daily throughput 4
→ Average Lead Time = 20/4 = 5 days
Enter fullscreen mode Exit fullscreen mode

In CFD, vertical distance is WIP, slope is throughput.

Conclusion: CFD is the Project's EKG

Just as doctors see heart status with EKG,
PMs see project status with CFD.

If burndown charts show "how much is left",
CFD shows "how is it flowing."

Both are needed, but CFD tells more.

Start drawing CFD from tomorrow.
Hidden project problems will be visible at a glance.


Need real-time CFD and advanced project analysis? Check out Plexo.

Top comments (0)