A session series is not eighteen sessions: the recurrence record explained
In short
A recurring session is stored as a rule plus a list of exceptions, not as 18 rows — until somebody edits one week, at which point the system either records an exception against the rule or turns that occurrence into its own object. Every confusing this-event-or-all-events prompt, and every booking that survives a cancelled week, comes from that single storage decision.
Key takeaways
- A series is a rule plus an exception list. The occurrences you see may not exist as rows at all.
- Store a local start time and a named timezone, never a fixed offset, or the clock change moves your sessions.
- Editing one week writes an override; editing all following splits the series into 2 and renumbers the future.
- Bookings, attendance, payments and credits must attach to the occurrence, never to the series.
- An open-ended series with no horizon quietly inflates the denominator in every utilisation report.
A recurring session is a rule with exceptions attached, not a set of sessions. "Under-14s, Tuesdays and Thursdays, 18:00, pitch 2, from 9 September to the end of term" is 1 record. The 18 sessions a coach sees may be rows in a table or computed on the fly, and which it is decides what happens when somebody moves one week.
Read it as a compound object rather than a setting — the habit behind what the delay on a live match stream is made of. Get the parts right and the awkward behaviour stops being mysterious.
The fields a recurrence record has to hold
| Field | What it holds | What breaks when it is missing or wrong |
|---|---|---|
| Anchor | Local date and start time of the first occurrence, with duration | Every occurrence inherits the error, and fixing it moves history |
| Timezone | A named zone, not an offset | Sessions shift by an hour at a clock change, or fail to shift |
| Rule | Frequency, interval, and which weekdays | A Tuesday-and-Thursday class becomes 2 series nobody can edit together |
| End condition | An occurrence count or a final date — 1 of the 2, never both | A series that runs forever, filling calendars and reports |
| Horizon | How far ahead occurrences are generated or shown | Members cannot book far enough ahead, or book past the term |
| Exception list | Dates the rule generates that do not happen | Cancelled weeks reappear when the series is rebuilt |
| Overrides | Per-occurrence changes to time, venue, coach or capacity | A moved week silently reverts when the series is edited |
Materialised rows or computed on read
There are only 2 strategies, and every scheduling product picks one. The trade is not subtle.
| Operation | Occurrences written as rows | Occurrences computed from the rule |
|---|---|---|
| Move one week | Cheap: update 1 row | Expensive: materialise the occurrence, then exclude the generated one |
| Change the rule | Expensive: rewrite future rows, decide what happens to edited ones | Cheap: change 1 record |
| Attach a booking | Natural: the booking points at a row | Needs a stable occurrence id derived from series and start date |
| Ask who is on pitch 2 at 18:00 | One indexed lookup | Expansion at query time, degrading across venues and seasons |
| Audit what happened | Each occurrence carries its own history | The past is recomputed, so a rule change rewrites it |
| Use it when | Bookings, attendance or money attach to sessions | The calendar is display-only, such as a public fixture list |
What "this one" and "all following" actually do
- Edit this occurrence. Writes an override against 1 date. The rule is untouched, so a later series edit must decide whether to respect the override — products differ, which is why a moved session sometimes reappears in its old slot.
- Cancel this occurrence. Adds the date to the exception list. That is half the job: the bookings, credits and attendance attached to it need their own decision, and no scheduling library makes it for you.
- Edit all following. Splits the series in 2 — the original ends the day before, a new one starts at the edit date. Everything referencing later occurrences by series id has to survive the split.
- Edit the whole series. Rewrites the past as well as the future unless past occurrences are protected. Freeze anything already marked, paid for or attended, and apply changes forward of today.
Bookings, attendance and money attach to the occurrence
This rule survives every product decision above: nothing concerning a specific date may reference the series.
- A booking names a date, not an intention. "Booked onto Thursdays" cannot express "coming on the 14th", and cannot be cancelled for 1 week without ambiguity.
- An attendance mark is meaningless without the occurrence it was taken at — the vocabulary that makes a register countable is in present, absent, excused.
- A credit is consumed against 1 occurrence, and a cancelled occurrence must return it: a credit is an entitlement with a scope and an expiry.
- A waitlist promotes into an occurrence, never a series, which is where promotion quietly fails: full class, empty floor.
- Utilisation counts occurrences, so an open-ended series inflates the denominator all year — the arithmetic in the denominator that hides.
A series is a plan and an occurrence is a fact. Anything that can be booked, marked, paid for or refunded belongs to the fact.
When specifying a club system, write the recurrence record out in full before anyone draws a screen: 7 fields, 2 storage strategies, 4 edit operations. Making them explicit keeps scheduling, attendance and the facility coherent as terms, venues and coaches change. Building that layer is routine AI agents and automation work in our sports and fitness practice, with the caveats in agents in production.
Frequently asked questions
Short answers to the follow-ups this page tends to raise.
What happens when you edit one session in a recurring class?
The system either records an override for that date and leaves the rule alone, or it turns that occurrence into an independent object and excludes the generated one. Both are correct implementations with different consequences: the first can be overwritten by a later series edit, the second drifts from the rule. Ask which your platform does before relying on a moved week staying moved.
Should recurring sessions be stored as rows or generated from a rule?
Generate from a rule, and materialise an occurrence the moment anything attaches to it — a booking, an attendance mark, a payment or an override. That hybrid keeps rule changes cheap while giving every real event a stable object to point at. Pure generation is only adequate when the calendar is display-only.
How far ahead should a series generate occurrences?
Far enough to cover the booking window plus a margin, and no further: usually the end of term or a rolling few months. An unbounded series fills reports, inflates utilisation denominators and makes rule changes expensive. How far ahead members may book is a separate policy, and the shorter of the 2 numbers.
What happens to bookings when a coach moves one week's session?
Nothing automatic, and that is the point: moving an occurrence changes a time, while a booking is a member's commitment to attend. Decide explicitly whether bookings follow the move, whether members are notified, and what happens to anyone who cannot make the new slot.
- recurrence
- scheduling
- data model
- bookings
The work behind this page
Builds from our portfolio that this page draws on.
DockQueue
A dock scheduling and yard management platform that lets carriers self-book dock appointments, assigns the right door on arrival, and tracks every trailer's dwell and detention live.
LogisticsFieldRoute
An AI field-service platform that auto-dispatches the best-matched technician, optimizes routes, and tracks first-time-fix against every SLA.
OperationsRead next
- The member export: what leaves your club platform and what staysAn export is not a backup. It is whichever subset of your data the incumbent chose to serialise, and two of the usual omissions can end a migration on their own.definition
- Three systems, three member lists, all wrong in different placesDisagreeing member counts are a diagnosable defect, not a reason to buy something new. The mismatch classes tell you whether you have a sync problem, a definition problem or an identity problem.diagnostic
Working on something in this space?
Tell us where you are in a sentence or two. We'll tell you honestly whether we're the right team, and what a sensible first slice of the work looks like.
Start the conversation