Post

Timezone collaboration without chaos

Overlap bands, fair five-step invites, EU/NA/Asia relay, async requests that survive a night, and copyable handoffs for distributed teams.

On this page

The weekly call that quietly cost one person her evening

For most of a year I sat in a weekly status call that started at 15:00 my time. It was a comfortable slot: lunch behind me, the worst of the afternoon dip not yet arrived. The product owner who organised it was in New York, where it was 09:00, also comfortable. The third regular was a tester in Manila, and for her it was 21:00.

She joined every week, camera off, said "nothing new from my side" most weeks, and left. None of us thought about it. The invite showed a sensible time in each of our calendars, nobody declined, so it looked fine. Then one week she mentioned, half as a joke, that Tuesday was the night she ate dinner on mute. I did the arithmetic and felt a bit stupid. Her written test reports were the most useful thing discussed in that call, and they were already in the tracker before it started. We were keeping her up so she could read us something we could have read ourselves.

That call is the whole problem with time zones in miniature. Nobody was being unkind. The calendar did exactly what it was told. The cost landed on the person furthest from the organiser, and she was too polite to send it back. Most time zone chaos looks like that. It is rarely a disaster. It is a slow, quiet tax on whoever lives at the edge of the map.

What follows is the system I've ended up with after several years on remote teams and freelance projects spread across Europe, the Americas and Asia. It is not clever. Most of it is writing things down in UTC and being honest about how many hours you actually share.

Photograph · 3:2A tester on a weekly status call from a kitchen at 21:00 with dinner on the table, a slot that looks comfortable only on the organiser's clock, warm indoor light, ratio 3:2, stock

Sort every pair of people into green, yellow or red

The clock on your wall is local. What a team needs is the set of hours, written in UTC, when every required person can work without giving up their evening. If those hours have no name, every invite turns into a small negotiation, and the person with the least seniority loses it.

Start by listing who must be part of a decision. Not who might find it interesting: who has to say yes. Write their zones as proper IANA names, such as Europe/Berlin, America/New_York or Asia/Manila. "The US" and "Europe" are not clocks. Two people in the United States can be three hours apart, and one of them might stop at 15:00 for a school pickup every Wednesday.

Then write down a daytime span. I use 08:00 to 18:00 local unless someone tells me otherwise. This sounds pedantic until you skip it. If the span is never written, "reasonable" drifts until it includes 21:30, which is exactly how my Tuesday call happened.

Now count the shared hours inside that span, for each pair and for the whole required group. I sort the results into three overlap bands:

  • Green: four or more shared daytime hours on most days. Decisions, pairing, code review conversations and a client call that fits all belong here.
  • Yellow: one to three shared hours. Enough for a short agenda with a pre-read, or a two-minute voice handoff. Not enough for a workshop. Push a yellow slot past its edge and the person on that edge leaves early or misses the decision, and next time they decline the series.
  • Red: no shared daytime unless someone works at night. Red is writing. You either move the decision into writing or shrink the list of required people until a band appears. You do not call a midnight slot "team culture".

The bands are only useful if you keep an eye on who pays for them. I track what I call overlap debt: every required attendance outside someone's written 08:00 to 18:00. If the same two names carry it every week, change the roster or change the meeting. Recompute whenever headcount changes and on the weeks the clocks change, because an offset that was right in March can be wrong in November. The specific ways that goes wrong are in DST mistakes remote teams make.

Decide how much live time this roster can afford

Once you know the band, match the plan to it. The most common mistake I've seen is a green plan running on a yellow roster: a daily standup and two weekly syncs for people who share ninety minutes. That setup becomes a standing apology.

Two zones with green overlap. Protect that window before other recurring meetings eat it. Spend it on decisions, pairing and reviews. Publish it in the first week, in UTC, with each person's local time on the same line.

Yellow only. Write first. Allow one short decision slot a week, and only if the pre-read is linked the day before. If the pre-read is missing, cancel. Do not quietly turn the slot into a round of updates, because updates are the easiest thing in the world to write down.

Three regions with no shared hour. Relay the work. Live time is pairwise, and the third person gets a written result and a next action, not a 22:00 seat so they can hear status. Unless you can name a conflict that genuinely needs all three voices at once, you do not have a three-way meeting.

One region always takes the late slot. Rotate it in public, or treat it as paid coverage with an end date. And praise the right thing. Praise the note that let the other region start on time, not the person who replied at midnight. Praising midnight replies is how you end up with the problem described in available all day is a bad system.

