Most design docs I’ve come across try to achieve total consensus which I’ve always found odd and unrealistic. On the other side, is IETF’s RFC 7282:

We reject: kings, presidents and voting. We believe in: rough consensus and running code.

IETF has been building internet standards for decades without traditional organizational hierarchy, so this is interesting in how they want technical decisions to be made.

The Problem with Engineering Votes Link to heading

Most engineering teams I’ve worked with eventually resort to voting when they can’t reach agreement. It feels democratic, but it optimizes for the wrong thing. Voting answers “what do most people prefer?” when the real question is “what technical approach best addresses our constraints?”

We don’t vote in the IETF. In some ways, we can’t vote: Since the IETF is not a membership organization, it’s nearly impossible to figure out who would get a vote for any given question.

This resonates with something I’ve noticed in cross-functional teams. Who exactly gets to vote on whether we use GraphQL or REST? The frontend engineers who’ll implement it? The platform team that’ll maintain it? Product managers who care about velocity? The security team with compliance concerns?

The IETF’s insight is that membership-based voting doesn’t work for technical decisions because expertise and stakeholdership are contextual, not hierarchical.

What Rough Consensus Actually Means Link to heading

I initially misunderstood “rough consensus” as “good enough agreement.” But the RFC clarifies something important:

Consensus is when everyone is sufficiently satisfied with the chosen solution, such that they no longer have specific objections to it.

This is fundamentally different from satisfaction voting. It’s about addressing objections, not maximizing preferences. The goal isn’t to make everyone happy-it’s to eliminate technical blockers.

Lack of disagreement is more important than agreement.

This flips the usual framing. Instead of asking “who supports approach A?” the question becomes “can anyone not live with approach A?” The second question surfaces different information-real constraints versus personal preferences.

I’ve started experimenting with this in design reviews. When someone objects to a technical decision, we dig into whether it’s a “this seems suboptimal” concern or a “this won’t work because…” concern. The first is them explaining their preference; the second is a technical constraint that needs addressing.

The Async Advantage Link to heading

What’s particularly interesting is how this maps to async-first communication. The IETF makes final decisions on mailing lists, not in meetings:

Final decisions are supposed to be taken on the mailing list, which reinforces the idea that we come to consensus by looking at the open issues and not counting heads.

There’s something powerful about giving people time to think through technical objections before responding. In synchronous meetings, the loudest voice or fastest thinker often wins. Async discussion creates space for deeper analysis.

Real-time consensus-building requires holding multiple complex technical concerns in working memory simultaneously. Async discussion lets you externalize that cognitive work-write down the objection, think through implications, research alternatives.

When Rough Gets Real Link to heading

The “rough” part of rough consensus happens when you can’t satisfy everyone:

It’s when the chair has to declare that an unsatisfied person still has an open issue, but that the group has truly answered the objection, that the consensus is only rough.

This is where most engineering teams get stuck. Someone raises a legitimate technical concern, but addressing it would require significant tradeoffs elsewhere. Traditional consensus models deadlock here.

The IETF’s approach is to explicitly acknowledge the unsatisfied objection while explaining why the group chose not to accommodate it:

Any finding of rough consensus needs, at some level, to provide a reasoned explanation to the person(s) raising the issue of why their concern is not going to be accommodated.

I’ve seen this pattern work in product engineering contexts where technical constraints bump up against product requirements. Instead of hand-waving away concerns, you document the tradeoff explicitly. The objector may not be happy, but they understand the reasoning and can plan accordingly.

Humming Instead of Hands Link to heading

The IETF has this interesting practice of “humming” instead of showing hands when they want to gauge sentiment:

Sometimes, to reinforce the notion that we’re not voting, instead of a show of hands, we often “hum”.

It’s not my cup of tea, but its interesting how they try to solve for sensing general direction over counting votes. I agree, that it also prevents the anchoring effect where early hand-raisers influence others.

I’ve been trying a variation of this in architecture discussions. Instead of asking “who prefers option A?” I ask “who sees significant technical problems with option A?” and have seen much more productive conversations.

The Facilitation Challenge Link to heading

Reading this made me realize how much consensus depends on skilled facilitation. The chair needs to:

  • Distinguish between technical objections and preferences
  • Ensure minority views get heard and addressed
  • Recognize when rough consensus has emerged
  • Communicate decisions in ways that acknowledge unsatisfied objections

Most engineering leads aren’t trained for this. We default to hierarchical decision-making because facilitative consensus is genuinely harder. But the payoff is decisions that stick because the technical concerns have been thoroughly aired.

Connection to System Design Link to heading

There’s an interesting parallel here to how we think about distributed systems. Traditional voting is like synchronous consensus-you need everyone online and participating. Rough consensus is more like eventual consistency-you work toward agreement over time, with temporary inconsistency being acceptable.

Trying to force synchronous decision-making across time zones creates artificial constraints. Async consensus processes can actually produce better technical decisions because they give space for deeper analysis.

Questions This Raises Link to heading

I’m still working through how to apply this practically. Some open questions that I’m going to dig into more to feed my curosity:

  • How do you prevent “consensus fatigue” when every decision requires extensive discussion?
  • What’s the right threshold for moving from discussion to rough consensus?
  • How do you handle time-sensitive decisions that can’t wait for full consensus?

The IETF has the luxury of long timelines for most decisions. Product engineering teams don’t always have that luxury. But I suspect there’s a middle ground between “let’s vote on it” and endless discussion.


Maybe the goal isn’t perfect consensus, but ensuring all technical objections get properly addressed.