Traffic mixes & think time
A workload is two independent things: what each kind of request costs, and how much of your traffic is each kind. Keeping them separate is what lets one measurement pass be re-projected against a Black Friday mix without measuring anything again.
Think time
The number that most changes the answer, and the one most often left out.
Ten thousand concurrent visitors is not ten thousand concurrent requests. A visitor reading a page for ten seconds and then clicking is making 0.1 requests per second, so ten thousand of them offer roughly a thousand requests per second — and the difference between those two numbers is a factor of a hundred in the size of server you buy.
Heat models people, asks how long they pause, and derives the request rate, rather than quietly assuming the terrifying answer. It is worth arguing about: ten seconds is ordinary browsing, three is somebody hunting for something, thirty is somebody reading. Set it in Settings, or per run with --think=.
The five request kinds
| Scenario | What it is |
|---|---|
| Cached visitor page | Answered by a proxy, static cache or CDN edge. No worker, no connection, no query. |
| Rendered visitor page | Craft actually renders it. The baseline everything sits on. |
| Logged-in visitor | Session-bearing, so no shared full-page cache is usable. Structurally the expensive path, and usually where sites fall over. |
| Editor saving an entry (Pro) | The most expensive thing a Craft site does: validation, element and content rows, revisions, search index, structure, invalidation, and every plugin listening to all of it. |
| Queue job (Pro) | Modelled as traffic on purpose — with runQueueAutomatically it literally is. |
Cached and rendered are separate costs rather than one averaged one, because the ratio between them is usually the most valuable number in the whole report.
The four mixes
| Mix | Shape | For |
|---|---|---|
browsing |
70% cached, 20% rendered, 8% logged in | A settled site with a working cache and a trickle of editing |
launch |
25% cached, 65% rendered | The campaign lands and the cache is cold |
members |
68% logged in | Almost nothing cacheable, because almost everyone is signed in |
editorial |
20% saves, 10% queue, think time 4s | A team publishing hard, and a queue full of the work those saves created |
Plan for the launch mix
Sites do not fall over at their busiest hour. They fall over at their busiest hour with an empty cache — the campaign lands, and most of the traffic is arriving at pages nobody has requested yet. That is the case worth sizing for, and it is why the launch mix exists.
php craft heat/capacity --mix=launch
Editorial has a shorter think time
Somebody working in the control panel is not reading the page, they are filling it in. The gap between their requests is a fraction of a visitor’s, so the editorial mix uses four seconds rather than ten. Fifty editors are not fifty visitors.
Weights are relative
Not percentages. A mix of 90 cached, 10 rendered and 1 editor means what it looks like, and adding a fourth kind does not require rebalancing the other three. Heat normalises on use and reports the resulting shares in the assumptions.
What Lite models
Visitor traffic only — cached, rendered and logged-in. Editor and queue load are Pro. Lite therefore reports a higher ceiling than Pro on the same machine, because it is modelling less load rather than finding the load cheaper, and every screen says so rather than letting the number stand on its own.