Reply expectations follow the same lines. Inside the overlap, chat is fair and a same-day answer is a reasonable aim. Outside it, nobody owes an instant reply, and a complete written request still gets answered at the next overlap. A vague instruction to "be responsive" mashes those two situations into one feeling, and new hires will stay up late trying to satisfy it.

Relay the day when three regions never share an hour

Here is the roster from my opening story, cleaned up into a worked example. The assumptions matter, so I'll state them. Berlin engineering works 09:00 to 17:30 local. New York product works 09:00 to 17:30 local. Manila QA works 09:00 to 18:00 local. The UTC figures assume northern summer, so Berlin is on Central European Summer Time (UTC+2) and New York on Eastern Daylight Time (UTC-4). Manila stays on UTC+8 all year.

In winter both Berlin and New York shift by an hour, and there are a few weeks in spring and autumn when only one of them has shifted. Recompute before you send a January invite. Do not paste summer hours into a winter series.

Under those summer assumptions the working spans in UTC are:

PersonLocal hoursUTC (summer)
Berlin engineer09:00 to 17:3007:00 to 15:30
New York owner09:00 to 17:3013:00 to 21:30
Manila QA09:00 to 18:0001:00 to 10:00

Berlin and New York share 13:00 to 15:30 UTC. That is two and a half hours, which by my own rules is yellow, and it is the most valuable yellow on the roster. A lunch break or a habitual 15:00 meeting on the Berlin side can cut it to an hour without anyone noticing. Berlin and Manila share 07:00 to 10:00 UTC, also yellow. New York and Manila share nothing in daylight. That pair is red, and a weekly hunt for a time that suits both will always end in somebody's night.

Diagram · 16:9Berlin, New York, and Manila daytime spans on one UTC axis, yellow overlap for Berlin with each of the others and red between New York and Manila, timezone overlap diagram, ratio 16:9, diagram

So the day becomes three hops, each with an owner:

  1. Manila to Berlin, around 08:00 UTC. Talk only if a voice prevents a wrong turn. Otherwise the handoff is already written on the ticket.
  2. Berlin to New York, 13:00 to 15:00 UTC. This is where decisions and review conversations happen. Status must be on the ticket before the window opens, or the decision slips past Berlin's day and into red.
  3. New York to Manila, in writing. New York finishes the note before logging off, because New York's afternoon is Manila's next morning.

A decision that needs all three people takes a full day to travel round. Anything Manila must act on tomorrow has to be written before New York's afternoon ends. If there is a three-way conversation that truly cannot be relayed, rotate the slot, record it, and send a written document before it. It should never be weekly status.

To make that concrete, one ordinary weekday with the same offsets. Manila posts test results before logging off, with the verification step and a line about what not to redo. Berlin reads them, writes a short decision brief before 12:00 UTC, and includes a recommendation plus a default if New York says nothing. New York uses 13:00 to 14:00 UTC to choose, writes the choice on the ticket before the slot ends, and leaves Manila a note covering what changed, how to verify it, what not to redo, and the next action with an owner and a UTC time. If Berlin's brief is late, nobody drags New York into a longer call. The decision moves to the next day, or the default runs. One extra half hour is all it takes to turn Berlin's yellow into red.

Run five checks before you send any recurring invite

I do this with the roster open, before I touch the calendar. If I start in the calendar, I start from my own morning, and the late slots drift onto whoever is furthest from me.

  1. List required voices only. If nothing breaks when a person is absent, they are optional and get the written summary. "They might have context" does not count as breaking. Context can be read.
  2. Map working hours from the roster, using IANA zones. Do not ask people to propose times first. Proposals cluster around the organiser's morning.
  3. Find the intersection in UTC for that specific date. Daylight saving belongs to the date, not to a city's nickname. Put each local start and end on the same line as the UTC span.
  4. Paste every required local time into the invite body. A lone UTC time gets misread, and a lone local time is meaningless to half the room.
  5. Name the outcome and the written fallback together. "We leave with option A or B chosen, written on PAY-200." If no green or yellow window exists that day for the required people, send the brief instead, with a UTC deadline and a default if nobody replies.

Here is how a few real invites hold up against those checks, using the summer offsets above:

InviteVerdict
14:00 UTC, 30 minutes, Berlin and New York, brief already sentFair. Inside the shared window, with a reason to exist
16:00 UTC weekly standup, Berlin and New YorkUnfair as a series. It starts at 18:00 in Berlin, after a normal day
"Whenever works", no zones in the bodyThrash. The cost is real but invisible
21:00 Manila weekly, so three regions hear statusUnfair. This was my Tuesday call. Write the status and relay it

