serversim
LearnSimulatorTemplatesPricing
…
…
Open menu
Learn↗Simulator↗Templates↗Pricing↗
My DocumentsDocs
Contents/Chapter 1616 / 16

Same work, four methods

Give the same work to four different methods — what changes, and by how much? The same 24 customers pass one counter four ways, with the time taken and the price paid written side by side.

See this first in FoundationsWhy does a busy server fall behind?→

These numbers are simulator output, not hand-written: one thread (chapter 7's world), pools of 4 and 64 (chapter 10), and the event loop (chapter 11), all under identical conditions.

① What to look at

Makespan is total time to finish all 24; switches counts context switches; memory is thread stacks; CPU busy is the fraction of time the core actually computed. One thread is dramatically slow, four is much better, and sixty-four buys no more speed while costing sixteen times the memory.

② So which do you pick?

Light per-request computation with very many connections favours the event loop on memory. Heavy computation, or unavoidable blocking libraries, strongly favours the thread pool — it survives the traps of chapters 13 and 14. The answer depends on the workload, not on taste.

③ What makespan alone hides

Makespan is the time to finish all twenty-four. But a user experiences only their own request. So in practice you look at the distribution of per-request latency. Requests that arrive early skip the queue and finish fast; later ones carry their queue time on top. Averages erase that difference, which is why the tail — p99 — is tracked separately.

④ Why 64 threads does not beat 4

Requests in flight equal throughput multiplied by response time. Throughput here is capped by the core. If the core is already saturated, more threads leave throughput unchanged and only raise the number of requests waiting — which shows up purely as longer response times. Nearly equal makespan at sixteen times the memory, in the table above, is exactly this effect.

⑤ How the choice is made in practice

Three questions. How much CPU does one request use — light computation with mostly waiting favours the event-loop family. Are there blocking libraries you cannot avoid — then a thread pool is safer. And can your team observe and debug the model — asynchronous code with broken stack traces bills you during incidents.

modelmakespanswitchesthread memoryCPU busy
Thread pool · 1192.0 tu01.025%
Thread pool · 465.8 tu454.073%
Thread pool · 6462.1 tu4764.077%
Event loop · 148.0 tu01.1100%

Try it in the simulator

  1. 1.Close out the series with the 'three-tier basics' preset. Move the client node's RPS from 1,000 (Spring CPU 63%) to 1,700 (CPU 99%, KPI panel p99 291ms) to 2,000 (queue-full, Success 89.2%) — every idea from this series (CPU, memory, threads, waiting) is stacked on that one slider.
  2. 2.MySQL, on the same mix, holds up to about 8,800 RPS — five times the app's ceiling. Only raising Spring's Instances to 6 finally pushes the MySQL card's CPU to 100%. Every chapter in this series lives inside these node cards.
Try it in the simulator →

Terms in this chapter

makespan
Total time to finish all the given work.
CPU utilization
Share of elapsed time the core spent computing.
Little law (L = λW)
In-flight = throughput × response time; the basis for sizing concurrency.
p99
The slowest one percent. The user experience an average hides.

Why it evolved this way

The four rows are not four different technologies but four answers to one question: what do you hold on to while waiting? One thread overlaps nothing — simplest and slowest. A pool attaches a whole stack to each wait: the code stays ordinary, and memory is the price. An event loop attaches nothing and merely registers with the kernel: almost no memory, provided everyone yields quickly. Coroutines and virtual threads keep that third answer while returning the code to the shape of the first. So this is not a performance comparison but a choice of cost structure — decided by what is expensive for your team and your service.

Choosing a model = choosing where the waiting lives, and what you pay for it.

← Previous

Chapter 15. How we got here — sixty years of evolution