# Versioning versus Coordination

DevFeed: [Versioning versus Coordination](<https://devfeed.tech/articles/versioning-versus-coordination-12568.md>)

Original publisher: [Read original article](<http://brooker.co.za/blog/2025/02/04/versioning.html>)

Author: Marc Brooker

Published: 2025-02-04T00:00:00Z

Content type: article

Language: en

Sources: [Marc Brooker's Blog](<https://devfeed.tech/sources/marc-brooker-s-blog.md>), [Marc Brooker's Blog](<https://devfeed.tech/sources/marc-brooker-s-blog-2.md>)

Topics: [Databases](<https://devfeed.tech/topics/databases.md>), [Transactions](<https://devfeed.tech/topics/transactions.md>), [Concurrency](<https://devfeed.tech/topics/concurrency.md>), [Scalability](<https://devfeed.tech/topics/scalability.md>), [Availability](<https://devfeed.tech/topics/availability.md>), [Latency](<https://devfeed.tech/topics/latency.md>), [SQL](<https://devfeed.tech/topics/sql.md>)

Tags: [architecture](<https://devfeed.tech/tags/architecture.md>), [availability](<https://devfeed.tech/tags/availability.md>), [concurrency](<https://devfeed.tech/tags/concurrency.md>), [data](<https://devfeed.tech/tags/data.md>), [database](<https://devfeed.tech/tags/database.md>), [latency](<https://devfeed.tech/tags/latency.md>), [scalability](<https://devfeed.tech/tags/scalability.md>), [sql](<https://devfeed.tech/tags/sql.md>), [transactions](<https://devfeed.tech/tags/transactions.md>)

## AI overview

The article argues that multi-versioning is preferable to coordination for a distributed database. It presents a serializable transaction example, explains how locking reduces concurrency and creates coordination challenges across replicas, and shows how versioned rows let readers and writers proceed without blocking while improving scalability, throughput, and performance consistency.

## Source excerpt

Versioning versus Coordination Spoiler: Versioning Wins. Today, we're going to build a little database system. For availability, latency, and scalability, we're going to divide our data into multiple shards, have multiple replicas of each shard, and allow multiple concurrent queries. As a block diagram, it's going to look something like this: Next, borrowing heavily from Hermitage, we're going to run some SQL. begin; -- T0 create table test (id int primary key, value int); -- T0 insert into test (id, value) values (1, 10), (2, 20), (3, 30); -- T0 commit; -- T0 So far so good. We've inserted three rows into our database. Next, we're going to run two concurrent transactions (from two different connections, call them T1 and T2), like so: begin; -- T2 begin; -- T1 select * from test where id = 1; -- T1. A: We want this to show 1 => 10. update test set value = value + 2; -- T2 select * from test where id = 2; -- T1. B: We want this to show 2 => 20. commit; -- T2 select * from test where id = 3; -- T1. C: We want this to show 3 => 30. commit; -- T1 There's only one valid serializable1 ordering of these transactions: at line A, T1 has seen the world before T2 commits, and so must see that same pre-T2 world until it commits. Therefore T1 must happen before T2 in the serial order. How might we implement this requirement in our distributed architecture? We could use locking: T1 takes a shared lock on id = 1 at A, T2 blocks on it when trying to get an exclusive lock to update the row, and T1 can complete. There are two practical problems with this approach. First, we're blocking a writer on a reader, which reduces concurrency and throughput. Second, specific to our distributed architecture, T1 needs to take its lock in a single place where T2 needs to look for it. With multiple replicas, where this single place is is not obvious. That can be solved by choosing a primary replica, implementing a single lock manager, or by locking on all replicas2. In all three cases, read scalab