If someone declines because the local time falls outside their 08:00 to 18:00, that is the system working, not someone being difficult. Move the slot or mark them optional. Once a slot is fair it still has to earn its length, which is the subject of fewer and better remote meetings.

Fill the five-line invite worksheet

Fill the five-line invite worksheet

Decision: [the choice, in one line]
Pre-read: [link, sent at least one workday ahead]
Exit: [what is written before hang-up, and where]
Required: [roles plus IANA zones; everyone else is optional]
Local clocks: [each required start and end, plus the UTC span]

If any line is empty, I am not ready to send it. An empty Decision line usually means the meeting is really a request for someone else to work out the agenda live, which spends the overlap on writing that should have happened yesterday.

Filled in for the Berlin and New York pair, with the pre-read already on the ticket and Manila picking up the result in the morning handoff:

Decision: checkout provider A vs B
Pre-read: PAY-200 decision brief
Exit: choice recorded on PAY-200 before hang-up
Required: Berlin engineer (Europe/Berlin), New York owner (America/New_York)
Local clocks: Berlin 15:00 to 15:30 CEST, New York 09:00 to 09:30 EDT, 13:00 to 13:30 UTC

Thin overlap calls for a tighter brief, not a longer meeting. And if the pre-read link does not open for one of the required people, fix the access before the slot rather than spending the first ten minutes on permissions.

Write requests that survive someone else's night

The person reading your message overnight cannot tap you on the shoulder. I learned this properly from one short message. At about 17:40 my time I wrote to a developer whose morning began while I slept:

Can you look at the checkout?

His reply was waiting when I woke up: which part, preview or production, and was this the bug from Thursday? By the time I answered, it was his evening. A full working day went on a sentence that would have taken me two extra minutes to write properly.

A request that survives a night includes the link, what done looks like, if you need a decision or an action, and a deadline in UTC. Miss any one of those and the reader either guesses or waits, and the relay loses a day. The version I should have sent:

PR 482 fails on the payment webhook in preview. The preview webhook secret is missing from the environment. Please set it before 14:00 UTC. Done means one success path and one failure path clicked through, with pass or fail commented on the PR.

A few habits make this easier. "End of day" means three different times on a three-region team, so write the UTC hour, and if you really mean their evening, say so on purpose. Answer questions in full the first time; ten lines now beat five exchanges across three mornings. If something can wait, say when you will next be online, in your zone and in UTC. The longer version of what a written ask needs is in async communication for distributed teams.

Most of all, do not log off on an open question that someone else is waiting for. Your open question becomes their blocker the moment you close the laptop. If you still own the work, leave a status note in the shape described in end-of-day status update. If ownership moves to someone else overnight, a status note is not enough. You need a handoff.

A handoff that describes your day is not a handoff

The handoff I'm least proud of said, roughly, "almost done, just the Redis thing left". The engineer who picked it up in the morning did the sensible thing with the information he had and restarted the old worker pool, which I had already restarted twice. That wiped the state I'd been staring at, and we both spent his morning getting back to where I'd been the night before. Nothing in my note was false. It just described my day instead of telling him what to do with his.

Since then I use five fields, every time ownership crosses a night.

Copy the overnight handoff template

Copy the overnight handoff template

Changed: [what is true now that was not true when you started]
Verify: [the check the next owner runs without you]
Do not redo: [the restart or experiment that would waste the next shift]
Next: [the first action, concrete enough to begin]
Owner: [role, IANA zone, and the UTC time the next move is due]

If Verify or Next is empty, you have written a diary entry. Either fill them in or keep the ticket and say so clearly, or the other region will pick it up by mistake.

Here is the note I should have written that night. The staging rate limit had been raised, the worker pool already restarted, the next likely fault was a Redis setting in preview, and the Berlin engineer owned the next move before 10:00 UTC:

Changed: rate limit raised on the staging API
Verify: hit /health and one authenticated route
Do not redo: do not restart the old worker pool
Next: if 5xx persists, check the Redis connection string in preview
Owner: Berlin engineer, before 10:00 UTC

Inside a yellow or green window, a two-minute voice handoff is worth it when it prevents a wrong restart. Stamp the note with UTC even if you write it at your own 17:00, because "this afternoon" stops meaning anything the moment you sign off. The fuller method, including how to separate blockers from ordinary next steps, is in leave work someone else can continue.

