# On-call burden and fairness board for incident.io rotations

> See who is really carrying your on-call rotation, compare pages per shift against a sustainable benchmark, and fix the imbalance before the next cycle.

- Workflow type: app
- Services: incident.io, Slack Bot
- Categories: Engineering, HR & People
- Published: 2026-08-31

## What it does

- Shows one row per person for the window you pick, with scheduled shifts, hours on call, how many alerts actually reached them, how many landed at night or on a weekend, and how many incidents they led.
- Sorts the most loaded people to the top and compares each person's pages per shift against a sustainable benchmark of about two pages per twelve hour shift, so you are looking at real load rather than calendar time.
- Lets you click any person to see their individual shifts and every page they took, then cover a rough shift for them and announce the swap to your team in Slack.
- Includes a Review this rotation button that reads the same schedule and alert history and writes a fairness brief back into the board, naming who is overloaded, which shifts are consistently brutal, and which swaps to make next cycle.

## What you'll need

- An incident.io account already using on-call schedules and alerts
- A Slack workspace for announcing shift swaps to the team
- Permission in incident.io to create schedule overrides, if you want to cover shifts straight from the board
- Your team's normal working hours, weekend days and timezone, so nights and weekends are counted correctly

## Prompt

Build me an on-call burden and fairness board for incident.io that my engineering managers open before every rotation planning session. The whole point is to answer one question honestly: who is actually carrying this rotation, and what should we change next cycle.

The main view is a table with one row per person covering a window I pick at the top of the page, defaulting to the last 4 weeks with presets for last 4 weeks, last 8 weeks and last quarter. Each row shows the person's name, number of scheduled shifts, total scheduled hours on call, how many alerts actually reached them, how many of those landed out of hours, how many landed on a weekend, how many incidents they led, and their pages per shift. Sort the table so the most loaded person sits at the top by default, using a load score that weights actual pages and out of hours pages more heavily than raw scheduled hours, and let me re-sort by any column.

Server side handlers build this from incident.io. Use List Schedules to find the schedules in scope, List Schedule Entries to get who was on call for which windows, List Alerts and List Escalations to work out which pages actually reached a given person, and List Incidents to count who held the lead role on each incident. Fetch the window once, aggregate per person inside the handler, and return a ready shaped row set to the UI rather than making the browser stitch it together.

Important nuance: incident.io has no list users operation, so there is no roster to fetch. Derive the roster from the people who appear in schedule entries during the window plus the people assigned to incident roles on incidents in the window, then merge those two sets on the incident.io user id and keep the display name from whichever record carries it. Someone who was scheduled but never paged should still appear with zero pages, and someone who led incidents without appearing on a schedule should still appear.

Working hours and timezone must be configurable per team and persisted in the app rather than hardcoded. Give me a settings panel where I set the timezone, the normal working day start and end, and which days count as the weekend. The out of hours calculation uses those settings: a page is out of hours when its timestamp falls outside working hours in the configured timezone, and it is a weekend page when it falls on a configured weekend day. Changing the settings recalculates the board.

Judge load against a sustainable benchmark rather than only counting calendar time. Compute pages per 12 hours of on call for each person and compare that against a benchmark of roughly 2 pages per 12 hour shift, which is a widely cited sustainable ceiling. Show the benchmark visibly on the board, flag any person sitting over it, and flag individual shifts over it in the drill down. Make the benchmark editable in settings for teams running different shift lengths.

Clicking a person opens their detail view: every shift they worked in the window with its start and end, the number of pages during that shift, whether the shift was out of hours or on a weekend, and a flag when the shift exceeded the benchmark, plus the individual alerts and escalations that reached them with timestamps, and the incidents they led. This is where I confirm whether a person's high total came from a few brutal shifts or a steady grind.

From any row on the main board I can cover that person. The cover dialog lets me pick one of their upcoming shifts, choose who takes it, and confirm, which writes a schedule override using Create Schedule Override. Once the override is written, announce the swap with the Slack Bot Send a Message action to a channel I configure, naming who is covering for whom, which schedule, and the shift window. Show me the message before it sends and let me edit the text.

Add a Review this rotation button that kicks off a background agent. The agent reads the same schedule and alert history the board is built from, using the same incident.io operations, then writes a fairness brief back into the app so the board can display it. The brief should name who is carrying too much and by how much relative to the rest of the team, call out which specific shifts or recurring slots are consistently brutal, for example a recurring weekend night that always pages, and recommend specific swaps to make next cycle rather than generic advice. Store each brief with the timestamp it was generated and the window it covered, show the most recent one in a panel on the main board, and keep previous briefs viewable so I can compare across planning cycles.

Handle the thin cases gracefully: a window with no schedule entries, a person with scheduled hours but zero pages, and schedules that ran with gaps. Show the active window and the configured timezone in the header so nobody misreads the numbers.

## How to customize

- Change the review window: four weeks is the usual minimum for judging fair distribution, but you can look back a full quarter before rotation planning.
- Set working hours, weekend days and timezone per team, so out of hours means the same thing for everyone on the board.
- Adjust the sustainable load benchmark if your team runs shifts longer or shorter than twelve hours.
- Choose which schedules the board covers and which Slack channel swap announcements go to.

## FAQ

### Does this show everyone on my team automatically?

The board builds its roster from the people who actually show up in your on-call schedules and incident roles during the window you pick. incident.io does not publish a team directory, so anyone who was never scheduled and never held an incident role in that period will not appear. That is intentional: the board is about who carried the load, not who is on the org chart.

### What counts as out of hours?

You decide. In settings you set your team's timezone, the normal working day start and end, and which days count as the weekend. Any page that lands outside those hours is counted as out of hours, and weekend pages are tracked separately so you can see scheduling imbalance that hourly totals would hide.

### Why compare pages per shift instead of just hours on call?

Two people can sit on identical calendar hours and have completely different weeks, because one of them got woken up nine times and the other got none. The board measures how many pages actually reached each person per shift and compares it against a widely cited sustainable ceiling of roughly two pages per twelve hour shift.

### Can I actually change the schedule from here, or is it read only?

You can act on it. From any row you can cover a person's shift, which writes a real override back into their incident.io schedule, and then posts an announcement to your Slack channel naming who is covering for whom and when. You get to review the message before it sends.

### How far back should I look when judging fairness?

Four weeks is generally treated as the minimum window, since anything shorter gets distorted by one unusually quiet or unusually painful week. Managers typically open the four week view for a routine check and switch to the quarter view when planning the next rotation.

Use this prompt in General Input: https://www.generalinput.com/prompts/on-call-burden-and-fairness-board-for-incidentio-rotations