How to build a fair residency call schedule
The rules every schedule has to respect, what “fair” means in numbers, and why the spreadsheet starts fighting you around week six.
Call schedules usually land on a chief resident, on top of a full clinical load. The first draft is not the hard part. The hard part is that every rule touches every other rule: one vacation request moves a weekend, which breaks someone’s rest, which pushes a PGY-1 onto a night with no senior backup. Then a swap request arrives and you start over.
Here is the process that holds up across a whole year, whether you build it by hand or with software.
1. Write the hard rules down first
A hard rule is one the schedule can never break without someone signing off. Put them on one page before you place a single name. Most programs have two layers.
ACGME limits
The ACGME Common Program Requirements set the floor for every program:
- 80 hours a week, averaged over four weeks, counting in-house work, clinical work from home and moonlighting.
- One day in seven free of clinical work and required education, averaged over four weeks. At-home call cannot be scheduled on those days.
- In-house call no more often than every third night, averaged over four weeks.
- At most 24 hours of continuous clinical work, plus up to four hours for handoffs and education.
- Rest between shifts: residents should have eight hours off between scheduled work, and at least 14 hours off after 24 hours of in-house call.
Your specialty’s Review Committee can tighten these, so check your program requirements too. The full text is on acgme.org.
Your program’s rules
These are the rules that make your schedule yours, and they cause most of the conflicts:
- Who can take which shift. Interns on primary call only with a senior on backup; backup limited to PGY-3 and up; a site that needs a PGY-2 or above.
- Rotation conflicts. Nobody on nights, vacation or certain off-service rotations takes weekend call, and nobody takes the Sunday before starting a nights week.
- Caps. At most three shifts in one weekend, at most two backups in one weekend, a yearly cap on 24-hour doubles.
A rule you can check by looking
“No AM shift the morning after a PM shift.” Same weekend, two drafts.
Draft A No rest after PM
Draft B Every rule checked
2. Collect time off before you start
Every request you take after the draft is a rebuild. Open one window for vacation, conferences, boards and life events, close it, then build. Decide up front what happens to requests that arrive late: they go on a waitlist, or they need a swap partner. Then everyone knows the answer before they ask.
3. Decide what fair means, in numbers
“Fair” causes more arguments than any rule, because everyone keeps a different count. Pick the counts you will track and publish them:
- Calls per resident against a target for their class. PGY-1s and PGY-4s rarely carry the same load, so equal for everyone is the wrong goal. Equal within a class, against a number you set, is the right one.
- Weekends and holidays, counted separately. A resident with an average total who works Thanksgiving and Christmas is not being treated fairly.
- Golden weekends (fully off), and how many 24-hour doubles each person takes.
Fair is a count against a target, per class
Example: one PGY-3 class, weekends worked this year, against a target of 12 (dashed line).
Every total is close to average. But NF worked six more weekends than LM, and that’s the gap residents talk about. It usually grows from small choices made one month at a time.
4. Build the year, not the month
Fairness is a yearly count, but most schedules are built a month at a time. Each month looks even on its own, and the year still drifts: the same people catch the long weekends, or one class quietly carries more backup. Build the whole year as one draft, publish it in blocks, and when you fix next month, look at the year-to-date counts first.
5. Check every rule after every change
The first draft is not where rules get broken. They get broken in March, on the fourth swap. Each change can break a rule two days away: a Friday PM swap can land someone on a Saturday AM with no rest. After any edit, recheck the whole schedule, not just the two cells that moved.
6. Plan for call-outs before they happen
Someone will get sick on a holiday weekend. Decide now who covers: a jeopardy or backup pool, an order of who gets asked, and whether coverage counts toward their totals. Then a call-out is a two-minute decision and not a group text at 5 a.m.
Why the spreadsheet starts fighting you
A spreadsheet is a fine place to record a schedule. It is a hard place to build one, for three reasons:
- Rules interact. Formulas can flag a broken rule after you break it. They can’t look three moves ahead to find the arrangement that breaks none.
- It can’t tell you when the rules are impossible. Sometimes a weekend can’t be staffed under your rules, because too many people are on nights or away. A spreadsheet just leaves you stuck. The useful answer is which rule to bend, and by how much.
- Fair over a year means trade-offs across hundreds of shifts. Hand-balancing 1,300 weekend seats across 37 residents, against class targets, is weeks of work. Doing it again after every swap is impossible.
What a schedule generator should do for you
Tempted to ask a chatbot instead? We tested that on a real program’s year.
This is the problem we built jacks to solve. Whatever tool you use, hold it to this list:
- It builds the whole draft from your rules, and the result checks every rule.
- It hits your fairness targets per class and shows the counts to everyone.
- When something can’t be staffed, it tells you exactly which rule is in the way and lets you decide.
- It lets you change anything by hand, then rechecks the whole schedule.
- It keeps published weeks fixed when it rebuilds the rest.