We know database replication is either sync or async, but there is a third mode that MySQL supports - semi-sync replication, and it is a clever middle ground worth knowing about.
MySQL’s default is async. The source commits a transaction and moves on immediately, with no idea whether the replica ever received it. If the source crashes at the wrong moment, those committed transactions are simply gone from the replica.
Fully synchronous replication fixes that - the source waits for every replica to commit before returning to the client. Safe, but every write now pays the cost of a full network round trip to every replica. That adds up fast, of course.
Semi-sync replication sits right in between. The source waits for at least one replica to acknowledge that it received and flushed the events to its relay log. Once that acknowledgment arrives, the source commits and returns. It does not wait for all replicas, and it does not wait for the replica to fully apply the transaction - just confirm receipt.
The cost is one TCP round-trip per commit to the nearest replica. This works best when the source and replica are on the same fast network. Over a slow or distant connection, every write slows down by that round-trip time.
There is also a built-in fallback - if no acknowledgment arrives within the timeout, MySQL quietly falls back to async replication. When the replica catches up, it switches back to semi-sync on its own.
Also, if the source crashes and you fail over to a replica, do not bring that crashed source back as a replication source. It may have locally committed transactions that were never acknowledged by any replica - reintroducing it will cause inconsistencies.
Semi-sync is actually a well-designed tradeoff, certainly not a silver bullet, but certainly the right tool when you need stronger durability without going fully synchronous.