MySQL10 min read

MySQL Group Replication vs Async Replication: Field Notes on the Tradeoffs

Group Replication promises consensus-backed failover; classic async promises simplicity. Field notes on what GR actually guarantees, how flow control stalls write bursts, and when async plus an orchestrator is still the better architecture.

I have run both architectures in production: classic async replication with an external failover manager, and Group Replication under InnoDB Cluster. I have also been paged by both. The async fleet once promoted a replica that was missing the last two seconds of committed writes. The GR cluster once throttled the primary to a crawl during a bulk import because one member's applier fell behind. Neither incident was a bug — both were the architecture doing exactly what it was designed to do.

That is the honest frame for this comparison. Group Replication is not a strictly better replication; it trades write availability and throughput headroom for a durability guarantee that async fundamentally cannot make. Whether that trade is right depends on your write pattern, your network, and how much operational machinery you are willing to own. These notes cover the guarantees as they actually are, the flow control behavior that surprises everyone, failure detection in both worlds, and where I draw the line between them.

What async guarantees, and what it quietly does not

Classic async replication is a log-shipping pipeline: the primary commits locally, writes the transaction to the binlog, and replicas pull and apply it on their own schedule. The primary never waits. That is the whole appeal — replication cost on the write path is near zero, replicas can be added almost without limit, and a slow or dead replica affects nobody but itself. The mechanics of that stream are their own topic; I covered them in the binlog vs WAL notes.

The guarantee it does not make: a transaction acknowledged to the client can exist only on the primary at the moment the primary dies. Fail over at that moment and those commits are gone — or worse, they resurrect later when the old primary is restored and now diverges. Semi-synchronous replication narrows the window by making the primary wait for one replica to acknowledge receipt (receipt into the relay log, not application) before acknowledging the client, but with a timeout that silently degrades to async when replicas stall. Semi-sync is a probability improvement, not a guarantee.

What Group Replication actually guarantees

Group Replication runs a Paxos-derived group communication engine underneath a set of 3 to 9 members. On commit, the transaction's write set is broadcast, and the commit only proceeds once a majority of members agree on its position in the total order and it passes certification — the conflict check against concurrently certified transactions. In the default single-primary mode certification conflicts are rare; in multi-primary mode, certification is what rolls back conflicting concurrent writes on different members.

The guarantee you buy: a committed transaction is durably known to a majority, so no single node failure can lose it, and the quorum requirement makes split-brain writes structurally impossible rather than operationally prevented. A minority partition stops accepting writes on its own, with no fencing scripts involved.

The guarantee people wrongly assume they bought: synchronous apply. Certification is synchronous; application is not. A secondary acknowledges ordering, queues the transaction, and applies it asynchronously. Right after a commit, a read on a secondary can be stale — GR's default consistency level is EVENTUAL. Since 8.0.14 the group_replication_consistency setting offers stronger modes: BEFORE makes a reading session wait until the local member catches up, AFTER makes writes wait until they are applied everywhere, BEFORE_ON_PRIMARY_FAILOVER holds queries on a newly promoted primary until it has applied its backlog. Each stronger level moves latency from the failure case into the everyday case; most deployments I have seen run EVENTUAL plus BEFORE_ON_PRIMARY_FAILOVER and handle read-your-writes in the application.

Flow control: the stall nobody budgets for

Because apply is asynchronous, a fast primary can build unbounded backlogs on slower members. GR's answer is flow control: when a member's certification or applier queue exceeds thresholds (25,000 transactions each by default), the group computes a quota and throttles writers. This is the mechanism behind the signature GR incident: a bulk import or a write burst runs fine for a minute, then primary throughput drops off a cliff while every host shows idle CPU. Nothing is broken. One member with slower storage or a cold buffer pool is lagging, and the whole group is now pacing to protect it.

The queues are visible, and I check them before touching any tuning knob:

SELECT member_id,
       count_transactions_in_queue        AS certifier_queue,
       count_transactions_remote_in_applier_queue AS applier_queue,
       count_transactions_checked,
       count_conflicts_detected
FROM performance_schema.replication_group_member_stats;

Pair the queue depths with membership state, which is where expel churn and recovering members show up:

