Your people
Availability is days and hours separated by semicolons: Mon-Fri 9-17; Sat 10am-2pm; Sun off. Days you do not list count as unavailable; leave it blank or write any for always free. Max hours default to 40.
Shifts to cover
Days can be a range (Mon-Fri) or a list (Mon/Wed/Fri). Times can be 9, 9:30 or 9am. An end at or before the start runs overnight into the next day. People needed makes that many separate shifts. To lock a shift to someone, add fixed: Ana as a last cell (use fixed: Ana + Ben to pin two copies); the tool plans everyone else around it.
off: days land in their own week. Uses the settings above and the Monday in "Week starting".
Sets each person's prev: (when their last shift ended) so rest rules hold across Monday.
Your people, shifts and settings are remembered on this device only (browser local storage), so next week you can open the page and click the button.
Enter your people and shifts, then click the button.
Collect your team's availability
Stop chasing availability in group chats. Make a link, send it to your team, and each person fills a week grid and sends you one line back. Paste the lines below and they replace each person's availability in your staff list; wages, roles and the hours cap you set stay (a person can only lower their own max hours). The link carries only the business name, week and, if you add it, one person's name; nothing is stored or uploaded.
Result
The roster
Hours and pay by person
| Person | Shifts | Hours | Overtime | Payroll | Against their limits |
|---|
Who this week depends on
Re-builds the week without each person. If shifts then go uncovered, that person is a single point of failure.
Changes since you posted it
Posted a schedule, then changed it? Choose the roster CSV you posted, say when you made the change, and see every shift that was added, cancelled or moved, how much notice each got, and the premium pay your own rule would owe. Fair-workweek laws differ by city and change: enter your window and premium from the rule that applies to you; nothing here is a statement of what a law requires.
Someone called in sick? Who can take the shift
Pick a shift. It lists everyone who could take it without touching anyone else's week, cheapest first, and why the rest cannot.
Two people want to swap? Check the trade
Pick the two shifts they hold. It says whether trading them keeps both weeks inside every rule, what it does to payroll, and which rule stops it if not.
Someone out for several days? Re-cover all their shifts
Pick the person and the days they are out. Every shift they hold on those days goes to someone else, cheapest first, without moving anyone else's existing shifts. Shifts nobody can take stay open, with the reason.
Against filling shifts in listed order
What you get by going through the shifts in time order and giving each to the first person in your list who is free and within the rules.
| Plan | Shifts left open | Overtime hours | Payroll |
|---|
How it is calculated
Hard rules (never broken): a person is only given a shift that falls inside one of their availability windows for the whole shift; shifts for one person never overlap and leave at least your rest gap between them; weekly hours stay at or under their maximum; days in a row stay at or under your limit. Objective: first cover as many shift-hours as possible, then minimise real payroll (wage × (1 + extras), overtime hours above your threshold at the multiplier), plus a small penalty for each hour a person is under their minimum and a quadratic penalty for hours drifting from a fair share (the balance slider). Search: a greedy build that fills the most constrained shifts first, then seeded simulated annealing with reassign and swap moves over several restarts; a fixed seed makes it repeatable. On small problems the tests compare it with an exhaustive search of every roster and it finds the same optimum; on large ones it is a strong heuristic, not a proof.
Not modelled: predictive-scheduling and fair-workweek rules as built-in law (the page flags a short-notice week and a changes report prices a premium you enter), breaks as a hard rule (unpaid meal breaks are deducted, and suggested meal and paid rest break times are shown from the numbers you enter), minor-labor limits beyond a per-person daily: cap, union rules, seniority, time off requests across weeks (a running tough: 3 cell, filled in by “carry over last week”, remembers who closed or worked weekends lately so the next week spreads them fairly when the spread setting is above 0; one week's time off works: add off: Wed; Fri 5pm-close to a person; a soft wish works too: prefer: Sat gives that person those hours when it costs nothing; avoid: Sat; Fri 5pm-close keeps those hours free unless the roster would otherwise leave a shift open or cost more). The rest rule does carry over from last week if you add prev: Sun 10pm to a person (when their last shift ended). Roles work: role: keyholder x1 on a shift needing 3 people asks for one keyholder among them. Unverified: checked against exhaustive search and invented data in unit tests, not against a real operator's payroll or a scheduling law.
Common questions
How do I make an employee schedule that covers every shift?
List each shift you need covered with how many people it takes, list each person with their availability, weekly hour limits and wage, and assign people to shifts one hard rule at a time: available for the whole shift, not double-booked, enough rest since their last shift, under their weekly limit. This tool does that search for you and shows any shift it could not fill with the reason.
How does the roster builder decide who works which shift?
It never breaks a hard rule (availability, weekly hour cap, rest between shifts, consecutive days, no double-booking). Among the rosters that follow those rules it covers as many shifts as possible first, then picks the lowest payroll, counting overtime above your threshold, nudged by the hour balance slider and by each person's minimum hours. The search is a seeded simulated-annealing optimiser, so the same inputs always give the same roster.
Is the roster guaranteed to be the cheapest possible?
No. Choosing who works which shift is a hard combinatorial problem, so the tool searches rather than proves optimality. On small problems the test suite checks the result against an exhaustive search of every possible roster and it matches. On a full week it finds a strong roster quickly, and the result is deterministic so you can compare changes fairly.
What does the hour balance slider do?
At zero the tool chases the lowest payroll, which can pile hours on the cheapest people and leave others under their minimum. Raising it adds a penalty for each person's hours drifting from their fair share of the total, in proportion to their weekly limit. Payroll shown is always the real cost, not the penalised score.
What does who-is-critical mean?
For each person on the roster the tool re-builds the week without them and reports how many hours of shifts would then go uncovered. A person whose absence leaves hours uncovered is a single point of failure: one sick call and a shift is open. Use it to see where you need a backup or wider availability.
What rules and laws does it check?
It enforces the availability, weekly hour limit, rest gap and consecutive-day limit that you type in, and prices weekly overtime above the threshold you set, plus optional daily overtime and double time (California-style presets included). It does not know your local predictive-scheduling or fair-workweek notice rules, break and meal-period rules, minor-labor limits, union terms or tip rules, which vary by place. Check the roster against the rules that apply to you.
Is my staff list uploaded anywhere?
No. Names, wages and availability are read and solved in this browser tab. Nothing is sent to a server, there are no accounts or cookies, and the tool does not store your roster. It works offline once the page has loaded.