A team spent three months parallelising their data pipeline across 64 cores. The job got 8× faster. They expected more. The law predicted exactly 8×. They could have known before writing a single line of code.
Amdahl's Law is not a guideline or a rule of thumb. It is a hard mathematical ceiling. It tells you the maximum speedup your system can achieve — given how much of it is inherently serial. No engineering effort can exceed it.
The Formula
Gene Amdahl stated the law in 1967. The speedup achievable from parallelism is:
Speedup = 1 / (S + (1 - S) / N)
Where S is the fraction of the program that must run serially, and N is the number of processors.
If 10% of your program is serial (S = 0.10) and you add infinite processors, the maximum possible speedup is:
1 / (0.10 + 0/∞) = 1 / 0.10 = 10×
Ten times. Not 100×. Not 1000×. Ten times. No matter how many cores you add.
The Ceiling Table
The numbers make the constraint vivid:
| Serial Fraction | Max Speedup (any N) | Speedup at N=64 | Speedup at N=1024 |
|---|---|---|---|
| 50% | 2× | 1.97× | 2.00× |
| 25% | 4× | 3.76× | 3.99× |
| 10% | 10× | 8.65× | 9.91× |
| 5% | 20× | 15.8× | 19.7× |
| 1% | 100× | 53.7× | 91.1× |
The team in the opening hook had a 10% serial fraction. 64 cores. The formula gives 8.65×. They got 8×. Close enough to confirm the bottleneck was the serial code, not the hardware.
What "Serial Fraction" Means in Practice
Serial fraction is not a line count or a percentage of files. It is the work that cannot proceed until something else finishes.
Database writes are often serial. One record must commit before the next transaction can read it. If your pipeline writes to a single database at the end, that write is serial regardless of how many workers processed the data upstream.
Synchronisation points are serial. A barrier that waits for all workers to finish before proceeding stops the clock on all parallelism. Every join(), every await all(), every checkpoint is a serial moment.
Locks are serial. A global lock serialises every thread that touches the locked resource. The more contention, the higher the effective serial fraction.
Single-threaded coordination is serial. A queue with one coordinator, a pub-sub broker running on one node, a leader node that validates all writes — these become the bottleneck as the rest of the system scales.
N parallel workers Serial chokepoint
[Worker 1] ──┐
[Worker 2] ──┤
[Worker 3] ──┤──▶ [DB write] ──▶ [Result]
[Worker 4] ──┤ ▲
[Worker 5] ──┘ │
one connection,
one lock,
one serial fraction
Where Engineers Get Burned
Adding more servers to a database-bound system is the most common mistake. The application tier scales. The database does not. The database becomes the serial fraction. More application servers make the queue to the database longer — not the throughput higher.
Adding more workers to a queue with a single coordinator hits the coordinator ceiling. The workers are parallel. The coordinator is not. At some point the coordinator is saturated and the workers wait.
Adding more threads to code with a global lock is the subtlest trap. The code looks parallel. The profiler shows threads. But every thread acquires the global lock before doing its work. Effective parallelism is 1.
Gustafson's Law: A Different Lens
Gustafson's Law is the counter-argument. It says: if you scale the problem size alongside the hardware, the serial fraction matters less.
Instead of asking "how much faster can we solve the same problem?", ask "how much larger a problem can we solve in the same time?" With more hardware, you can process more data in the same window. The serial portion stays constant in absolute time while the parallel portion grows.
This is genuinely useful for batch processing, scientific simulation, and training large models. It does not apply when the problem size is fixed — a user waiting for a response, a transaction that must complete, a report that covers a defined date range.
Most production engineering problems have a fixed input. A checkout must process one order. A search must return results for one query. Gustafson does not rescue you there.
Measure Before You Buy
The practical implication is this: measure the serial fraction before adding hardware.
Profile your system under load. Find the parts that run sequentially. Find the locks, the serial writes, the global coordinators. Calculate the serial fraction. Then run the formula. That number is your ceiling.
If the ceiling is 4×, buying a 32-core machine instead of an 8-core machine will not help. Fix the serial bottleneck first. Halving the serial fraction typically yields more speedup than doubling the cores.
Option A: Double cores (8 → 16), S = 0.25
Speedup = 1 / (0.25 + 0.75/16) = 3.37×
Option B: Halve serial fraction (0.25 → 0.10), N = 8
Speedup = 1 / (0.10 + 0.90/8) = 5.56×
Same budget. Different result. Option B wins.
The serial fraction is where the leverage is. Hardware scales cheaply. Eliminating a serial bottleneck is often weeks of engineering work. But it is the only work that moves the ceiling.
You cannot parallelise your way out of a serial bottleneck.