Skip to content
Jun '266 min read

The two hard parts of a repeating deadline

Recurrence looks trivial and isn't. The difficulty hides at the edges, in the months that are too short and the occurrences you miss.

Conrad
ConradOn deadlines and the design of working instruments

“Repeats monthly” is the kind of feature that looks like an afternoon of work and turns into a week. The happy path is genuinely easy. A thing is due the fifteenth, it repeats every month, so generate the next one for the fifteenth of next month. Done. The trouble is that the happy path is not where deadlines live. Deadlines live at the edges, and recurrence has two edges that most tools fall off.

The first edge, the short months

Set a deadline for the thirty-first and repeat it monthly. What happens in February?

The lazy answer, and the one a surprising number of tools ship, is to step forward a month from each occurrence and clamp to the end when the month is too short. January 31, step a month, February has no 31st, clamp to February 28. So far so reasonable. But now the next step starts from February 28. March, step a month, lands on March 28. The deadline has silently moved. It was the last day of the month, and now it is the twenty-eighth, and it will stay the twenty-eighth for the rest of the year because each step measures from the last one. A “last day of the month” filing has quietly become a “twenty-eighth of the month” filing, and nobody told you.

The right answer is to never let the date drift. Deadlinewatch stores a fixed anchor day for the series and clamps from that anchor every single month, not from the previous occurrence. The thirty-first means the thirty-first. January 31, then the true last day of February, then back to March 31, then April 30, holding the anchor the whole way. An anchor of the thirtieth recovers to the thirtieth after February instead of getting stuck a day early. And if what you actually mean is “the last day, whatever it is,” there is a checkbox that says exactly that, so the deadline lands on the real end of every month, twenty-eight, twenty-nine, thirty, or thirty-one, every time.

This is a small thing that is not a small thing. The gap between “the 31st” and “the 28th” is three days, and three days is the gap between on time and late for the kind of work where the last day of the month is a hard line.

The second edge, the one you miss

The other place recurrence breaks is completion. Most tools tie the next occurrence to finishing the current one. You complete this month’s, and that is what spawns next month’s. It is a tidy model, and it has a hole you can drive a truck through. What happens the month you do not complete it?

If the next occurrence only appears when you finish the last, then a month you miss takes the whole future of the series down with it. You forget to close out March, and April never appears, and May never appears, and the repeating deadline you set up specifically so you would not have to remember it has quietly stopped reminding you. The one time the safety net mattered, it was not there.

Deadlinewatch separates the two triggers. Completing a deadline does spawn the next one immediately, so finishing early keeps an upcoming instance in view. But completion is not the only trigger. A scheduled job runs every day and materializes the next occurrence on its date whether or not you ever touched the last one. The series advances on the calendar, not on your behavior.

And the occurrence you missed does not disappear to keep the books tidy. It stays in your list as its own overdue row, in plain sight, because a missed deadline is a fact and the tool does not get to hide facts to make itself look neat. You end up with exactly what is true. The missed one sitting there overdue, and the next one already on the calendar, both visible at once.

Why this is worth a week

A repeating deadline is a promise the tool makes to your future self. The promise is that you set this up once, and from now on you do not have to remember it. Every place recurrence cuts a corner is a place that promise breaks. Drift breaks it quietly, by moving the date out from under you. Completion-coupling breaks it loudly, by going silent the month you needed it most.

Most tools treat recurrence as a checkbox. It is closer to a contract. The version worth building holds the date against the short months and keeps every occurrence whether or not you showed up for the last one, because those are the two ways the promise gets broken, and the whole point was to be the thing that does not break it.

Common questions

If I set a monthly deadline for the 31st, what happens in February? It lands on the last day of February, then returns to the 31st in March. The date is clamped from a fixed anchor day every month, not stepped from the previous occurrence, so it never drifts permanently to the 28th. There is also a “last day of the month” option if that is what you mean.

Do I have to complete one occurrence for the next to appear? No. Completing one spawns the next right away, but a daily job also materializes occurrences on their date regardless of whether you finished the last. The series advances on the calendar, so a month you miss never stops the future ones from appearing.

What happens to an occurrence I miss? It stays in your list as its own overdue row. Missed occurrences are not hidden or rolled forward. You see the missed one overdue and the next one upcoming at the same time, which is the honest picture.

What cadences are there? Weekly, monthly, quarterly, and yearly, with an optional date to repeat until. Monthly and yearly series hold a fixed anchor day so the date stays put across the short months.