Calendar Service System Design Interview: Recurrence and Time Zones
A spoken-style walkthrough of the calendar service system design interview: requirements, recurrence, time zones, conflicts and the trade-offs to say out loud.
A calendar prompt looks like a CRUD exercise. It isn't. The hard parts are time, recurrence and shared state, and the interviewer knows it. This walkthrough gives you a narrative you can speak in a real calendar service system design interview: pin down requirements, choose a data model, handle recurring events and time zones, then close with the trade-offs you made.
Treat it as a script you rehearse, not a diagram you memorise. The structure matters more than any single box, because it shows the interviewer how you think when the problem gets awkward.
Why a Calendar Is a Harder Prompt Than It Looks
Start by naming the traps out loud. There are three, and saying them early buys you credit for the rest of the answer.
- Recurring events. A weekly stand-up is not one row; it is a rule plus exceptions, and every read has to decide what to materialise.
- Time zones and daylight saving. A stored instant is not enough if a 9am meeting must stay at 9am local time.
- Concurrent edits. Two attendees editing the same event can silently overwrite each other unless you design against it.
Then set the frame in one sentence: "I'm designing a service that stores events, expands recurrence, answers availability queries and sends reminders." That tells the interviewer what is in scope before you draw anything.
Finally, give them a map. Say that you will start with requirements and return to trade-offs at each step. That sentence is small but it changes the interview: instead of watching you build, they are following a plan.
Clarify Requirements Before You Draw Anything
Ask questions in a fixed order so you never freeze. Use the same order every time and it becomes automatic. In a calendar service system design interview, the requirements phase is also where you earn the right to skip things later.
Scale and shape of the workload
- How many users, and how many events per user?
- How many attendees on a typical event — one, or a team of twenty?
- How far into the future do people schedule, and how far back do they look?
Read/write mix
Calendars are read-heavy. Opening a week view, checking free/busy and loading a shared team calendar all happen far more often than creating an event. Ask which read path matters most, because it decides your caching and indexing.
To make that concrete, estimate the ratio rather than asserting it: ask how many events a user creates in a week versus how many times they open a view, and multiply by the user count. Even a rough figure changes decisions — a ratio of tens to one justifies read replicas and a longer cache TTL on month views, while a ratio near one would push you back toward a single primary and shorter caches.
Consistency expectations
Ask directly: "Is it acceptable for two people to briefly see different versions of the same event?" Most interviewers will say yes for a shared view, but no for a single event being edited. That answer shapes your concurrency design later.
Scope boundaries
Pin down whether you are designing a single-user calendar, shared team calendars, invitations, or sync with external calendar providers. Each one is a project. Choosing two to design in depth and sketching the rest is a legitimate, senior answer.
Latency targets
Ask for the two paths that matter: fetching a month view, and checking free/busy. Write the numbers down.
Then do the thing that impresses interviewers: write your agreed requirements as a short list and refer back to it. "Given we said month view is the dominant read, I'll index on calendar and time range." That single habit makes your answer feel engineered rather than improvised.
Functional Requirements: The Core Operations
List the operations, then say which you will go deep on.
- Create, read, update and delete events, including events with multiple attendees.
- List events for a time range — month and week views are the dominant reads.
- Expand recurring events into concrete occurrences for a requested window.
- Query free/busy across several calendars to find a meeting slot.
- Send reminders and invitations.
That last one is a delivery problem, not a storage problem. Saying so out loud shows you can separate concerns. Then commit: "I'll design storage, recurrence and free/busy in depth, and sketch reminders." Without that commitment, you will run out of time in the middle of recurrence, which is exactly where the interviewer wanted to push.
Non-Functional Requirements Worth Naming
Do not read these out as a wish list. Pair each one with what you are trading against it.
- Availability. Calendars are checked constantly; people notice immediately when theirs will not load. This pushes you toward replicas and caching, at the cost of some read staleness.
- Read latency. A month view should be fast and predictable. Reminder delivery can tolerate more delay, so it does not belong on the same path.
- Durability. Losing a meeting is worse than showing it a second late. Writes go to durable storage before you acknowledge them.
- Correctness under concurrency. Two attendees editing the same event must not silently overwrite each other.
A useful sentence: "I'm prioritising availability and read latency for the month view, and accepting eventual consistency for shared team views, because a few seconds of staleness there is invisible to users." That is a trade-off, not a feature list, and it is what the interviewer is listening for.
Data Model and Storage Choices in the Calendar Service System Design Interview
Name the entities, then justify the store.
- User — identity and preferences, including default time zone.
- Calendar — an owned collection of events, with sharing rules.
- Event — title, description, start, end, time zone, organiser, status.
- Attendee — the join between event and user, carrying the response status.
- Recurrence rule — the pattern that generates occurrences.
- Reminder — when and how to notify, stored separately from the event itself.
A relational store fits the ownership and invitation relationships well: foreign keys, transactions and range queries are all natural here. At larger scale, a wide-column or document store can help with the event table, which is large and mostly read by calendar and time range. Say which part you are moving and why, rather than moving everything.
Index by calendar and time range, because range queries dominate. And store the event's intended local time plus its zone, not only a UTC instant — more on that below.
Recurring Events: The Part Interviewers Push On
The core decision is whether you store the rule or every occurrence.
Store the rule, expand on read. One row for "every Monday at 10:00 until June". Edits to the series are cheap. The cost lands on reads: a year-long daily event queried over a year means expanding hundreds of occurrences per request.
Precompute occurrences on write. Fast reads, but every rule change rewrites a large set of rows, and long series bloat storage.
A hybrid is usually the best answer, and saying it plainly is the point: expand on read for short windows, and cache expanded windows for hot calendars such as a team's shared view.
Exceptions are where the design earns its keep
An occurrence can be moved, cancelled, or edited independently of the series. Model this as an exception keyed by the series and the original start instant of the occurrence. When you expand, apply exceptions after generating the base occurrences.
Now say what breaks. If the series rule changes — say from weekly to every two weeks — the generated dates shift, so an exception keyed to an original start instant may no longer line up with any occurrence it was meant to modify.
The common approach is to key exceptions to the original start instant and, when the rule changes, run a defined policy: either re-map each exception to the occurrence it still modifies, or drop the orphans and tell the user. Pick one and name its cost — a write pass over the series' exceptions, plus the risk of losing an edit the user made deliberately. Naming that cost is what makes the trade-off visible to the interviewer.
Time Zones, Daylight Saving and Calendar Correctness
This is a correctness problem, not a scaling problem, and interviewers often care about it more than your sharding plan.
Store the event's intended local time plus its zone identifier, not just a UTC instant. Otherwise a recurring 9am meeting drifts to 8am or 10am when a region shifts its clocks.
Walk through a concrete case. A weekly meeting at 09:00 in a region that observes daylight saving: the local time stays fixed, so the UTC instant changes twice a year. If you stored only the first UTC instant and repeated it weekly, every occurrence after the clock change would be an hour off. Naming that example is worth more than any diagram.
All-day events are calendar dates with no zone, so they break a naive timestamp model; store them as a date, not an instant.
Scaling Reads, Writes and Reminders
Now you can talk about scale without it feeling like a bolt-on.
Reads
Cache month and week views per user, and invalidate on write to that calendar. Because reads dominate, this is the highest-leverage change you can make.
Sharding
Shard by calendar owner. Sharding by event time is a poor fit here: it spreads one person's calendar across many nodes, so a single month view fans out to all of them, and free/busy across a team becomes a scatter-gather.
Free/busy fan-out
Free/busy is the second main read path, and it is computed differently from a month view. For each calendar in the request, you read the events overlapping the requested window, expand any recurrence into that window, subtract cancelled exceptions, and merge the busy intervals into a set of free gaps. The merge is conceptually simple, but the boundary handling is where bugs hide: whether interval ends are inclusive or exclusive, and normalising every calendar's zone before you compare, are the details that produce off-by-one gaps and phantom conflicts.
Querying many calendars at once needs a time budget. Set a deadline, return partial results, and tell the user which calendars did not respond in time. Merging partial results means marking the unanswered calendars as unknown rather than free — treating silence as availability is how people end up double-booked. Tie it back to the latency target you agreed with the interviewer: if your budget for free/busy is a few hundred milliseconds, a partial answer inside that budget beats a complete one that blows through it.
Caching interacts with this directly. A per-user month view cache does not help a free/busy query that spans ten calendars, so cache the computed busy intervals per calendar per window instead, with a short TTL, and accept that a just-created event may not appear until the TTL expires.
Reminders
Move reminder delivery to a scheduled pipeline with retries, separate from the request path. A reminder that fires twice is annoying; a reminder that blocks a user's calendar load is a bug.
Spikes
Expect a burst when everyone opens their calendar at the start of the working day. Caching and read replicas absorb most of it; the reminder pipeline should be isolated so it cannot compete for the same capacity.
Concurrency, Conflicts and Trade-Offs to Say Out Loud
Use optimistic concurrency: attach a version number or ETag to each event, and reject an update that carries a stale version. Return a clear conflict response so the client can show the user both versions and let them choose. Last-write-wins is tempting because it needs no coordination, but it silently discards one person's edit — and for a meeting, that is data loss.
Then compare consistency levels honestly. A single event being edited wants strong consistency. A shared team view can be eventually consistent, because a few seconds of staleness is invisible. Say which you chose and why.
Close the walkthrough by summarising two or three trade-offs and what would change your mind. For example: "I expand recurrence on read and cache hot windows; if most calendars were long-running daily series, I'd precompute more aggressively." One sentence per trade-off. That sentence is usually what the interviewer remembers.
Rehearsing the Calendar Service System Design Interview
Reading this is not the same as saying it. Do these five things.
- Rehearse out loud with a timer. Aim to reach the recurrence discussion within the first third of your time.
- Record yourself and check two things: did you state requirements before designing, and did you name trade-offs?
- Prepare three follow-up answers in advance — recurrence exceptions, time zones, and conflict handling.
- Reuse the same structure for other prompts so the opening minutes become automatic and your attention goes to the hard part.
- Practise the one-sentence trade-off summary until it comes out without hesitation.
The calendar prompt rewards a steady narrative more than a perfect diagram. If you want to strengthen the opening minutes, the Blog has more walkthroughs you can rehearse in sequence, including the rate limiter walkthrough.
Frequently asked questions
How deep should I go into recurring events in a calendar system design interview?
Deep enough to state the rule-versus-occurrence trade-off, describe how exceptions are stored, and name the failure mode of your choice. That usually means two to three minutes, and it is worth spending them: recurrence is the part of the prompt that separates a calendar from a generic CRUD system.
Should I store every occurrence of a recurring event or expand it on read?
Both are defensible. Storing the rule and expanding on read keeps writes cheap but pushes cost onto reads for long series. Precomputing occurrences makes reads fast but makes rule edits expensive. Most strong answers propose a hybrid: expand on read for short windows and cache expanded windows for frequently viewed calendars.
How do I handle time zones and daylight saving in a calendar design?
Store the event's intended local time together with its zone identifier, not just a UTC instant, so a recurring 9am meeting stays at 9am when clocks shift. Treat all-day events as dates with no zone, and explain the daylight-saving case out loud — it demonstrates correctness thinking rather than scaling talk.
What is the right way to handle two people editing the same event at once?
Use optimistic concurrency with a version number or ETag on the event, reject updates carrying a stale version, and return a conflict response the client can show to the user. Last-write-wins avoids coordination but silently discards an edit, which for a meeting is real data loss.
How long should a calendar service system design answer take?
Fit the structure to the time you are given, but keep the proportions roughly the same. Spend the first few minutes on requirements and scope, put the bulk of the middle on the data model, recurrence and time zones, and leave the last few minutes for scaling and a short trade-off summary. Decide in advance which parts you will design in depth and which you will sketch, so you do not run out of time mid-recurrence.
Do I need to design the notification and reminder system too?
Only in outline unless the interviewer asks for more. Reminders are a scheduled delivery problem with retries, not a storage problem, so the useful move is to separate them from the request path and say why, then move on.
Read the rate limiter walkthrough next and rehearse its structure out loud.