Nobody is absent from a day they don't work
Open the dashboard on a Saturday morning and count three absent out of eight. Nobody did anything wrong. The GM works Monday to Friday, the bookkeeper comes in twice a week, and the prep cook is weekdays only. All three are at home, exactly as arranged.
The number was technically defensible and completely useless. An owner who sees a red 3 every Saturday stops reading the number at all — and then misses the Tuesday when it means something.
So the absent count is not a headcount. It's a question about your schedule, and the shift is what answers it.
Absent is a subtraction
The count is built, not stored:
expected − present − on leave, floored at zero.
Two of those terms are facts. Present is who scanned. On leave is who has an approved request covering today. Neither is interesting.
Expected is the whole game. It is not the number of people on your payroll, and DailyBrew deliberately keeps the two apart: the "total employees" figure on your dashboard counts every active employee, because that's what your plan's seat limit is measured against. The absent calculation starts from a different, smaller number — the people who were actually due in today.
What a shift says about a day
A shift answers one question for any given weekday: is this employee expected to work? There are two ways it can answer, and the difference matters more than it looks.
A shift with no per-day rules means every day. Set a shift to 09:00 → 17:00 and it applies Monday through Sunday. That's the original behaviour and it hasn't changed — changing it under existing customers would silently redraw numbers people already rely on.
A shift with per-day rules is a complete schedule. On Espresso you can give a shift different times for different days. Once a shift has any per-day rule, the days you didn't write a rule for are off-days — not "fall back to the default times".
That second sentence is the one worth re-reading. Add a single Monday rule to a shift and you have just declared Tuesday through Sunday to be off. This is intentional: a per-day schedule that silently filled its own gaps couldn't express a Monday-only cleaner, and half-specified schedules are the ones that produce wrong numbers quietly. If someone works five days, write five rules.
Employees with no shift at all are always counted as expected. There's nothing to read a schedule from, so DailyBrew doesn't guess.
Three places the answer shows up
The same question gets asked in three different rooms, and it's the same answer in all three.
The dashboard. The absent baseline counts only employees whose shift is scheduled today. The Monday-to-Friday GM is not in Saturday's denominator, so Saturday reads what it should.
The log and the monthly grid. On an off-day with no check-in, no absent row is written at all. The monthly grid marks the day off and paints it neutral, rather than red. An empty Saturday and a no-show Tuesday look nothing alike, which is the point.
The late and left-early flags. Flags compare a punch against the times that apply on that day. If the day has no rule, there are no times to compare against, so no flag is raised. This matters most for overnight shifts, where the check-out lands on the following calendar day: the start and the end are always read from the same day's rule, never one from each.
Turning up anyway still counts
An off-day suppresses an expectation. It never suppresses a fact.
If someone scans in on a day they weren't scheduled — covering a sick colleague, coming in for a delivery — the row is recorded and shows as present, on the grid and in every export. DailyBrew declines to invent an absence; it never declines to record work.
Two other things narrow the baseline
Shifts are the main lever, but not the only one.
Employees who aren't tracked. Set an employee's attendance tracking to "none" and they leave the absent calculation entirely — no baseline, no flags, ever. This is for the admin helper or the flexible-hours family member who genuinely has no expected day. They can still check in, and their times are still recorded; they simply can't be absent. Note that they still count against your plan's seat limit, because they still occupy a seat.
Closures and approved leave. A closure period suppresses the expectation for everyone. An approved leave request subtracts that person for the days it covers. Both were already true before per-day schedules existed; per-day rules just handle the case that recurs every week rather than once.
Editing a shift rewrites the past
Change a shift today and past dates are re-read under the new schedule. Last month's Saturdays can stop being absences retroactively.
This is deliberate, and it's how closures have always worked here — there is no snapshot of "what the schedule was in March". The upside is that fixing a schedule you set up wrong repairs your history instead of leaving a scar in it. The tradeoff is real and worth knowing: if you restructure a shift, numbers you have already looked at can move. The shift editor says so on the per-day panel rather than letting you find out later.
On the Free plan
Per-day schedules are an Espresso feature. On Free, a shift means "these times, every day", and the absent baseline is simply every tracked employee.
Nothing is broken there — the count is just less specific. If your crew works a genuinely uniform week, it's also completely correct, which is why it stays the default.
The short version: the absent count is only ever as good as the schedule you told DailyBrew about. If a number looks wrong on a Saturday, the fix is almost never in the attendance log. It's in the shift.