Four rounds of pull request comments about pagination
I once spent the best part of three days arguing with a backend colleague about pagination. The endpoint returned a list of orders, and I had written it with cursor pagination: you get a page and a token for the next one. She left a review comment asking for offset pagination instead, with page numbers. I replied with the usual reasons cursors are better for lists that change while you read them. She replied that offset was simpler and that the cursor version made a particular screen awkward. I replied that the awkwardness was worth it. She replied, a little more firmly, that it was not.
By the fourth round we were both restating the same points with stronger adjectives. Nobody was being rude, exactly. But I had started drafting replies in my head while doing other work, which is always a sign that a thread has stopped being useful.
We got on a call for twenty minutes. About five minutes in it became obvious that we were talking about different screens. I was thinking of the mobile app, which scrolls endlessly and never needs page 40. She was thinking of an admin export screen where support staff jump straight to a page number someone read out on the phone. Both of us were right about our own screen. Neither of us had mentioned which screen we meant, because each of us assumed it was obvious.
The decision took two more minutes: cursors on the public endpoint, offset on the admin one. I wrote it in the pull request before we hung up.
That thread did not need a call because it was heated, and it did not need one because it was important. It needed one because writing had stopped producing new information. That is the main signal, and the five checks below are ways of spotting it before day three.
It needed one because writing had stopped producing new information.
Default to one more structured round
Most disagreements on a remote team can finish in writing if people name the options, bring evidence and agree a decision time. A live call becomes worth it when writing keeps looping, when tone is souring the thread, or when waiting costs more than a short conversation.
My rule of thumb is to try one more written round with a hard decision time first, and to escalate only when one of the checks below trips. Whether a topic deserves a meeting at all, before anyone has disagreed, is a different and broader question; I cover it in when a remote team needs a meeting.
Check 1: three rounds with no movement
Threshold: three full rounds on the same decision with no movement towards a shared option.
A round means each person involved has replied once to the current options, not three messages from the same person. If the third round still has the same two positions and no new fact, writing is unlikely to produce the missing piece. Book fifteen to twenty-five minutes with a short pre-read listing the stuck options.
If the second round already narrowed things and only details remain, stay in writing. Details belong in comments with a reaction deadline. The test I use is simple: did the latest reply contain anything the previous one did not? In my pagination thread, rounds three and four did not. That was the moment to stop typing.
Check 2: a fact nobody in the thread can reach
Threshold: the argument depends on a fact that nobody in the thread can confirm from something shared within one working day.
"Does the vendor API support this?" when nobody has a sandbox account. "Did legal already approve this copy?" when the email sits in one person's inbox. "Is that customer still on the old plan?" when only sales can see the account.
If the fact can be fetched in writing (paste the ticket, link the contract, run the query, forward the email), stay async, name the person fetching it and give them a UTC deadline. Do not book a call to argue about something one person could paste in five minutes. If the fact needs two people looking at the same confusing output and interpreting it together, a short screen share is right, followed by a written decision.
There is a quieter version of this check, which is what caught me: the hidden assumption. Both people hold a fact the other lacks, and neither knows it matters. A call surfaces those quickly because you can hear the other person's example and say "wait, which screen?" in the same breath.
Check 3: the thread is getting personal
Threshold: two or more of these signals show up: personal attribution ("you always"), sarcasm aimed at a person rather than the work, side conversations forming in private messages, or someone saying they feel dismissed.
Tone is where async fails first. Text strips out the small signals that let people repair a misunderstanding as it happens. A fifteen-minute voice call, cameras optional, followed by a written decision line, usually costs less than another day of comments getting sharper.
The test I like: if you would not want the thread screenshotted and shown to a new hire, stop typing and talk. Then write the outcome back where the work lives, so the call does not turn into a story people half remember.
Stay in writing when the heat is about the work and people are still addressing the work. "This change breaks the migration" can stay in review comments. "You never take product seriously" needs a voice.
Check 4: hard to undo, wide reach
Threshold: the choice is hard to reverse within a week or affects people who are not in the thread, and the positions still split after one written options doc.
Decisions like that deserve live attention, but only after writing has framed them. First write a half-page note: context, options, recommendation, owners, and what would make you revisit it. That format is the one in documenting decisions without bureaucracy. Give it a comment window in overlap hours.
If the window closes with the positions still split, book the call. If the comments converge, skip the call and publish the decision. Choices that are easy to reverse and touch few people almost never need a disagreement call, however loudly people disagree. Feature flags, copy tweaks and experiment variants can be settled by trying one.
Check 5: waiting costs more than talking
Threshold: the cost of waiting is higher than the cost of a short call for the people who must decide.
Rough maths for a sticky note:
People blocked: N
Days until the next natural overlap without a call: D
A rough value for one blocked person-day, using your own planning number: V
Call cost: attendees × length in hours, plus about half an hour to an hour of lost focus per attendee (my planning assumption, not a measurement)
If N × D × V is clearly larger than the call cost, and the other checks already lean towards talking, book it. If the "blocker" is really discomfort with an open question, stay in writing.
Two engineers blocked on an API shape for three days, with weak overlap between their zones, is six engineer-days of stalled integration. A twenty-minute call for three people is cheaper by a long way. A disagreement about README formatting that blocks nobody can stay in writing indefinitely, and probably should.
Diagram
Diagram · 16:9five checks from stalled writing rounds through tone, reach and waiting cost, shows when a disagreement should leave the thread for a short call, labelled flow, ratio 16:9, diagram
If you decide to meet
Write a three-line invite: the decision sentence, a link to the stuck thread or options doc, and a hard stop.
Invite only the people who must speak. Everyone else reads the notes.
Name the note taker in the invite.
Open with the decision sentence, not with status.
Before hanging up, write: decision, owner, date, and what you explicitly did not decide.
Link those notes from the ticket within the hour.
If you cannot write step one, you are not ready to meet. Do one more written round instead.
If you stay in writing
Restate the decision sentence at the top of the thread.
List at most three options with one advantage and one drawback each.
Ask for reactions by a UTC time inside the next overlap window.
Name who decides if agreement fails, by role, not by whoever is loudest.
After the deadline, publish the choice and close the thread. Late opinions reopen it only if they bring a new fact.
That last step matters more than it looks. Threads that never formally close are how two people end up building both options in parallel, which is exactly the duplicate async work everyone says they hate.
The same argument, run two ways
Without the checks: a pricing disagreement runs for nine days in a chat channel. Sixteen people add opinions. Nobody owns a decision time. Two developers wait. Eventually someone books a sixty-minute alignment call for twelve people with no pre-read. The call spends forty minutes discovering basic facts out loud and ends with "let's write a doc". Another week goes.
With them: the same disagreement trips Check 1 at round three and Check 5 because two developers are blocked. An options doc goes out Monday at 14:00 UTC. A twenty-minute call happens Wednesday with product, the engineering lead and design. The decision goes into the ticket before anyone leaves. The developers start Thursday morning.
Same people, same disagreement. The only difference is that somebody noticed the thread had stopped producing anything new.
When someone asks for a call about a disagreement, ask which check tripped. If none did, write one more round and put a clock on it. If one did, send the pre-read and keep the call short. And notice your own version of my pagination tell: when you are composing replies in your head while doing something else, the thread has already told you what it needs.
End of this piece
Writer
PrimedEcho
Independent notes on remote work, focus, and freelance practice. About this site.