A holiday accrual tracker on AWS for a few dollars a month
The owner of a small care agency asked a reasonable question: how many days holiday does Marta have left. Nobody could answer it. The rota lives in one app, the timesheets in another, and holiday is a shared spreadsheet somebody set up in 2023 with a column per person and no formula in it. Marta has worked there four years.

Key takeaways
- For irregular hours, entitlement accrues from hours worked, not from days on a calendar.
- The accrual happens every pay period, whether or not anybody records it.
- Untracked accrual does not disappear. It becomes a liability nobody has booked.
- The balance has to be answerable on any date, not just at year end.
- Designed on AWS for about $3 a month.
The whole system on one page
Before any code, here is the shape of what we are designing.
- Security & identity
- Management
- Analytics
Why the hours go missing
Holiday for a fixed five-day week is easy enough that nobody builds a system for it. Twenty-eight days, count them down, done. The trouble starts the moment a business has staff who work four hours on Tuesday, eleven on Saturday and nothing at all in February, because a day is no longer a unit of anything.
For those workers the entitlement is a rate rather than a number: a percentage of the hours actually worked in each pay period, accruing continuously. That is a perfectly workable rule, and it has one operational consequence that catches every business that meets it for the first time. The entitlement accrues whether or not anybody writes it down. It does not wait for a spreadsheet.
So the accrual runs quietly for four years while the shared sheet records only the leave that was taken, and the difference between the two sits on the books as nothing at all until somebody resigns and asks to be paid for it.
What runs (the inside)
- The leave year. Which twelve months a balance belongs to, and where that boundary comes from when nobody wrote it down. Part 2.
- Accrual. Hours worked in a pay period turned into hours of entitlement, one immutable line at a time. Part 3.
- Bookings and carry-over. Leave deducted as it is taken, and the three quite different reasons a balance is allowed to cross the year boundary. Part 4.
- The last day. What is owed when somebody leaves, and the evidence that makes the number stand up. Part 5.
One employer, one leave year
- Management
- Analytics
- People
In plain words
Every pay period, the hours each worker actually worked are read from wherever they already live — a rota export, a timesheet, a clock-in feed — and turned into hours of entitlement at the applicable rate. That produces one ledger line per worker per period, and those lines are never edited afterwards. If a period is later corrected, the correction is another line.
Leave requests come in from wherever the business already takes them, and a booking that is actually taken becomes a negative line in the same ledger. Booked-but-not-yet-taken is tracked separately, because a request in September for next March is not a deduction yet and treating it as one produces a balance that goes backwards when somebody cancels.
At the leave year boundary the system does the one piece of genuine reasoning in it: it decides how much of an unused balance is allowed to cross into the next year, under which of the three rules, and for how long the carried amount survives. That is part four, and it is where most manual processes simply zero the column and hope.
And on any date, for any worker, the system can produce a balance with the arithmetic attached: this many hours accrued from these periods, this many taken on these dates, this much carried in under this rule, leaving this. That sentence is the deliverable. The number on its own is worth very little when somebody disagrees with it.
Design rules that shaped every decision
- The ledger is append-only. A correction is a new line, never an edit.
- Accrual is calculated from hours worked, never from hours rostered.
- A booking is not a deduction until the leave has actually been taken.
- Carry-over records which rule allowed it, not just that some was allowed.
- Every balance can name the lines it came from.
- The system never rounds a balance in the employer’s favour.
What it does not do
It does not run payroll. It produces the hours and the rate that payroll needs, and it reconciles against what payroll actually paid, but the payment itself belongs somewhere that already handles tax codes and national insurance and is regulated for it.
It does not approve leave either. Whether Marta can have the first week of August off is a staffing decision made by somebody who knows who else is away, and the system’s only contribution is telling them the balance is sufficient. Approval workflows are a different product and every business already has one, even if it is a group chat.
It also does not give legal advice. It implements a set of rules that are written down and dated, records which version of them it applied, and shows its working. When the rules change — and this area changes every few years — the old calculations remain correct for the periods they were made in, which is the whole reason the ledger is append-only.
The next four posts walk through each piece: what a leave year actually is and where the boundary comes from, how hours become entitlement, how bookings and carry-over move the balance, and what is owed on the last day. One diagram per post, a cost breakdown, and an engineering reference at the end.
All posts