Where do you place the cutover between old and new logic so no published period is produced half by each version?
answer
- a boundary in the output, not the calendar
- whole periods, never half
- open groups are the hard case
- mark which period changed definition
basics
~20 sCut over at a boundary in the output's own grouping — the start of a whole published period — not at the moment someone deploys. Record the first period the new version owns, stored with the numbers, and keep the old version runnable.
solid answer
~50 sThe cutover point is a property of the **output**, not of the deployment. Pick the boundary of a whole published period, so every period is produced end to end by exactly one version and no figure has two definitions inside it. For a periodic job over a finite input this is easy: swap between runs. For a continuous job it is harder, because the switch happens by ending one and starting the other, and the groups open at that instant were seen in full by neither — so either choose a quiet boundary, start the new version early enough that it has seen those groups whole, or accept the seam and recompute that one period afterwards. Then record the seam durably, with the numbers, and keep the old version runnable until the new one has survived a full cycle including the rare paths.
go deeper
Recall that the switch should happen between whole published periods, so that no single figure is computed partly by the old logic and partly by the new one.
Explain why a continuous job is the hard case: there is no natural gap, so the groups open at the moment of the switch were seen in full by neither version.
Show that you choose the boundary from the output's grouping, record it with the numbers, and plan a full cycle of the rare paths before retiring the old version. Name the point past which reverting stops being free.
Set the organisational rule: who may declare a cutover, what evidence is required first, and how long the previous version stays runnable. Without a standing rule each change re-argues it and the cautious answer wins by default.
## The cutover is a property of the output The question *when do we switch* is routinely answered with a deployment time, and that is the wrong unit. The people who read your numbers do not experience deployments; they experience periods — a day, an hour, a month. If the switch lands in the middle of one, that period was computed partly under one definition and partly under another, and it belongs to neither. Nobody can say what it means, nobody can reproduce it, and it sits in the series forever as an unexplained point. So the cutover point is a boundary in the output's own grouping, chosen so that every published period is produced end to end by exactly one version of the logic. The deployment happens whenever it happens; the *cutover* is the first period the new version owns. ## A periodic job over a finite input This case is clean, and it is the one to reach for when you have the choice. Each execution covers one whole period from beginning to end, so the seam falls naturally between two executions. You deploy, and you state that the new version owns everything from a named period onward. The only subtlety is what happens if one of those periods is later run again. A re-run must be deliberate about which version it uses: re-running an old period with the new logic changes a figure that was already published, which is no longer a cutover decision at all but a restatement decision, and it is argued separately. ## A continuous job: the seam falls inside open groups A continuous job has no natural gap. Switching versions means ending one and starting the other, and whatever groups were open at that instant were seen in full by neither version. How a job is stopped cleanly and resumed at all is a separate subject; what belongs here is where the seam lands in the published series and what you do about it. Three workable answers: 1. **Choose a quiet boundary.** Switch at the boundary of the output's grouping during the period of lowest arrival, so the number of half-seen groups is as small as possible. 2. **Overlap deliberately.** Start the new version early enough that it has observed the affected groups from their beginning, discard its earlier output, and publish from it only from a clean boundary. 3. **Accept the seam and repair it.** Switch, then recompute that single period afterwards with the new logic so the series is consistent, which is affordable precisely because it is one period. The shape of this problem varies by runtime model, and a claim that fits one misleads on the next: | runtime model | where the seam falls | the risk to manage | |---|---|---| | continuous work run as a rapid succession of small finite runs | between two small runs | a published group spanning several small runs is still split across versions | | record-at-a-time with a key-bound retained set | inside whatever groups are open | the new version begins with an empty retained set, so its first outputs are incomplete for that reason alone | | a periodic job over finite input | between two executions | none inherent; the risk is a re-run later using the other version | ## Record the seam with the numbers Whichever boundary you choose, the series needs a durable marker of which version produced each period, stored where the numbers are stored. Not in a message, not in a deployment log, not in somebody's memory. Six months later a colleague comparing this quarter to last will find a step change and will spend a day looking for a data incident that never happened. A version marker alongside the figures turns that day into a glance. ## Keep it reversible, and know the limit Keep the old version runnable until the new one has survived at least one full cycle of the rare paths: - the period close, which may run different logic from an ordinary period - the month where the calendar is unusual - the upstream source that delivers only occasionally - the volume peak, which is where a change that is merely slower becomes a change that is late Reversibility has a hard limit, though, and it is worth saying out loud: once the new version has published figures that people have read and quoted, reverting does not restore the old world. It creates a second seam in the opposite direction, and now the series has two. Past that point the honest options are to fix forward, or to make a deliberate restatement decision. ## What the cutover point is not It is not the moment the code merges. It is not the moment the deployment completes. It is not when a scheduler next happens to fire — when a run is triggered, over what interval, with what retry rule, is a scheduling subject and has nothing to do with which definition a published figure is on.
- Why is deploy on Friday evening when traffic is low a poor cutover rule?Low traffic is not a period boundary. If the day is the published grain, a Friday-evening switch splits Friday's figure across two definitions, which is the exact defect to avoid. It also puts the first comparison at the moment fewest people are available to read it.
- The new version has been publishing for three weeks and a defect appears. Is reverting still the answer?Rarely. Reverting restores a definition you had already decided against and creates a second seam three weeks after the first. Usually you fix forward, and then decide separately whether those three weeks must be recomputed — which is a restatement question, not a cutover one.
- Can you cut over per key rather than all at once?Sometimes, and it limits blast radius: route a subset of keys through the new logic and the rest through the old. The cost is that the published series is then internally inconsistent — an aggregate over all keys mixes both definitions — so it suits per-key outputs and suits totals badly.
saying these in an interview costs you the question
- Cuts over at the moment the deployment finishes
- Leaves a published period produced partly by each version
- Records the switch in a chat message rather than with the numbers
- Assumes reverting is free after the new version has published
- Confuses the cutover point with when the next run is scheduled