Velocity: Committed vs. Completed

Purpose

Velocity: Committed vs. Completed shows the amount of work planned and completed by iteration (sprint/release).

How metric helps

Velocity: Committed vs. Completed helps to determine a team velocity and to accurately estimate the amount of work a team is able to complete in future iterations.

Chart with Velocity: Committed vs. Completed in Story Points by sprints contains Rolling Average Velocity and Rolling Average Predictability, which helps to find trends that would otherwise be hard to detect.

Questions it answers:

  • how stable is the performance of a team

  • how stable is the reliability of a delivery process.

  • how team keeps its commitments

  • how much work the team can take on/commit to

  • how fast team is identifying / removing roadblocks

  • how accurate estimates are

  • how mature planning is 

  • does team's velocity have any dramatic ramp downs or ramp ups 

  • does scope have any slippage 

  • how work is being ready for development when taken into sprint

How metric works

Chart overview

Velocity: Committed vs. Completed shows the amount of work planned and completed by issue type with the following variations:

  1. Velocity: Committed vs. Completed in items by sprints/releases.

  2. Velocity: Committed vs. Completed in SP by sprints/releases.

  3. Velocity: Committed vs. Completed in remaining hours by sprints.

  4. Velocity: Committed vs. Completed in original hours by sprints/releases.

Axis X - iteration name/timeline;  Axis Y - number of committed and completed items, story points or hours and percentage of predictability in case if chart is Velocity: Committed vs. Completed in SP by sprints.

Chart can be viewed for all issue types in use or for a particular issue type selected in the drop down list.



On hover over a committed column (blue column), a hint appears with the following info:

  • Iteration name - Iteration name as it is in a tracking system;

  • Iteration time frame - Iteration start-end date;

  • Committed - a number/story points/hours of committed items.

On hover over a completed column (purple column), a hint appears with the following info:

  • Iteration name - Iteration name as it is in a tracking system;

  • Iteration time frame - Iteration start-end date;

  • Completed - a number/story points/hours of completed items.

On hover over a metrics on the Velocity: Committed vs. Completed in SP by sprints chart, a hint appears with the following info:

  • Iteration name - Iteration name as it is in a tracking system;

  • Iteration time frame - Iteration start-end date;

  • Committed - story points of committed items.

  • Completed - story points of committed items.

  • Velocity (rolling average 3 sprints) - story points of rolling average velocity for 3 last sprints.

  • Predictability (rolling average 3 sprints) -percentage of rolling average predictability for 3 last sprints.

Chart legend shows the following (with the exception Velocity: Committed vs. Completed in SP by sprints):

  • the last calculated number of committed items;

  • the last calculated number of completed items.

By click on a point a pop up appears with the following information got from a task tracking system: 

  • Issue ID;

  • Type;

  • Priority;

  • Summary.

Top 5 problems metric identifies 

  1. Testing starts late on time

  2. Not ready for development backlog is taken into work

  3. Poor Sprint planning process

  4. Poor dependencies execution

  5. Uncontrolled scope volatility

Calculation

Calculation

Items

Story Points

Original Hours

Remaining hours

Committed

a number of issues assigned to a sprint before or on the sprint start date and time plus Sprint Planning Grace Period 

sum of SP for issues assigned to a sprint before or on the sprint start date and time plus Sprint Planning Grace Period 

sum of Original Hours for issues assigned to a sprint before or on the sprint start date and time plus Sprint Planning Grace Period 

sum of Remaining Hours for issues assigned to a sprint before or on the sprint start date and time plus Sprint Planning Grace Period 

Completed

a number of issues got a 'Done' status before or on the sprint end date/time 

sum of SP for issues got a 'Done' status before or on the sprint end date/time

sum of Original Hours for issues got a 'Done' status before or on the sprint end date/time

sum of Remaining Hours for issues got a 'Done' status before or on the sprint end date/time

Velocity (rolling average 3 sprints)

no

RAV=∑SP - sum of SP for issues completed in a sprint - for Sprint 1 and Sprint 2;

RAV3= (V1+V2+V3)/3

RAV4..n = (Vlast+Vlast-1+Vast-2)/3 - rolling average calculation for Sprint 4 and next sprints .

where

Vlast is Velocity for the last sprint (current).

Vlast-1 is  Velocity for the sprint prior to the last sprint.

Vlast-2 is  Velocity for the sprint prior to the completed of the last sprint.

no

no

Predictability (rolling average 3 sprints)

no

If Completed>Committed:

P1..3 = (AvgSPcommitted/AvgSPcompleted) * 100 %.

If Completed<Committed:

P1..3 = (AvgSPcompleted / AvgSPcommitted) * 100 %

where

AvgSPcompleted is a sum of SP of completed issues averaged for the last 3 completed sprints.

AvgSPcommitted is a sum of SP of committed issues averaged for the last 3 completed sprints.



RAP4..n = (Plast+Plast-1+Plast-2)/3 - rolling average calculation.

where

Plast is Predictability for the last completed sprint.

Plast-1 is Predictability for the sprint prior to the last completed.

