Skip to content
About
Main content

Why concurrency is a different kind of problem

Why does ten times more throughput create a hundred times more conflict, and how should we think about correctness when many users act at once?

The failure mode changes

Think about the topics that come before concurrency in a database: how bytes sit on a disk, how rows are laid out, how data is encoded, how indexes find rows. All of them answer one question: "what does it cost to represent bytes and reach them?" You can read all of them as if the database had exactly one user. The way they go wrong is that the system is slow or expensive.

Concurrency control is the first topic where the number of actors is the subject, and the first where the failure mode is wrong, silently, and only sometimes. Two things change in a basic way.

Change 1: we judge a schedule, not a state

For storage questions you can point at bytes and ask whether they were laid out well. Here the thing being judged is a schedule: an ordering of operations taken from several transactions. A system is correct if every schedule it allows is equivalent to some (one transaction at a time).

You cannot look at a database state and tell whether its concurrency control is correct. The bug lives in a history, not in a state. That is why this topic resists the debugging habits that everything below it taught you: there is often nothing wrong to see in the data afterwards. Two produce a perfectly normal-looking balance. It is just the wrong normal-looking balance.

Change 2: the cost is combinatorial, not physical

A acquisition is one on a hash bucket, about 100 ns. A is one log write. Nothing here is expensive in the way a disk seek or a network shuffle is expensive. What is expensive is conflict. Conflict is a property of the workload and of how many transactions you insist on running at the same time. You cannot buy your way out with faster hardware, and that is new.


The arithmetic that governs this mechanism

This calculation is worth doing once, because everything later is built on it.

Step 1: how many transactions are in flight? says that to sustain an arrival rate λ when each transaction stays in the system for W seconds, you must have

RelationshipLittle's Law →
L
— average number of items inside the system (the concurrency)
λ
— arrival rate (items per second)
W
— average time an item stays in the system (residence time, including waiting)

transactions alive at the same moment. This is not a decision. It is an identity. Here it is a correctness constraint, not only a capacity one: the more transactions overlap, the more chances for them to disagree.

Step 2: how many conflicts? Suppose each of the L live transactions touches k items out of an effective of N items, and assume every item is equally likely.

  • Two given transactions each have k items, so the chance that they share at least one item is about k²/N (k × k pairs of items, each pair equal with probability 1/N, when this number is small).
  • There are about L²/2 pairs of live transactions.

So the expected number of conflicts at any moment is about

