on-call-schedule-optimizer

Analyze and optimize on-call schedules for engineering teams. Balance load distribution, respect timezone coverage, minimize burnout, handle holidays and PTO, and generate fair rotation schedules for PagerDuty, OpsGenie, or custom systems.

Safety Notice

This listing is from the official public ClawHub registry. Review SKILL.md and referenced scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "on-call-schedule-optimizer" with this command: npx skills add charlie-morrison/on-call-schedule-optimizer

On-Call Schedule Optimizer

Build on-call schedules that don't burn people out. Analyze current rotation fairness, balance load across timezones, respect PTO and holidays, minimize after-hours pages per person, and generate optimized schedules — for PagerDuty, OpsGenie, or spreadsheets.

Use when: "optimize on-call schedule", "on-call rotation", "fair on-call distribution", "reduce on-call burnout", "timezone coverage", "who's on call too much", or when designing on-call for a new team.

Commands

1. analyze — Audit Current On-Call Schedule

Step 1: Extract Current Schedule

# PagerDuty API
curl -s "https://api.pagerduty.com/schedules/$SCHEDULE_ID" \
  -H "Authorization: Token token=$PD_TOKEN" \
  -H "Content-Type: application/json" | python3 -c "
import json, sys
schedule = json.load(sys.stdin)['schedule']
print(f'Schedule: {schedule[\"name\"]}')
print(f'Timezone: {schedule[\"time_zone\"]}')
for layer in schedule.get('schedule_layers', []):
    print(f'\\nLayer: {layer[\"name\"]}')
    for user in layer.get('users', []):
        print(f'  - {user[\"user\"][\"summary\"]}')
"

# OpsGenie API
curl -s "https://api.opsgenie.com/v2/schedules/$SCHEDULE_ID" \
  -H "Authorization: GenieKey $OG_API_KEY" | python3 -c "
import json, sys
data = json.load(sys.stdin)['data']
print(f'Schedule: {data[\"name\"]}')
print(f'Timezone: {data[\"timezone\"]}')
"

Step 2: Calculate Fairness Metrics

from collections import defaultdict
from datetime import datetime, timedelta

def analyze_on_call_fairness(shifts):
    """Analyze fairness of on-call distribution"""
    person_stats = defaultdict(lambda: {
        'total_hours': 0,
        'weekend_hours': 0,
        'holiday_hours': 0,
        'night_hours': 0,  # 22:00-08:00
        'incidents': 0,
        'consecutive_days': 0,
        'max_consecutive': 0,
    })

    for shift in shifts:
        person = shift['person']
        start = shift['start']
        end = shift['end']
        hours = (end - start).total_seconds() / 3600

        person_stats[person]['total_hours'] += hours

        # Weekend check
        if start.weekday() >= 5:
            person_stats[person]['weekend_hours'] += hours

        # Night check (22:00-08:00)
        if start.hour >= 22 or start.hour < 8:
            person_stats[person]['night_hours'] += hours

    # Print fairness report
    avg_hours = sum(s['total_hours'] for s in person_stats.values()) / len(person_stats)
    for person, stats in sorted(person_stats.items(), key=lambda x: -x[1]['total_hours']):
        deviation = ((stats['total_hours'] - avg_hours) / avg_hours) * 100
        fairness = '🟢' if abs(deviation) < 10 else '🟡' if abs(deviation) < 25 else '🔴'
        print(f'{fairness} {person}: {stats["total_hours"]:.0f}h total ({deviation:+.0f}%), '
              f'{stats["weekend_hours"]:.0f}h weekends, {stats["night_hours"]:.0f}h nights')

Step 3: Generate Report

# On-Call Schedule Analysis

## Fairness Score: 65/100 (⚠️ Unbalanced)

## Load Distribution (last 90 days)
| Person | Total Hours | Weekends | Nights | Incidents | Deviation |
|--------|------------|----------|--------|-----------|-----------|
| Alice | 720h | 180h | 240h | 23 | +15% 🟡 |
| Bob | 480h | 120h | 160h | 12 | -23% 🔴 |
| Carol | 600h | 200h | 200h | 18 | -4% 🟢 |
| Dave | 720h | 100h | 240h | 28 | +15% 🟡 |

## Issues Found
1. 🔴 Alice and Dave carry 30% more load than Bob
2. 🟡 Carol has disproportionate weekend hours (33% vs team avg 25%)
3. 🟡 No timezone diversity — all US-East, gap 02:00-08:00 UTC
4. 🔴 Dave had 14 consecutive on-call days last month (burnout risk)

## Recommendations
1. Equalize rotation: Bob needs more shifts to balance
2. Add weekend weight: count weekend hours as 1.5× for fairness
3. Cap consecutive days at 7
4. Consider follow-the-sun with EU team (if available)

2. generate — Create Optimized Schedule

Given team members, timezones, PTO calendar, and constraints:

  • Generate rotation that minimizes max deviation from fair share
  • Respect PTO and holidays (no on-call during approved time off)
  • Balance weekend and night hours separately
  • Ensure handoff times align with business hours for each timezone
  • Cap consecutive on-call days (default: 7)

3. coverage — Analyze Timezone Coverage

Map on-call coverage across 24 hours:

00  02  04  06  08  10  12  14  16  18  20  22  24
|---US-West---|
         |---US-East---|
                   |---EU----|
                              |---India----|
                                        |---APAC---|
Gap: 03:00-05:00 UTC (no primary on-call)

Recommend schedule layers to fill gaps.

4. burnout — Calculate Burnout Risk

Score each team member's burnout risk based on:

  • Hours on-call in last 30/90 days
  • Incidents handled (especially 2AM+ pages)
  • Consecutive on-call days
  • PTO taken vs owed
  • After-hours page frequency

Flag anyone above threshold and recommend remediation (extra PTO, reduced rotation, hire).

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

三色人格陪伴

恋人、损友、死敌三种陪伴模式。记忆完全隔离不串档,一秒切换情绪状态,承包你所有治愈、解压与情绪拉扯需求。

Registry SourceRecently Updated
General

Zero Api Key Web Search

OpenClaw skill for source-backed web search, page reading, and evidence-aware claim checking. No API keys required by default; optional providers can be enab...

Registry SourceRecently Updated
General

Novel Writer V3.2 - 小说写作引擎

专业小说写作引擎V3.2,支持短篇(3章)到超长篇(500万字)。内置AI味量化检测、四层质检、伏笔管理、角色状态追踪、断点续传。 自动根据字数裁剪流程:短篇模式(<10章)/ 中篇模式(10-50章)/ 长篇模式(50章+)。 触发场景:写小说、小说大纲、小说创作、网文写作、长篇小说、百万字小说、章节规划、 角...

Registry SourceRecently Updated
General

Hk Stock Morning Report

Generate HK stock market morning report (股市晨報) for bank trading desks. Triggers: "生成晨报","股市晨报","今日股市","港股晨報" 推送:微信個人 + 飛書群 | 數據:騰訊財經+stcn.com+格隆匯+實時搜索

Registry SourceRecently Updated