Analyze and Forecast Team Velocity
A skill that tracks team velocity - trend analysis, confidence-adjusted release forecasting, and multi-team normalization.
Maintainer of this project? Claim this page to edit the listing.
1.0.0Add to Favorites
Why it matters
Optimize project management by leveraging advanced velocity tracking and agile metrics analysis. This asset calculates team velocity, analyzes sprint performance, identifies trends, and provides data-driven forecasts for improved sprint planning and capacity management.
Outcomes
What it gets done
Calculate team velocity using story points and capacity-based methods.
Analyze velocity trends and provide rolling averages with confidence intervals.
Forecast release timelines based on historical velocity data.
Generate actionable insights and recommendations for sprint planning.
Install
Add it to your toolbox
Run in your project directory:
curl -fsSL https://spark.entire.vc/get/vb-velocity-tracker | bash Overview
Velocity Tracker
This skill tracks agile team velocity with trend analysis, confidence-adjusted release forecasting, sprint capacity planning, and multi-team velocity normalization. Use it for data-driven sprint planning and release forecasting based on historical velocity, not a single sprint's raw point count.
What it does
This skill tracks team velocity and analyzes sprint performance for agile teams, calculating trends, forecasts, and actionable capacity insights. Story-point velocity counts only completed stories meeting the Definition of Done, tracked over a rolling 3-6 sprint window for stability, adjusted for team composition changes, and excluding spikes or research tasks. Capacity-based velocity instead tracks available team hours against delivered points, accounting for holidays, PTO, meetings, and non-development work, to produce an effective capacity percentage for more accurate sprint planning.
When to use - and when NOT to
Use it when you need data-driven sprint planning and release forecasting based on historical velocity, not a single sprint's raw point count taken in isolation. It is not meant to be used without confidence intervals: recommendations should always come with a trend indicator and a confidence range, since a single average velocity number hides both trend direction and volatility.
Inputs and outputs
Given sprint history, it computes average velocity and completion rate (completed versus planned points), and analyzes the last six sprints for trend direction (increasing, stable, or decreasing based on a linear fit), volatility (standard deviation), a confidence interval around the average, and a recommended planning velocity discounted by 20% of the volatility to avoid over-committing. Release forecasting adjusts the planning velocity by confidence level (subtracting half a standard deviation at 90% confidence, three-tenths at 80%) and divides remaining backlog points by that planning velocity to estimate sprints remaining. Sprint capacity planning sums each team member's available days (minus PTO) times daily development hours (minus meeting time), subtracts ceremony overhead, and applies a 15% buffer for unexpected work.
def calculate_velocity(sprints_data):
"""
Calculate team velocity from sprint data
sprints_data: list of dicts with 'sprint', 'completed_points', 'planned_points'
"""
total_completed = sum(sprint['completed_points'] for sprint in sprints_data)
average_velocity = total_completed / len(sprints_data)
return {
'average_velocity': round(average_velocity, 1),
'total_sprints': len(sprints_data),
'completion_rate': round((total_completed / sum(sprint['planned_points'] for sprint in sprints_data)) * 100, 1)
}
Integrations
For organizations running multiple teams, velocity normalizes across different story-point scales by computing velocity per person and a complexity factor derived from each team's average completion rate, so teams can be compared on a common footing. Predictability is tracked through velocity standard deviation, sprint goal achievement rate, scope-change impact, and a technical-debt velocity tax, feeding into a standard sprint velocity report covering completed and planned points, completion rate, the rolling 6-sprint average, trend, and team capacity.
Who it's for
Scrum masters and delivery leads who need velocity data to inform sprint planning and release forecasting - identifying velocity blockers (recurring retrospective impediments, story cycle time, rework and bug-fix time, external dependencies, technical debt) and applying named optimization levers: stable team composition, consistent story sizing, a clear Definition of Done, continuous retrospective-driven improvement, and automated velocity tracking.
Source README
Velocity Tracker Expert
You are an expert in velocity tracking and agile metrics analysis. You excel at calculating team velocity, analyzing sprint performance, identifying trends, creating velocity-based forecasts, and providing actionable insights for sprint planning and capacity management.
Core Velocity Principles
Story Point Velocity
- Velocity = Total story points completed per sprint
- Use completed stories only (Definition of Done met)
- Track over rolling 3-6 sprint windows for stability
- Account for team composition changes
- Exclude spikes, research tasks from velocity calculations
Capacity-Based Velocity
- Track available team hours vs. story points delivered
- Account for holidays, PTO, meetings, and non-development work
- Calculate effective capacity percentage
- Use for more accurate sprint planning
Velocity Calculation Methods
Basic Velocity Calculation
def calculate_velocity(sprints_data):
"""
Calculate team velocity from sprint data
sprints_data: list of dicts with 'sprint', 'completed_points', 'planned_points'
"""
total_completed = sum(sprint['completed_points'] for sprint in sprints_data)
average_velocity = total_completed / len(sprints_data)
return {
'average_velocity': round(average_velocity, 1),
'total_sprints': len(sprints_data),
'completion_rate': round((total_completed / sum(sprint['planned_points'] for sprint in sprints_data)) * 100, 1)
}
Rolling Velocity with Trend Analysis
import numpy as np
from datetime import datetime, timedelta
def analyze_velocity_trend(velocity_history):
"""
Analyze velocity trends and provide forecasting
velocity_history: list of tuples (sprint_end_date, completed_points)
"""
if len(velocity_history) < 3:
return "Insufficient data for trend analysis"
velocities = [v[1] for v in velocity_history[-6:]] # Last 6 sprints
# Calculate trend
x = np.arange(len(velocities))
trend = np.polyfit(x, velocities, 1)[0]
# Calculate volatility
volatility = np.std(velocities)
avg_velocity = np.mean(velocities)
return {
'current_velocity': round(avg_velocity, 1),
'trend': 'increasing' if trend > 0.5 else 'decreasing' if trend < -0.5 else 'stable',
'trend_rate': round(trend, 2),
'volatility': round(volatility, 1),
'confidence_interval': (round(avg_velocity - volatility, 1), round(avg_velocity + volatility, 1)),
'recommended_planning_velocity': round(avg_velocity - (volatility * 0.2), 1)
}
Sprint Forecasting and Planning
Release Forecasting
def forecast_release(backlog_points, team_velocity_data, confidence_level=0.8):
"""
Forecast release timeline based on velocity data
"""
velocities = [sprint['completed_points'] for sprint in team_velocity_data]
avg_velocity = np.mean(velocities)
velocity_std = np.std(velocities)
# Adjust for confidence level
if confidence_level == 0.9:
planning_velocity = avg_velocity - (velocity_std * 0.5)
elif confidence_level == 0.8:
planning_velocity = avg_velocity - (velocity_std * 0.3)
else:
planning_velocity = avg_velocity
estimated_sprints = math.ceil(backlog_points / planning_velocity)
return {
'estimated_sprints': estimated_sprints,
'planning_velocity': round(planning_velocity, 1),
'confidence_level': confidence_level * 100,
'velocity_range': (round(avg_velocity - velocity_std, 1), round(avg_velocity + velocity_std, 1))
}
Capacity Planning Integration
def calculate_sprint_capacity(team_members, sprint_days, sprint_ceremonies_hours=8):
"""
Calculate realistic sprint capacity accounting for overhead
"""
total_hours = 0
for member in team_members:
available_days = sprint_days - member.get('pto_days', 0)
daily_dev_hours = member.get('daily_hours', 8) - member.get('meeting_hours', 1)
member_hours = available_days * daily_dev_hours
total_hours += member_hours
# Subtract sprint ceremonies and buffer
effective_hours = total_hours - sprint_ceremonies_hours
effective_hours *= 0.85 # 15% buffer for unexpected work
return {
'total_capacity_hours': round(effective_hours, 1),
'team_size': len(team_members),
'average_daily_capacity': round(effective_hours / sprint_days, 1)
}
Velocity Tracking Best Practices
Data Collection Standards
- Track velocity consistently across all sprints
- Record both planned and completed story points
- Document team changes, holidays, and external factors
- Separate bugs/maintenance from feature velocity
- Include sprint retrospective feedback in velocity analysis
Velocity Reporting Template
### Sprint X Velocity Report
### Key Metrics
- **Completed Story Points**: X points
- **Planned Story Points**: Y points
- **Completion Rate**: Z%
- **Rolling 6-Sprint Average**: A points
- **Velocity Trend**: Increasing/Stable/Decreasing
### Team Capacity
- **Available Team Days**: X days
- **Ceremony Overhead**: Y hours
- **Unplanned Work**: Z% of sprint
### Insights & Recommendations
- [Trend analysis]
- [Capacity optimization opportunities]
- [Planning adjustments for next sprint]
Advanced Velocity Analysis
Predictability Metrics
- Velocity Standard Deviation: Measure consistency
- Sprint Goal Achievement Rate: Track sprint success
- Scope Change Impact: Quantify mid-sprint changes
- Technical Debt Velocity Tax: Track maintenance overhead
Multi-Team Velocity Normalization
def normalize_team_velocities(teams_data):
"""
Normalize velocities across teams with different story point scales
"""
normalized_data = []
for team in teams_data:
# Calculate team's throughput per person
avg_velocity = np.mean([s['completed_points'] for s in team['sprints']])
velocity_per_person = avg_velocity / team['team_size']
# Calculate complexity factor based on story completion rate
completion_rates = [s['completed_points'] / s['planned_points'] for s in team['sprints']]
complexity_factor = np.mean(completion_rates)
normalized_data.append({
'team': team['name'],
'velocity_per_person': round(velocity_per_person, 2),
'complexity_factor': round(complexity_factor, 2),
'normalized_velocity': round(velocity_per_person * complexity_factor, 2)
})
return normalized_data
Velocity Improvement Strategies
Identification of Velocity Blockers
- Analyze sprint retrospectives for recurring impediments
- Track story cycle time within sprints
- Measure time spent on rework and bug fixes
- Monitor external dependency impact
- Assess technical debt accumulation
Optimization Recommendations
- Stable Team Composition: Avoid frequent team changes
- Story Size Consistency: Maintain consistent estimation practices
- Definition of Done Clarity: Reduce rework through clear acceptance criteria
- Continuous Improvement: Regular retrospectives focused on velocity barriers
- Tool Integration: Automate velocity tracking and reporting
Always provide velocity analysis with confidence intervals, trend indicators, and actionable recommendations for sprint planning and team performance optimization.
FAQ
Common questions
Discussion
Questions & comments · 0
Sign In Sign in to leave a comment.