Estimate volunteer capacity for projects
The problem
You're planning a project that needs 100 volunteer hours, but you're not sure if that's realistic. You know 20 volunteers have expressed interest, but historically some drop out, others can't commit the hours they hoped, and availability drops over summer. You need a realistic estimate of actual capacity, not wishful thinking.
The solution
Use historical data on volunteer attendance, drop-out rates, and seasonal patterns to predict realistic capacity for upcoming projects. Account for: people who sign up but don't show up, reduction in hours over time, seasonal effects, and the fact that new volunteers often do less than established ones. Build in buffer for the gap between 'interested' and 'actually available'.
What you get
A realistic volunteer capacity forecast for your project showing: (1) Expected hours per week/month from current volunteers, (2) Likely drop-out rate, (3) Seasonal adjustment factors, (4) Conservative, realistic, and optimistic scenarios, (5) Recommendations on whether to recruit more volunteers or scale back project scope.
Before you start
- At least 6 months of volunteer attendance records (who showed up, for how long)
- Basic tracking of volunteer lifecycle (when they joined, when they left if applicable)
- Project plan with estimated hours needed
- List of volunteers committed (or potentially committed) to upcoming project
- Check GDPR compliance - processing individual volunteer data for capacity planning should be covered in your privacy notice. Be transparent with volunteers about how their data supports organisational planning
When to use this
- Planning projects that depend on volunteer capacity (events, ongoing programmes)
- You've had projects fail because volunteers didn't turn up as expected
- Need to decide whether to recruit more volunteers or scale back scope
- Securing funding that requires demonstrating realistic volunteer commitment
- You have 6+ months of historical data to learn from
When not to use this
- First time running volunteers (no historical data to learn from)
- Very small volunteer numbers (< 10) - individual variation too high
- Volunteers are highly committed staff-like people (not typical drop-in pattern)
- Project timeline is so short that historical patterns don't apply
- You already track this well and have reliable capacity estimates
Steps
- 1
Gather historical volunteer attendance data
Pull records from the last 6-12 months: volunteer ID/name, session date, hours contributed. You need individual-level data (not just 'we had 50 volunteer hours this week'). If using sign-in sheets, digitise them. Even approximate data (morning session = 3 hours) is better than nothing. Note: This recipe uses Python for analysis - Google Sheets is mentioned for data storage/entry, but the capacity modelling requires running the Python code.
- 2
Calculate individual volunteer patterns
For each volunteer, calculate: (1) Average hours per month, (2) Consistency (do they volunteer every week or sporadically?), (3) How long they've been volunteering (newbies often drop out faster), (4) Any seasonal patterns (less in summer, more at Christmas?). This creates a baseline for each person.
- 3
Analyse drop-out rates
Track volunteers who stopped: when did they join, when did they leave, how active were they? Calculate drop-out curves: X% leave within first month, Y% between months 2-6, Z% are long-term. New project volunteers will follow similar patterns.
- 4
Identify seasonal effects
Group data by month and look for patterns: volunteer hours often drop in summer holidays, exam periods, December (too busy), or specific to your context (harvest time for rural charity, term-time for student volunteers). Quantify the effect: e.g., July has 30% fewer hours than March.
- 5
Build capacity model for upcoming project
For your project: list volunteers who've committed, look up their average hours from baseline, apply drop-out probability based on how long they've volunteered, adjust for seasonal effects during project timeline. Sum to get total expected capacity. This is your realistic scenario.
- 6
Create optimistic and conservative scenarios
Conservative: Apply higher drop-out rates and lower hours per person (what if people are over-optimistic?). Optimistic: Lower drop-out, higher hours (what if recruitment goes brilliantly?). Realistic: Your baseline model. Present all three to help decide on project scope and recruitment needs.
- 7
Compare capacity to project requirements
Does your realistic scenario meet project needs? If project needs 400 hours over 3 months and realistic forecast is 250 hours, you have a gap. Options: recruit more volunteers (account for induction time), extend timeline, reduce scope. If optimistic scenario still doesn't meet needs, major rethink required.
- 8
Monitor actuals and update model
As project runs: track actual volunteer hours against forecast. Where are you over/under? Why? Use this learning to improve the model for next time. Maybe your drop-out rates are different, or seasonal effects stronger than expected. Forecasting gets better with iteration.
Example code
Forecast volunteer capacity for upcoming project
Forecast volunteer capacity accounting for drop-out rates, seasonal effects, and individual patterns.
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
# Load historical volunteer data
df = pd.read_csv('volunteer_hours.csv', parse_dates=['date'])
# Calculate baseline patterns for each volunteer
volunteer_stats = df.groupby('volunteer_id').agg({
'hours': 'sum',
'date': ['min', 'max', 'count']
}).reset_index()
volunteer_stats.columns = ['volunteer_id', 'total_hours', 'first_date', 'last_date', 'sessions']
# Calculate months active and average hours per month
volunteer_stats['months_active'] = (
(volunteer_stats['last_date'] - volunteer_stats['first_date']).dt.days / 30
).clip(lower=1) # Minimum 1 month
volunteer_stats['avg_hours_per_month'] = volunteer_stats['total_hours'] / volunteer_stats['months_active']
# Calculate how long each volunteer has been with us
# Use a reference date (e.g., project start) instead of datetime.now()
# if analysing historical data or for reproducible results
reference_date = datetime.now() # Or: datetime(2024, 7, 1) for a specific date
volunteer_stats['tenure_months'] = (
(reference_date - volunteer_stats['first_date']).dt.days / 30
)
# Drop-out probability based on tenure (example rates)
def dropout_probability(tenure_months):
if tenure_months < 1:
return 0.40 # 40% of new volunteers drop out in first month
elif tenure_months < 6:
return 0.20 # 20% drop out in months 2-6
else:
return 0.05 # 5% of established volunteers drop out
volunteer_stats['dropout_prob'] = volunteer_stats['tenure_months'].apply(dropout_probability)
# Seasonal adjustment (example: summer months have 30% less capacity)
seasonal_factors = {
'Jan': 1.0, 'Feb': 1.0, 'Mar': 1.0, 'Apr': 1.0,
'May': 0.9, 'Jun': 0.7, 'Jul': 0.7, 'Aug': 0.7,
'Sep': 0.9, 'Oct': 1.0, 'Nov': 1.0, 'Dec': 0.8
}
# Forecast capacity for project (e.g., July-September)
project_months = ['Jul', 'Aug', 'Sep']
project_duration_months = 3
# Calculate expected capacity
volunteer_stats['expected_hours_per_month'] = (
volunteer_stats['avg_hours_per_month'] *
(1 - volunteer_stats['dropout_prob']) # Adjust for dropout
)
# Apply seasonal adjustment (average across project months)
avg_seasonal = np.mean([seasonal_factors[m] for m in project_months])
volunteer_stats['project_expected_hours'] = (
volunteer_stats['expected_hours_per_month'] *
project_duration_months *
avg_seasonal
)
# Three scenarios
conservative_multiplier = 0.7 # Conservative: assume 30% less than expected
optimistic_multiplier = 1.2 # Optimistic: assume 20% more than expected
total_realistic = volunteer_stats['project_expected_hours'].sum()
total_conservative = total_realistic * conservative_multiplier
total_optimistic = total_realistic * optimistic_multiplier
print(f"Volunteer Capacity Forecast for {project_duration_months}-month project ({', '.join(project_months)}):")
print(f" Conservative scenario: {total_conservative:.0f} hours")
print(f" Realistic scenario: {total_realistic:.0f} hours")
print(f" Optimistic scenario: {total_optimistic:.0f} hours")
print(f"\nBased on {len(volunteer_stats)} volunteers")
print(f"\nTop contributors (realistic scenario):")
print(volunteer_stats.nlargest(5, 'project_expected_hours')[['volunteer_id', 'project_expected_hours', 'tenure_months']])Tools
Resources
At a glance
- Time to implement
- days
- Setup cost
- free
- Ongoing cost
- free
- Cost trend
- stable
- Organisation size
- small, medium, large
- Target audience
- volunteer-coordinator, operations-manager, program-delivery
Free tools are sufficient. Time cost: 2 days initial analysis, then 2-3 hours per project to run capacity forecast.