What Amdahl's law tells you, and what it refuses to tell you
Amdahl's law answers one question: if you hold a job's size constant and give it more processors, how much faster does it finish? Gene Amdahl posed it in 1967 as an argument against building ever-wider parallel machines, and the arithmetic is unchanged since.
Split the single-processor runtime into two parts. A fraction p can be spread across workers. The remaining fraction 1 − p cannot: it is the sequential set-up, the file read that must complete before the loop starts, the final reduction that combines everyone's answer. Give the parallel part N workers and it takes p/N of the original time. The serial part still takes 1 − p. Total time becomes (1 − p) + p/N, and speedup is the reciprocal of that.
The consequence is severe and it is the reason the law is famous. As N grows without bound, p/N vanishes and the runtime converges on the serial fraction alone. A program that is 90% parallel can never run more than ten times faster, on ten cores or ten million. At 95% the ceiling is 20×; at 99% it is 100×. The serial fraction, not the hardware budget, sets the limit.
What the law does not model is everything that makes real parallel programs slow: message passing, cache-line contention, lock convoys, load imbalance, NUMA effects and the memory bandwidth that all the cores share. Every one of those pushes measured speedup below this number. Treat the output as a ceiling you approach, never as a target you exceed. If you need to size the machine rather than the algorithm, the server vCPU sizing calculator works from throughput and utilisation instead.
Reading the formula term by term
Write the parallel runtime as a fraction of the original: T(N) = (1 − p) + p/N, with T(1) = 1. Speedup is T(1)/T(N), which is why the formula is one over that sum.
p is measured in time, not in code. This is the single most common mistake. If 95% of your source lines sit inside a parallel loop but that loop only accounts for 60% of the runtime, then p = 0.60 and your ceiling is 2.5×, not 20×. Profile the serial version, total the wall-clock time spent inside the regions you intend to parallelise, and divide by total runtime.
p/N assumes perfect division. The formula gives every worker exactly 1/N of the parallel work with no communication cost. That is an idealisation you should consciously discount: with 16 workers and one chunk that takes twice as long as the others, your effective N is closer to 8.
The denominator never falls below 1 − p. That single fact generates the whole ceiling. Doubling cores from 512 to 1,024 at p = 0.99 moves the denominator from 0.011934 to 0.010967 — a 4% gain in return for twice the hardware.
Parallel efficiency is S(N)/N, expressed as a percent. It is the share of a perfect linear speedup you actually get, and equivalently the fraction of each processor's capacity doing useful work. At p < 1 it falls monotonically as you add processors, which is what makes the cost question sharp: you pay linearly for cores and get sub-linear speed.
Worked example: 90% parallel code on 8 cores
A batch job takes 60 seconds on one core. Profiling shows 54 seconds inside a loop you can parallelise and 6 seconds of serial set-up and output, so p = 54/60 = 0.90. You have an 8-core machine.
- Serial fraction. 1 − p = 1 − 0.90 = 0.10.
- Parallel work per core. p ÷ N = 0.90 ÷ 8 = 0.1125.
- Denominator. 0.10 + 0.1125 = 0.2125.
- Speedup. 1 ÷ 0.2125 = 4.7059×.
- Runtime. 60 s ÷ 4.7059 = 12.75 s. Check it directly: 6 s serial + 54/8 = 6.75 s parallel = 12.75 s. The two agree, as they must.
- Efficiency. 4.7059 ÷ 8 = 58.82%. Eight cores are delivering the work of 4.7.
- Ceiling. 1 ÷ 0.10 = 10×. Even an infinite machine finishes this job in 6 seconds, because the serial 6 seconds never shrinks.
Now ask what a 5× speedup costs. Rearranging, N = p ÷ (1/S − (1 − p)) = 0.90 ÷ (0.20 − 0.10) = 0.90 ÷ 0.10 = 9 cores. So 8 cores buy 4.71× and 9 buy exactly 5×. Push to 8× and the same formula gives 0.90 ÷ (0.125 − 0.10) = 36 cores: four times the hardware for a 1.7× further gain. That collapse in marginal return is the practical content of the law.
Finally, Gustafson's view of the same numbers: (1 − p) + p·N = 0.10 + 0.90 × 8 = 7.3×. That figure answers a different question — see the section below.
How to read the speedup and the efficiency
Read the two numbers together. Speedup tells you how much sooner the job finishes; efficiency tells you how much of the hardware you are wasting to get there.
Efficiency above roughly 75% is the region where adding cores is still clearly worth the money: you keep most of each new processor. Between 40% and 75% the decision turns on whether wall-clock time is worth more to you than the machine. Below 40%, more than half of every core you buy is producing nothing, and the honest move is usually to attack the serial fraction instead of the core count.
The ceiling is the number to quote in a design review. It is fixed by the code, not the budget, and it is the strongest argument you have for spending engineering time on the sequential part. Cutting the serial fraction from 10% to 5% doubles the ceiling from 10× to 20×; buying twice as many cores at p = 0.90 takes you from 4.71× to 6.40×, and never past 10×.
Watch for a specific failure mode: measured speedup that flattens well short of the predicted curve, or falls as you add workers. Amdahl's curve is monotonically increasing, so a measured decline is proof of an overhead the model omits — usually synchronisation or memory bandwidth. When that happens, fit the Karp–Flatt metric described below rather than adjusting p by eye.
Speedup also interacts with queueing. If your job is one of many in a pipeline, halving its service time does not halve end-to-end latency; the Little's law concurrency calculator shows why, and the cache hit ratio and AMAT calculator covers the memory-side ceiling that often shows up first.
Speedup ceiling and attained speedup by parallel fraction
| Parallel fraction p | 8 cores | 64 cores | 1,024 cores | Ceiling |
|---|---|---|---|---|
| 50% | 1.78× | 1.97× | 2.00× | 2× |
| 75% | 2.91× | 3.82× | 3.99× | 4× |
| 90% | 4.71× | 8.77× | 9.91× | 10× |
| 95% | 5.93× | 15.42× | 19.64× | 20× |
| 99% | 7.48× | 39.26× | 91.18× | 100× |
| 99.9% | 7.94× | 60.21× | 506.18× | 1,000× |
Read down a column to see how little the hardware matters, and across a row to see how much the serial fraction does. At 1,024 cores, moving p from 90% to 99% buys 9.2× more speed; moving from 8 to 1,024 cores at p = 90% buys 2.1×.
Gustafson's law: the same algebra, a different question
John Gustafson published a rebuttal in 1988 after his team measured speedups above 1,000 on a 1,024-processor hypercube — a result Amdahl's law appears to forbid. The resolution is that nobody runs the same small problem on a bigger machine. They run a bigger problem.
Gustafson fixes the parallel runtime rather than the total serial runtime. If a job on N processors spends fraction 1 − p of its time serial and p parallel, then doing the same work on one processor would take (1 − p) + p·N times as long. That is the scaled speedup, and it grows linearly in N with slope p, with no ceiling at all.
Neither law is wrong; they measure different experiments. Use Amdahl when the workload is fixed and you want a given job finished sooner — a nightly batch that must clear by 06:00, a compile, a single query. Use Gustafson when more hardware means a finer mesh, a longer simulation, more documents indexed, or a larger training run — the case where you buy capability rather than latency. In the worked example above, the same 90%/8-core inputs give 4.71× under Amdahl and 7.3× under Gustafson, and both are true statements about different questions.
A third tool closes the loop. The Karp–Flatt metric (1990) inverts Amdahl to recover the serial fraction from a measurement: e = (1/S − 1/N) ÷ (1 − 1/N). Compute e at several processor counts. If it stays constant, the serial fraction is the whole story and Amdahl's prediction should hold. If e climbs with N, you are paying a parallel overhead that grows with the worker count — communication or synchronisation — and no amount of extra hardware will help until you fix it.
Mistakes that make an Amdahl estimate useless
- Estimating p from lines of code. The fraction is a share of runtime. A ten-line loop can be 98% of the time; a 500-line initialiser can be 40%. Profile first.
- Forgetting that I/O is serial. Reading the input file, writing the result, committing to a database and logging are usually sequential and often dominate on short jobs.
- Counting hyperthreads as cores. Two hardware threads on one physical core share execution units. For compute-bound work, use physical cores; for latency-bound work with lots of stalls, the extra threads help but not by a factor of two.
- Treating the answer as a prediction. It is an upper bound with communication cost set to zero. Measured speedup at 64 workers is routinely well below the curve.
- Ignoring the memory wall. Cores on one socket share cache and DRAM bandwidth. A memory-bound kernel can stop scaling at 8 threads on a 64-core part regardless of p.
- Quoting Gustafson speedup as if it were Amdahl speedup. They answer different questions and Gustafson's number is the larger of the two whenever N > 1 and p > 0. Always say which one you mean.
- Assuming p is a constant. Parallel efficiency often changes with problem size, because the serial set-up cost is fixed while the parallel work grows. Measure p at the size you actually run.
Where these laws come from
Gene Amdahl stated the argument in a 1967 AFIPS paper, Validity of the single processor approach to achieving large scale computing capabilities. He gave no formula in the modern algebraic form; the expression now called Amdahl's law was distilled from his argument by later authors and appears in that form in Hennessy and Patterson's Computer Architecture: A Quantitative Approach, where it is generalised as the law of diminishing returns for any enhancement that applies to only part of a workload. John Gustafson's Reevaluating Amdahl's Law appeared in Communications of the ACM in 1988; Alan Karp and Horace Flatt's experimentally determined serial fraction followed in the same journal in 1990.
The general form: any speedup of any component
Amdahl's law is not really about processors. It is the arithmetic of improving part of a system, and the same expression covers every optimisation you will ever evaluate. Write f for the fraction of runtime the enhancement touches and k for the factor by which it speeds that fraction up; the overall speedup is 1/((1 − f) + f/k). Processors are the case k = N.
Read that way it becomes a triage rule. Making a component infinitely fast gives you at most 1/(1 − f), so before optimising anything, measure f and compute that bound. If a function is 12% of runtime, deleting it entirely buys 1.14×. Engineers routinely spend weeks on a 12% component because the profiler ranked it first, and then report a disappointing result the law predicted before they started.
The same reasoning applies to caches, where the fraction is the miss rate and the enhancement is the hit; to encoding and serialisation, where a wire-format change only touches the bytes on the network (see the base64 encoded size calculator); and to algorithmic work, where switching complexity class changes the runtime of one phase only. For that last case, pair this page with the Big-O operations and runtime estimator: it tells you how the parallel phase itself grows with the input, which is exactly the term Gustafson's scaling argument depends on.
Key terms
- Parallel fraction (p)
- The share of single-processor runtime spent in work that can be executed concurrently. Measured in time, not in code volume.
- Serial fraction (1 − p)
- The share that must execute sequentially. It sets the speedup ceiling and is the only part worth attacking once you are near that ceiling.
- Speedup
- Single-processor runtime divided by N-processor runtime for the same problem. Dimensionless, quoted with a ×.
- Parallel efficiency
- Speedup divided by processor count, as a percent. 100% means perfect linear scaling; it is the fraction of the hardware you are actually using.
- Strong scaling
- Fixed problem size, growing processor count — the regime Amdahl's law describes.
- Weak scaling
- Problem size grown in proportion to processor count so that work per processor stays constant — the regime Gustafson's law describes.
- Karp–Flatt metric
- The serial fraction inferred from a measured speedup: e = (1/S − 1/N)/(1 − 1/N). A rising e across processor counts indicates parallel overhead rather than inherent serial work.