Plast-2 is Predictability for the sprint prior to the completed of the last completed.

Including the current sprint.

no

no



Calculation notes

  1. Sprint Planning Grace Period is set in Project configuration>Data Sources>Task Tracking System>Scope Management>Sprint Planning Grace Period

  2. 'Done' statuses are specified in Project Configuration>Data Sources>Task Tracking System>Workflows.

  3. Committed issues moved to another sprint are counted in the sprint they are actually completed.

  4. If, during the sprint, issues were removed from the sprint, then they are not calculated in Completed.

  5. Issues/work items got into a sprint after a sprint start and completed within this sprint are included into Completed.

  6. Reopened and completed issues are included in the completed value calculation by their latest completion date timestamp.

  7. Estimates for Committed are taken at a sprint start including a grace period value if any; 

  8. Estimates for Completed are taken at an issue completion.

  9. Sub items are included into the calculation if "Include sub items into metrics calculation" setting is on.

  10. Calculation of the metrics based on TFS takes into account sprint start at 23:59:59 so the same metric based on Jira data may differ.

  11. Releases without start/end dates are ignored.

  12. Trend line (blue dotted line) calculation (its inclination to axis x) ignores an incomplete iteration in the chart to reveal an accurate tendency.

 

PerfQL

with
sprints as (
select id, name, coalesce(activated_date, start_date) + (sprint_starting_grace_period())::INTERVAL as start_date, coalesce(complete_date, finish_date) as finish_date from sprint
where state != ''FUTURE'' and start_date is not null and start_date < now() and (finish_date is not null or complete_date is not null)
order by finish_date desc limit 12
),

scope as (
select * from ticket
where case when is_include_sub_items() then true else parent_task is null end
),

story_points_field_update_history as (
select
t.id as workitem_id,
coalesce(h.start, t.created) as updated_date,
-- if there is no story_points updates in ticket history then get story_points from ticket
(case
when h.start is null then t.story_points
else h.story_points
end) as story_points,
t.done_date as done
from scope t
left join tickethistory h on t.id = h.workitem_id and h.field = 7
),

story_points_update_history_on_sprint_start as (
select distinct on (h.workitem_id, s.id) h.workitem_id, s.id as sprint_id, h.story_points
from story_points_field_update_history h, sprints s
where h.updated_date < s.start_date
order by h.workitem_id, s.id, h.updated_date desc
),

story_points_update_history_on_sprint_finish as (
select distinct on (h.workitem_id, s.id) h.workitem_id, s.id as sprint_id, h.story_points
from story_points_field_update_history h, sprints s
where h.updated_date < s.finish_date
order by h.workitem_id, s.id, h.updated_date desc
),

sprint_field_update_history as (
select
t.id as workitem_id,
coalesce(h.start,t.created) as updated_date,
-- if there is no sprint updates in ticket history then get sprints from ticket
(case
when h.start is null then t.sprints
else string_to_array(h.sprint, '','')::bigint[]
end) as sprint,
t.done_date
from scope t
left join tickethistory h on t.id = h.workitem_id and h.field = 1
),

sprint_update_history_on_sprint_start as (
select distinct on (h.workitem_id, s.id) h.workitem_id, s.id, h.sprint
from sprint_field_update_history h, sprints s
where h.updated_date < s.start_date
order by h.workitem_id, s.id, h.updated_date desc
),

sprint_update_history_on_sprint_finish as (
select distinct on (h.workitem_id, s.id) h.workitem_id, s.id, h.sprint
from sprint_field_update_history h, sprints s
where h.updated_date < s.finish_date and h.done_date < s.finish_date
order by h.workitem_id, s.id, h.updated_date desc
),

start_sprint_scope as (
select distinct s.id as sprint_id, array_agg(workitem_id) as tickets
from sprints s
inner join sprint_update_history_on_sprint_start h on h.id = s.id and s.id = any(h.sprint)
group by sprint_id
),

finish_sprint_scope as (
select s.id as sprint_id, array_agg(workitem_id) as tickets
from sprints s
inner join sprint_update_history_on_sprint_finish h on h.id = s.id and s.id = any(h.sprint)
group by sprint_id
),

sprint_stat as (
select
s.id,
s.name,
s.start_date,
coalesce(sc.tickets, array[]::bigint[]) as start_items,
coalesce(fc.tickets, array[]::bigint[]) as finish_items
from sprints s
left join start_sprint_scope as sc on s.id = sc.sprint_id
left join finish_sprint_scope as fc on s.id = fc.sprint_id
)

select
s.name as "Sprint",
(select coalesce(sum(story_points), 0) from story_points_update_history_on_sprint_start h
where h.sprint_id = s.id and h.workitem_id = any(start_items)
) as "Committed",
(select coalesce(sum(story_points), 0) from story_points_update_history_on_sprint_finish h
where h.sprint_id = s.id and h.workitem_id = any(finish_items)
) as "Completed"
from sprint_stat s
order by start_date

Data Source

Data for the metric can be collected from a task tracking system (Jira, TFS, Rally, etc.).

See also