Publish the roster, the reply bands and who takes the late slot

Keep one roster and let people edit it when their hours change. If a second copy lives pinned in chat, that will be the one someone trusts on the week it is out of date.

PersonIANA zoneTypical local hoursUTC this seasonNotes
Berlin engineerEurope/Berlin09:00 to 17:30Recompute for the dateSchool pickup on Wednesday
New York ownerAmerica/New_York09:00 to 17:30Recompute for the dateEarly start on decision days
Manila QAAsia/Manila09:00 to 18:0001:00 to 10:00No daytime overlap with New York

Pair each overlap band with a reply band. Otherwise "urgent" ends up meaning both "right now" and "when you get a moment", and the person in the later zone pays for the confusion.

Overlap bandReply you can expectLive time
Green, shared daytimeDecisions and ordinary requests, same dayShort, with a stated outcome
Yellow, thin overlapWritten request with a UTC need-byA real blocker only, pre-read already sent
Red, no shared daytimeWritten request, answered at the next overlapNone, except the production incident path

Put both tables somewhere a new starter will find them in their first week. More detailed wording for reply promises is in response expectations that respect time zones.

Then write the rules down in a form short enough to paste, and refuse quiet exceptions:

Decision hours: 13:00 to 15:00 UTC on weekdays
Outside those hours: a complete written request, reply at the next overlap
Urgent production: the incidents channel only
Handoff fields: Changed, Verify, Do not redo, Next, Owner
Late slot: rotated, never the same region three weeks in a row

The "quiet exceptions" part is where most teams slip. Someone senior asks for "just this once" at 16:00 UTC, and because nobody wants to be awkward, it happens. Then it happens again. A rare live exception can rotate. The week it becomes weekly, it is policy, and it should be written down as policy so people can argue with it.

When the client is the one in another time zone

Freelancing adds a twist, because the person setting the hours is also paying you. I once worked with a client seven hours behind me whose only free time, as far as he was concerned, was the end of his working day. That was 20:00 for me. I said yes for about a month, and my evenings started to feel borrowed.

What fixed it was not a difficult conversation. In the next quote I named the hours I work, the shared window we had (his early morning, my mid-afternoon), and a line saying calls outside that window were billed at a higher evening rate. He chose written updates within a week and seemed relieved; it turned out he had been squeezing those calls in reluctantly too.

The general version: put the clocks in the contract. Name the overlap, the response window, and who absorbs a rare red-band call. If a client can only meet in your red band, that belongs in the price or in a rotation with an end date. It does not belong in your goodwill indefinitely.

When you are the one seven hours ahead, treat the shared window as precious. Protect it for decisions and write everything else. Don't join every 09:00 call on their side as if you shared their whole day, and put your own fixed commitments, like an early finish on Wednesdays, on the roster where they can see them. On the weeks the clocks change, confirm the offset before accepting a repeating invite.

Silence, holidays and the first two weeks of a new hire

Silence needs a rule, or it turns into anxiety. My rule: after two quiet overlaps, send one bump with the same fields and a new UTC cutoff. If the choice is still open, book a short slot in the next green or yellow window and write the decision down before anyone leaves. A third quiet overlap means the default runs. Do not start a new status meeting about the silence.

Name the hop when you assign work. "Manila to Berlin owns the next move" is usable. "The team overnight" is not an owner. Public holidays shrink green and sometimes delete it, so update the roster before the week starts and cancel any slot that would only make the people who turned up feel guilty about the people who didn't.

New hires are the best test of the whole system, because they have no memory of how things used to work. Ask them to add their real hours to the roster, send one complete request and leave one handoff in their first week. For their first two weeks, count three things: invites outside someone's daytime span, requests with no UTC deadline, and handoffs that needed a call to understand. Fix one series based on what you find. If nobody can say who has been taking the late slot, export the calendar and look before anyone starts a conversation about culture.

It is a slow, quiet tax on whoever lives at the edge of the map.

The calendar will never tell you that someone is eating dinner on mute. You have to go and look, in UTC, with the roster open. I'd rather protect two and a half shared hours properly and write everything else down than pretend a team spread across three continents shares a working day. It doesn't, and the sooner the plan admits that, the sooner the person at the edge of the map gets her evenings back.

End of this piece

Writer

PrimedEcho

Independent notes on remote work, focus, and freelance practice. About this site.

All posts