4.4.20 · D2Databases

Visual walkthrough — Optimistic vs pessimistic concurrency control

2,723 words12 min readBack to topic

We will need exactly three plain-language quantities. Let's meet them slowly, one picture at a time.


Step 1 — What is a "conflict", and what is ?

WHAT. Two transactions run at the same time. Sometimes they touch the same piece of data in a clashing way — one writes what the other is about to read or write. That clash is a conflict. Out of many transactions, some fraction of them hit a conflict. Call that fraction .

WHY this number and not another. The entire choice between the two philosophies turns on how often clashes actually happen. If clashes are rare, paying to prevent them is wasteful. If clashes are constant, paying to clean up after them is ruinous. So the rate of clashing — — is the axis the whole decision lives on. Nothing else captures "how contested is this data?" in one dial.

PICTURE. Below, imagine 100 transactions as dots. Green dots sail through untouched; magenta dots hit a conflict. is simply the magenta fraction. Slide the fraction from left (calm) to right (chaos) and you are sliding from to .


Step 2 — The pessimistic cost: you always pay

WHAT. Pessimistic control (see Two-Phase Locking (2PL)) grabs a lock before doing work. Acquiring the lock, holding it, and releasing it all cost time. Call that whole overhead (for Lock). (Remember from the model note: this is the extra overhead on top of the base work, which both schemes share.)

WHY it is a flat line. Here is the crucial feature: a pessimistic transaction locks whether or not anyone else was around. It cannot know in advance if a conflict was coming, so it defends every single time. The cost does not depend on at all.

PICTURE. On a graph of cost (up) versus conflict rate (right), the pessimistic cost is a perfectly horizontal orange line at height . It does not care what is.


Step 3 — The optimistic cost: pay only when you fail

WHAT. Optimistic control (see MVCC and Compare-and-Swap (CAS)) does its work with no locks, then checks at the end "did anything I read change?" If yes, it throws the work away and re-does it. Each such re-do costs (for Retry).

WHY there is no flat charge. When there's no conflict — probability — the optimistic transaction pays essentially nothing extra; its cheap version-check passes and it commits. It only pays the extra when it conflicts, which happens with probability . So its overhead scales with , unlike the flat pessimistic line.

PICTURE. A single transaction: with probability it commits (extra cost ), with probability it must retry (cost , then it tries again). This is a two-branch fork.


Step 4 — Why a retry can itself fail: the geometric series

WHAT. A retry is just another optimistic attempt. It, too, can hit a conflict. So we might retry, and retry, and retry. We need to add up the cost of all possible retry chains.

WHY a series and not a single term. If we only counted "one retry", we'd undercount the pain of high contention. The honest picture is a chain: fail (prob ) → retry → fail again (prob , independent) → retry again… Each extra failure multiplies another independent factor of .

PICTURE. Stack the shrinking rectangles — each a fraction of the one before. They pile up to the finite height . Watch how the pile explodes upward as approaches .


Step 5 — Race the two curves: find where they cross

WHAT. We now have both costs on the same axes:

  • Pessimistic: flat line at .
  • Optimistic: rising curve , starting at and shooting to infinity.

Optimistic wins wherever its curve sits below the flat line.

WHY they must cross exactly once. At the optimistic curve is at (below ) and the pessimistic line is at — optimistic wins. As the optimistic curve rockets past to infinity — pessimistic wins. Crucially the optimistic curve is strictly increasing (monotonic) in : differentiating, for all , so the curve never dips back down. A curve that starts below the line, ends above it, and only ever rises must cross the flat line exactly once. That crossing point is the break-even .


Step 6 — Solve for the crossing: the master inequality

WHAT. Set the two costs equal and solve for .

WHY this form is beautiful. The right side depends only on your cost ratio, not on . It's a fixed line in the sand you can compute once for your system. Then you just ask "is my measured left of it?"

PICTURE. The crossing point projected straight down onto the -axis is . Left of it: optimistic zone. Right of it: pessimistic zone.


Step 7 — The edge cases (never leave the reader stranded)

Every honest derivation must survive its extremes. Here are the four corners.

PICTURE. The two extreme thresholds — pushing to the far right (all-optimistic world) and pinning at the far left (all-pessimistic world) — bracket every real system in between.


Step 8 — Plug in real numbers (Example 2, visualised)

WHAT. Take the parent's numbers: ms, ms.

PICTURE. The threshold at splits the axis. Our two workloads land on opposite sides, and their vertical distance to the pessimistic line shows how much each strategy wins by.


The one-picture summary

Everything above collapses into a single graph: the flat pessimistic line, the exploding optimistic curve, their one crossing at , and the two zones. If you memorise one image from this whole topic, memorise this one.

Recall Feynman retelling — say it to a 12-year-old

Two ways to share one toy. Grab-and-lock (pessimistic): you always pay a little "wait in line" tax, even if nobody else wanted the toy — that's the flat cost . Play-then-check (optimistic): you play freely and pay nothing extra… unless someone else grabbed the same toy first, and then you have to start over — that's the retry cost , and it hurts more the more crowded it gets. (Both ways include the same time to actually play with the toy, plus the same quick "is it still free?" glance — we don't count those, since they're identical either way; we only count the sharing tax.) How crowded is it? That's , and we assume the crowd is evenly mixed so everyone faces the same chance. When the playground is nearly empty ( small), play-then-check is a steal. When it's a mosh pit ( near 1), starting over again and again ( blowing up, because each fresh try is just as likely to clash) is torture — grab-and-lock wins. The exact tipping point is where "always paying " costs the same as "sometimes paying ": that's . Left of it, be optimistic; right of it, be pessimistic. That single line in the sand is the entire chapter.

Recall Quick self-test

What does the symbol mean? ::: The expected (long-run average) cost — each possible cost times its probability, summed. What does measure, and what workload assumption makes it a single number? ::: The probability one transaction conflicts with at least one other; it assumes a uniform workload where transactions overlap at random so all face the same clash chance. What cost does our model count, and what does it ignore? ::: It counts only the extra concurrency overhead (lock cost , retry cost ) and ignores the base execution cost and the cheap constant validation check, both identical for both schemes. What assumption lets us write the retries as ? ::: Each attempt conflicts independently with the same probability , so "fail then fail again" multiplies to . Where does come from? ::: Summing the geometric series of independent retry chains; it's the average number of wasted retries. Why does the optimistic curve cross the flat line only once? ::: It is strictly increasing (its derivative ), starts below the line and ends above it, so it crosses exactly once. What is the break-even threshold? ::: — go optimistic when measured is below it. What happens to OCC as ? ::: The cost : endless retry storms (livelock), so pessimistic wins. With , , what is ? ::: .

See also: ACID properties · Serializability and Isolation Levels · Write Skew and Phantoms · Deadlocks