live transactions (Little's Law: arrival rate × duration)
items each transaction touches
the effective key space (skew shrinks it)
transactions per second and how long each holds its items
N = 10⁶ itemseffective N = 10⁴ (skewed keys)
Data table
Expected conflicts at any moment, by throughput (k = 10, W = 5 ms)
Throughput λ (transactions per second)seriesConflicts at any moment
1KN = 10⁶ items0.001
1.09KN = 10⁶ items0.001
1.19KN = 10⁶ items0.002
1.3KN = 10⁶ items0.002
1.41KN = 10⁶ items0.002
1.54KN = 10⁶ items0.003
1.68KN = 10⁶ items0.004
1.83KN = 10⁶ items0.004
2KN = 10⁶ items0.005
2.18KN = 10⁶ items0.006
2.37KN = 10⁶ items0.007
2.59KN = 10⁶ items0.008
2.82KN = 10⁶ items0.01
3.07KN = 10⁶ items0.012
3.35KN = 10⁶ items0.014
3.65KN = 10⁶ items0.017
3.98KN = 10⁶ items0.02
4.34KN = 10⁶ items0.024
4.73KN = 10⁶ items0.028
5.16KN = 10⁶ items0.033
5.62KN = 10⁶ items0.04
6.13KN = 10⁶ items0.047
6.68KN = 10⁶ items0.056
7.29KN = 10⁶ items0.066
7.94KN = 10⁶ items0.079
8.66KN = 10⁶ items0.094
9.44KN = 10⁶ items0.111
10.3KN = 10⁶ items0.132
11.2KN = 10⁶ items0.157
12.2KN = 10⁶ items0.187
13.3KN = 10⁶ items0.222
14.5KN = 10⁶ items0.264
15.8KN = 10⁶ items0.314
17.3KN = 10⁶ items0.373
18.8KN = 10⁶ items0.444
20.5KN = 10⁶ items0.527
22.4KN = 10⁶ items0.626
24.4KN = 10⁶ items0.745
26.6KN = 10⁶ items0.885
29KN = 10⁶ items1.05
31.6KN = 10⁶ items1.25
34.5KN = 10⁶ items1.49
37.6KN = 10⁶ items1.77
41KN = 10⁶ items2.1
44.7KN = 10⁶ items2.49
48.7KN = 10⁶ items2.96
53.1KN = 10⁶ items3.52
57.9KN = 10⁶ items4.19
63.1KN = 10⁶ items4.98
68.8KN = 10⁶ items5.91
75KN = 10⁶ items7.03
81.8KN = 10⁶ items8.35
89.1KN = 10⁶ items9.93
97.2KN = 10⁶ items11.8
106KN = 10⁶ items14
115KN = 10⁶ items16.7
126KN = 10⁶ items19.8
137KN = 10⁶ items23.5
150KN = 10⁶ items28
163KN = 10⁶ items33.3
178KN = 10⁶ items39.5
194KN = 10⁶ items47
211KN = 10⁶ items55.8
230KN = 10⁶ items66.4
251KN = 10⁶ items78.9
274KN = 10⁶ items93.7
299KN = 10⁶ items111
325KN = 10⁶ items132
355KN = 10⁶ items157
387KN = 10⁶ items187
422KN = 10⁶ items222
460KN = 10⁶ items264
501KN = 10⁶ items314
546KN = 10⁶ items373
596KN = 10⁶ items444
649KN = 10⁶ items527
708KN = 10⁶ items626
772KN = 10⁶ items745
841KN = 10⁶ items885
917KN = 10⁶ items1,050
1MN = 10⁶ items1,250
1Keffective N = 10⁴ (skewed keys)0.125
1.09Keffective N = 10⁴ (skewed keys)0.149
1.19Keffective N = 10⁴ (skewed keys)0.177
1.3Keffective N = 10⁴ (skewed keys)0.21
1.41Keffective N = 10⁴ (skewed keys)0.249
1.54Keffective N = 10⁴ (skewed keys)0.296
1.68Keffective N = 10⁴ (skewed keys)0.352
1.83Keffective N = 10⁴ (skewed keys)0.419
2Keffective N = 10⁴ (skewed keys)0.498
2.18Keffective N = 10⁴ (skewed keys)0.591
2.37Keffective N = 10⁴ (skewed keys)0.703
2.59Keffective N = 10⁴ (skewed keys)0.835
2.82Keffective N = 10⁴ (skewed keys)0.993
3.07Keffective N = 10⁴ (skewed keys)1.18
3.35Keffective N = 10⁴ (skewed keys)1.4
3.65Keffective N = 10⁴ (skewed keys)1.67
3.98Keffective N = 10⁴ (skewed keys)1.98
4.34Keffective N = 10⁴ (skewed keys)2.35
4.73Keffective N = 10⁴ (skewed keys)2.8
5.16Keffective N = 10⁴ (skewed keys)3.33
5.62Keffective N = 10⁴ (skewed keys)3.95
6.13Keffective N = 10⁴ (skewed keys)4.7
6.68Keffective N = 10⁴ (skewed keys)5.58
7.29Keffective N = 10⁴ (skewed keys)6.64
7.94Keffective N = 10⁴ (skewed keys)7.89
8.66Keffective N = 10⁴ (skewed keys)9.37
9.44Keffective N = 10⁴ (skewed keys)11.1
10.3Keffective N = 10⁴ (skewed keys)13.2
11.2Keffective N = 10⁴ (skewed keys)15.7
12.2Keffective N = 10⁴ (skewed keys)18.7
13.3Keffective N = 10⁴ (skewed keys)22.2
14.5Keffective N = 10⁴ (skewed keys)26.4
15.8Keffective N = 10⁴ (skewed keys)31.4
17.3Keffective N = 10⁴ (skewed keys)37.3
18.8Keffective N = 10⁴ (skewed keys)44.4
20.5Keffective N = 10⁴ (skewed keys)52.7
22.4Keffective N = 10⁴ (skewed keys)62.6
24.4Keffective N = 10⁴ (skewed keys)74.5
26.6Keffective N = 10⁴ (skewed keys)88.5
29Keffective N = 10⁴ (skewed keys)105
31.6Keffective N = 10⁴ (skewed keys)125
34.5Keffective N = 10⁴ (skewed keys)149
37.6Keffective N = 10⁴ (skewed keys)177
41Keffective N = 10⁴ (skewed keys)210
44.7Keffective N = 10⁴ (skewed keys)249
48.7Keffective N = 10⁴ (skewed keys)296
53.1Keffective N = 10⁴ (skewed keys)352
57.9Keffective N = 10⁴ (skewed keys)419
63.1Keffective N = 10⁴ (skewed keys)498
68.8Keffective N = 10⁴ (skewed keys)591
75Keffective N = 10⁴ (skewed keys)703
81.8Keffective N = 10⁴ (skewed keys)835
89.1Keffective N = 10⁴ (skewed keys)993
97.2Keffective N = 10⁴ (skewed keys)1,180
106Keffective N = 10⁴ (skewed keys)1,400
115Keffective N = 10⁴ (skewed keys)1,670
126Keffective N = 10⁴ (skewed keys)1,980
137Keffective N = 10⁴ (skewed keys)2,350
150Keffective N = 10⁴ (skewed keys)2,800
163Keffective N = 10⁴ (skewed keys)3,330
178Keffective N = 10⁴ (skewed keys)3,950
194Keffective N = 10⁴ (skewed keys)4,700
211Keffective N = 10⁴ (skewed keys)5,580
230Keffective N = 10⁴ (skewed keys)6,640
251Keffective N = 10⁴ (skewed keys)7,890
274Keffective N = 10⁴ (skewed keys)9,370
299Keffective N = 10⁴ (skewed keys)11.1K
325Keffective N = 10⁴ (skewed keys)13.2K
355Keffective N = 10⁴ (skewed keys)15.7K
387Keffective N = 10⁴ (skewed keys)18.7K
422Keffective N = 10⁴ (skewed keys)22.2K
460Keffective N = 10⁴ (skewed keys)26.4K
501Keffective N = 10⁴ (skewed keys)31.4K
546Keffective N = 10⁴ (skewed keys)37.3K
596Keffective N = 10⁴ (skewed keys)44.4K
649Keffective N = 10⁴ (skewed keys)52.7K
708Keffective N = 10⁴ (skewed keys)62.6K
772Keffective N = 10⁴ (skewed keys)74.5K
841Keffective N = 10⁴ (skewed keys)88.5K
917Keffective N = 10⁴ (skewed keys)105K
1Meffective N = 10⁴ (skewed keys)125K

Useful work rises in a straight line. Conflict rises with the square. The two lines cross, and that crossing is why the throughput curve of every transactional system turns over (it goes up, peaks and then falls) instead of flattening.

This is exactly what Tomas saw. Going from 800 to 8,000 orders per second multiplied the number of transactions in flight by ten and the number of colliding pairs by about a hundred.

The same square appears elsewhere

This quadratic is not new. In scalability theory (the Universal Scalability Law) there is a "coherency" term that grows as N(N−1): the cost of every worker needing to agree with every other worker. You may know it from false sharing (several CPU cores fighting for one cache line) and from incast (many servers answering one server at the same time). For transactions the pairwise term is literal, not an analogy: its coefficient is the probability that two concurrent actors touch the same item.

The assumption nobody can check: uniform access

The formula needs N, and this is the assumption the whole topic makes and cannot verify. The arithmetic above assumes every item is equally likely to be touched. Real access patterns are skewed (statisticians say Zipfian: a few keys get most of the traffic). So the is not the number of rows you store. It is smaller, often by two or three orders of magnitude (100 to 1,000 times).

Who pays? The , the popular account, the one partition that every writer touches on the hour. For Kestrel: 50,000 seats exist, but if 90% of buyers want 200 floor seats, the effective N for most buyers is closer to 200 than to 50,000.