Every Payroll System Has One Clock
Ask any payroll system a question and it answers from a single point of view: now. What is this employee’s salary? What is the tax rate? What was the gross last month? The system reads the data as it currently stands and computes the result. This is the implicit assumption built into nearly every payroll engine ever written: the calculation happens in a live context, against the latest known state of the world.
That single clock is the effective date (also called the value date or validity date): the moment from which a value is true. A salary of 5,000 effective March 1. A tax class change effective June 20. Effective dating is well understood, and good systems track it carefully — it is what allows them to split a period when something changes mid-month.
But there is a second question that the one-clock model cannot answer: not “what is true,” but “what did we know, and when did we know it.” On March 15 we learn that an employee’s rate changed effective February 15. We already ran February’s payroll on February 25 with the old rate. So what was the “correct” rate for February 25 — the one we used, or the one we later learned? Both answers are valid. They just live on different clocks.
This is the bitemporal question. It is not new in computer science — valid time and transaction time have been in the SQL standard since SQL:2011, and the canonical textbook example used to teach the concept is, fittingly, a payroll salary change. What is rare is a payroll calculation engine that treats the second clock as a runtime input, not just a reporting filter.
Mid-Month Splitting Is Not the Innovation
It is tempting to pitch “we handle mid-month changes” as a differentiator. It is not. The ability to decompose a pay period into sub-periods when something changes partway through is mature, documented, and present across the incumbents. An honest comparison says so plainly:
| System | Mid-period mechanism | How it is configured |
|---|---|---|
| SAP HCM | WPBP split (Work Place / Basic Pay) + retroactive accounting via difference wage types (/551, /552, /553) | Personnel Calculation Rules (PCRs), schema copies, processing classes |
| Workday | Sub-periods + gross-to-net proration | Proration rule per Earning/Deduction (calendar days vs. work-shift days) |
| Oracle PeopleSoft GP | Period segmentation & element segmentation (“slices”) | Proration rule per element; segments produce separate gross-to-net result sets |
| Dayforce (Ceridian) | Mid-period proration of Auto Pay | Auto Pay Rule drop-down (260/312 days) + “Sync Pay Changes” wizard |
| Payroll Engine | Automatic sub-period decomposition; segment-preserving operator arithmetic | None — the formula is written once, the engine resolves the splits |
The honest distinctions here are two. First, in the incumbent systems segmentation is largely opt-in per pay component and configured explicitly (a proration rule on each earning, a PCR, a wizard run). In Payroll Engine, every case value is natively time-stamped, so segmentation is universal and automatic rather than something you switch on. Second — and this is the genuinely elegant part — the arithmetic operators on a Payroll Engine case value preserve the sub-period structure. A regulation author writes Salary × Rate exactly once; the engine aligns the segments, multiplies per slice, and sums. (We covered this mechanism in depth in Mid-Month Changes: When One Period Isn’t One Period.)
That is better engineering. It is not a new category. A knowledgeable evaluator will — correctly — point out that period slicing has existed for decades. So if mid-month handling is the headline, the story is weak. It is the wrong headline.
The Real Innovation: The Second Clock as a Calculation Input
Payroll Engine separates two independent time axes for every value it reads, and exposes both as parameters to the payrun:
| Axis | Parameter | Question it answers |
|---|---|---|
| Value Date | periodStart |
Which value is active at this point in time? |
| Evaluation Date | evaluationDate |
Which entries are visible — what was the knowledge cutoff? |
The value date is the clock everyone has. The evaluation date is the second clock. It is backed by the immutable Created timestamp on every case value: the engine can reconstruct exactly which entries existed at any past moment, and run the full calculation as if it were standing at that moment, blind to everything entered afterwards.
This is the part incumbents do not expose at the calculation layer. It is the difference between “show me the data as of a date” (a report filter) and “run the engine with the knowledge state of a date” (a calculation input). The Payroll Engine documentation states the gap directly:
“Most payroll systems implicitly assume that data is always processed in a live context — they have no concept of an Evaluation Date. This limits them to calculating what is valid right now, making forecasts and historical reconstructions complex workarounds rather than first-class operations.”
Two Clocks, One Matrix
When both axes are free, a payrun is no longer a single answer — it is a coordinate in a plane. To see what that means in practice, consider a single employee whose salary history unfolds across both clocks during one calendar year:
Three entries, each with its own effective period and its own creation date:
- Jan 12 — salary of 5,000 entered, effective from Feb 1 onward.
- May 17 — raise to 5,500 entered, effective from Apr 1 onward. Any calculation evaluated before May 17 is blind to this raise.
- Jul 13 — a forecast entry (Budget 2026) sets the salary to 6,000 for Oct 1–Nov 30 only. It expires on its own — December reverts automatically.
Today is September 1. The same underlying data answers four different questions depending on where you stand on each clock:
| Scenario | Evaluation Date | Value Date | Result | Question answered |
|---|---|---|---|---|
| A | Today (Sep 1) | Today (Sep 1) | 5,500 | What is the current salary? |
| B | Jun 1 | Jun 1 | 5,000 | What did we know on June 1? |
| C | Jun 1 | Today (Sep 1) | 5,000 | What would we have predicted for today, back in June? |
| D | Today (Sep 1) | Jun 1 | 5,500 | What do we know today about June 1? |
Scenario C is the one that breaks the single-clock model. “What would we have predicted for today, based only on what we knew on June 1?” is not a data query — it is a complete payroll calculation constrained to a past knowledge horizon. A reporting “as-of” date cannot produce it, because the numbers must be recomputed under the old information set, not merely retrieved.
Push the evaluation date into the future and the same mechanism produces forecasts — and because the two clocks are independent, the engine computes directly in the target period without replaying every month in between:
| Scenario | Evaluation Date | Forecast | Result | Question answered |
|---|---|---|---|---|
| E | Oct 15 | — | 5,500 | October salary without any forecast plan |
| F | Oct 15 | Budget2026 | 6,000 | October salary including the budget plan |
| G | Dec 15 | Budget2026 | 5,500 | December salary after the budget entry expires |
Retro, reconstruction, and forecast are not three subsystems. They are seven coordinates on the same two-axis plane, served by one calculation path.
Why “Effective Dating” Isn’t the Same Thing
Several incumbents will say they already do this. The claim deserves a precise rebuttal, because the surface vocabulary overlaps.
Workday is effective-dated, and its reports let you set an “as-of” date to see a worker’s attributes as they were on a chosen day — what its own community calls time-travel in reports. Its API exposes both an effective moment and an entry moment. This is real bitemporal data access. But it is fundamentally a retrieval capability for viewing records; it does not re-run the payroll engine constrained to a past knowledge state with forecast isolation.
SAP has powerful retroactive accounting: a change with a past effective date sets the earliest retro date (Infotype 0003) and the engine recomputes forward from there, booking the deltas into /551 and /552. This is excellent for the one job it does — pay the difference now. But there is no free evaluation-date axis. You cannot ask SAP to reconstruct “the prediction we would have made in February” as a first-class run; the system is oriented around producing the current correct payment, not around querying arbitrary historical knowledge states.
Oracle and Dayforce segment and prorate competently, but the same limitation applies: the second clock is implicit, embedded in stored results and recalculation triggers, not surfaced as a parameter you can set.
The architectural point: the second clock is not a feature you add — it is a property of the data model. It requires that no value is ever overwritten, that every entry carries an immutable creation timestamp, and that the calculation engine reads through both axes on every lookup. A system designed around a single live clock cannot bolt this on later without rebuilding its storage and execution core. That is what makes it defensible, and that is why it is rare.
Values That Expire on Their Own
The second clock has a quieter companion that is just as unusual in payroll: every value can carry its own end date. Most systems model a value as a field that holds until something overwrites it — validity is open-ended by default, and “turning it off” means entering a second change. Payroll Engine models a value as an interval: a start, and optionally an end. A value can therefore be true only for a bounded window and then simply stop being true, with nothing overwriting it.
This sounds like a small thing. It removes an entire class of manual bookkeeping:
- A hardship allowance granted for exactly three months expires by itself — no diary reminder, no follow-up entry to switch it off, no risk of it silently running for a fourth month.
- A temporary market-rate supplement, a fixed-term shift premium, a relocation bonus paid across a defined window — each carries its own end date and disappears on schedule.
- A statutory parameter that applies only until a mid-year law change ends precisely where its successor begins, with no overlap and no gap.
And it composes cleanly with everything above. A value that ends mid-period is just another boundary on the value-date axis: the engine slices the period at the end date exactly as it would at a change date. An expiring value that falls inside a forecast window is computed correctly in the target period and then vanishes from later ones — which is exactly scenario G in the matrix above, where the budget entry expires and December reverts to 5,500. No null handling, no cleanup runs, no orphaned overrides lingering into next year. Validity is a property of the data, not a task on someone’s checklist.
What Falls Out of the Model
The strategic elegance is that once payroll is a function of two clocks, the “hard” payroll problems stop being individually engineered features. They are corollaries of the same model:
- Mid-month change — a single value-date split inside one period. The trivial case.
- Overlapping mutations — several value-date splits across different fields, aligned to a daily grid and resolved by segment-preserving operators. Two changes on different days simply produce more slices; the formula is unchanged.
- Time-limited validity — a value with an end date that expires mid-period. Just another value-date boundary; the slice after the end date carries no value, automatically.
- Retroactive correction — an evaluation-date shift into the past plus a new entry; affected periods recompute automatically and the deltas flow into the current run.
- Point-in-time reconstruction — an evaluation-date shift alone, for audit or dispute (“what did the payslip look like with the information we had then?”).
- Forecast — an evaluation-date shift into the future, optionally with an isolated, named scenario; computed directly in the target period.
One model, five behaviors, no special-case code paths. That is the difference between a clever feature and an architecture.
The Formula Never Changes
The final consequence is the one that reaches the people who configure payroll. Because the engine resolves both time axes in the background, the regulation author — typically a payroll consultant, not a programmer — never writes time logic. In the No-Code layer, a wage type that combines a salary with a risk bonus is expressed in token form, once:
^^Salary + ^^Salary * ^^RiskBonus
The ^^ token references a case value; the rest is ordinary arithmetic. There is no proration term, no day-count, no if branch for “changed mid-month.” The consultant writes the business rule and nothing else. When a calculation genuinely outgrows the token layer, it drops to a single line of Low-Code that still reads like the formula above — the engine’s segment-preserving arithmetic does the time work either way.
That one expression is correct whether nothing changed, whether the salary changed on the 10th, whether the bonus changed on the 20th, whether both changed, whether a value expired halfway through the month, and whether the run is a live payslip, a backdated correction, or a forecast. Compare that to the SAP world, where retroactive behavior is the province of specialist consultants writing PCRs — the complexity that the two-clock model absorbs is, in legacy systems, precisely the complexity that leaks into the configuration layer and drives implementation cost. This is the practical payoff of no-code regulation development: keep the business logic simple, and let the engine own the time dimension.
Inspectable by Design
There is one more thing no incumbent offers alongside this model: the engine is open source. The two-clock calculation core is MIT-licensed and auditable. For a capability whose entire value proposition is correctness across time — retroactive deltas, historical reconstructions, forecasts that must match the eventual legal run — being able to read the actual implementation rather than trust a black box is not a minor footnote. A bitemporal, regulation-driven, open-source payroll calculation engine is, as far as public information shows, a combination that does not otherwise exist.
A Coordinate System an AI Can Query
The two-clock model has a property that only becomes obvious once you try to put an AI assistant in front of payroll: every meaningful question is already a coordinate, not a bespoke report. “What would September have looked like with the knowledge we had in June?” “Forecast Q4 under the budget scenario.” “Reconstruct the payslip as of the audit date.” Each of these is the same calculation with two parameters set differently — periodStart and evaluationDate, plus an optional named forecast. There is nothing to special-case, which means there is nothing an agent has to learn beyond where it wants to stand on each clock.
That is what makes the model a natural fit for the Model Context Protocol. Payroll Engine exposes the engine through an MCP server, so an assistant can drive real runs in plain language — and because the request maps directly onto the two axes, the agent is not estimating. The figures it returns come from the same calculation path that produces the legal payslip; the MCP layer adds no parallel analytics model and no statistical guess over past results. It simply lets a caller name a point on the value-date / evaluation-date plane and reads the engine’s answer back.
What that opens up is analysis that used to require a specialist and a spreadsheet, now expressed as a conversation:
- Scenario comparison — ask for several coordinates at once (“current vs. what we knew in June vs. the budget forecast”) and get them side by side, each a full gross-to-net result rather than an interpolation.
- Delta explanation — “why is this month’s net different from last month’s?” becomes a retroactive reconstruction the agent runs and narrates, instead of a manual hunt through change logs.
- Audit and dispute — reproduce exactly what was known on a past date, on demand, inside the same chat that asked the question.
- Forward planning — what-if forecasts in an isolated, named scenario, computed directly in the target period and never leaking into live results.
The division of labor is the point: the agent decides where to stand on the two clocks; the engine still owns the math. Because the read-only server is part of the open-source core, the surface an assistant can reach is inspectable and permission-controlled rather than a black box — and every answer it gives remains reproducible by a human running the same two coordinates. This is AI as a query interface to a deterministic engine, not payroll-by-chatbot.
When the Second Clock Matters
The two-clock model is not equally valuable to everyone. It earns its keep where time itself is the hard part of the problem:
- Audit and dispute resolution — reproducing exactly what a payslip showed, and what was known, at a past date.
- Continuous and on-demand payroll — running pay at any point, not only at month-end, with retroactivity handled automatically.
- Earned wage access — an exact net-pay figure mid-period, computed by the same engine that will later produce the legal payslip, with no estimation gap.
- Budgeting and what-if planning — forecasts that compute directly in the target period and stay isolated from live results (see Complex Forecasts).
- High-change workforces — frequent mid-period salary, role, and jurisdiction changes, where overlapping mutations are the norm rather than the exception.
For a business that runs simple monthly payroll with rare changes, a single-clock system is perfectly adequate. The second clock is for everyone whose reality is messier than that — which, in practice, is most of them.
See the two-clock model in action
Mid-month changes, retroactive corrections, and forecasts from one calculation path — on an open-source engine you can read line by line.
Get in Touch →