SELECT member_host, member_state, member_role, member_version
FROM performance_schema.replication_group_members;

You can raise the thresholds or disable flow control entirely, and sometimes that is right — but understand what you are choosing: an unthrottled group lets the applier queue grow without bound, and if you fail over to a member holding a million-transaction backlog, BEFORE_ON_PRIMARY_FAILOVER turns your failover into minutes of write unavailability while it drains. Flow control is not an annoyance to disable; it is the knob that decides whether write bursts cost you throughput now or availability during failover. Async replication makes the opposite default: the primary never slows down, and lag is purely the replicas' problem — which is exactly why async lag monitoring has to be treated as a first-class alert rather than a curiosity.

Failure detection: built-in membership vs external judgment

GR detects failures itself. Members exchange liveness through the group communication layer; an unresponsive member is suspected, and after group_replication_member_expel_timeout (default 5 seconds in modern 8.0) it is expelled. The survivors, if they hold a majority, elect a new primary in seconds with no external coordinator, and expelled members can attempt automatic rejoin. The failure cases that remain are the distributed-systems classics: a full network partition where no side holds a majority blocks writes everywhere until an operator intervenes, and flaky networks cause expel-rejoin churn that is far more disruptive than a clean failure. WAN links push GR's timeouts and consensus round trips into uncomfortable territory; GR wants low, stable latency between members.

Async replication has no built-in opinion about failure at all. Detection, quorum judgment, candidate selection, and topology rewiring belong to an external system — orchestrator being the standard choice — plus something to move client traffic. That machinery is yours to deploy, test, and keep honest, and its judgment about the freshest replica decides how many transactions a failover costs. I compared that world with Patroni's approach on the PostgreSQL side in the orchestrator vs Patroni notes; the short version is that external failover systems are mature and battle-tested, but they are a second distributed system you now operate.

The constraint list GR does not advertise loudly

  • Table requirements. InnoDB only, and every table needs a primary key or a non-null unique key — certification works on write sets keyed by them. Audit before migrating, not after.
  • Transaction size. group_replication_transaction_size_limit defaults to roughly 143 MB, and huge transactions stress consensus even under the limit. Chunk your batch jobs.
  • Nine members, majority quorum. Read scale beyond nine means hanging async replicas off the group anyway. Two-member groups are worse than one: lose either and the survivor has no majority.
  • Prerequisites. GTID mode, row-based binlog, and ideally uniform hardware — the slowest member sets the group's write pace once flow control engages.
  • No filtering, no delayed members. The tricks async operators lean on — replication filters, delayed replicas as fat-finger insurance — do not exist inside a group.

When I pick which

Group Replication, via InnoDB Cluster with MySQL Router and the Shell AdminAPI, is my pick when the workload is OLTP with small transactions, the members share a low-latency network, write throughput has headroom to spare, and the business requirement is genuinely zero committed-transaction loss with hands-off failover. Payments, inventory, anything where resurrected or vanished writes turn into reconciliation projects.

Async plus orchestrator stays my pick when replicas span regions, when write bursts and bulk loads are routine and cannot tolerate flow control pacing, when I need many replicas or delayed replicas or filtered replicas, and when the team already understands binlog replication cold. A well-monitored semi-sync setup with tested failover automation loses less data than its reputation suggests, and its failure modes are simpler to reason about at 3 a.m. The mistake is not choosing either one; it is choosing GR for its brochure and then disabling flow control, running two members, and putting them on a WAN — at which point you own async's risks plus consensus latency.

Monitoring both worlds — and where MonPG fits

The two architectures need different evidence. Async needs lag per replica measured in transactions and seconds, semi-sync degradation events, and GTID gaps at failover time. GR needs member state churn, certification and applier queue depths, conflict rates in multi-primary setups, and flow control engagement — the queue query above, sampled continuously, would have explained every GR page I have received.

Stating MonPG's position plainly: MonPG is a PostgreSQL monitoring platform today, and MySQL support is being built now — it does not monitor MySQL clusters yet. Replication topology evidence like the above is core to what we are building, and the MySQL monitoring (coming soon) page is where to track it or tell us which topology you run. If your estate includes PostgreSQL, its streaming replication and failover stacks are fully covered today and you can start there.