When Hetscale adds or removes a server
Last updated
Hetscale adds servers to a node group when one of its scale-out rules holds, such as the default CPU above 75% for 3 minutes, and removes one server when all of its scale-in rules hold, such as the default CPU below 35% for 10 minutes. Scale-in is always stricter than scale-out, and the rules are set per group.
What does Hetscale measure?
- CPU per server. Hetzner reports a server’s CPU as the sum over its vCPUs; Hetscale divides it by the number of vCPUs, so every server reads between 0 and 100% whatever its size. The group’s figure is the average over its servers.
- Requests per second per server. Your load balancer’s requests, divided by the servers that count, so a threshold stays valid at any group size. A load balancer without an HTTP service counts no requests.
- Open connections per server. Your load balancer’s open connections, divided the same way. The presets never use it: it is on only when you add a rule for it, with a threshold you choose. It needs a Hetzner Load Balancer.
The servers that count are those serving, past their warm-up and not leaving. A server on its way or still warming up already counts as capacity, but its metrics do not.
Your load balancer’s metrics are read every minute. Each server’s CPU is read every minute while the node groups of your Hetzner project hold up to 25 servers, every 2 minutes up to 50 servers and every 5 minutes above that, at one-minute resolution, so that polling stays inside Hetzner’s API budget, which is counted per project.
As of September 2026, Hetzner’s API reports CPU, disk and network for a server, and requests, connections and bandwidth for a load balancer. It reports no RAM, no latency and no error counts, so none of them can drive a decision.
When does it add servers?
When any one of the group’s scale-out rules holds for its whole window: every minute of the window above the threshold, not just the average. By default, that is CPU above 75% for 3 minutes.
It then works out how many servers the load needs. For each rule that holds, the servers that count times the window’s average, divided by the threshold and rounded up, is the number of servers needed; the largest of these, minus the servers the group already has or has on the way, is what it asks for. For example, four servers averaging 96% CPU need six to get below 75%, so it asks for two. The caps below decide how many start at once: the Balanced preset adds one server per 5 minutes, so the second is created five minutes after the first if the load still needs it.
What caps a scale-out:
- the group’s maximum;
- the most servers the policy may add within a window (“Max rate of change · servers added” … “Max rate of change · within”);
- the cost guard, the most servers the group may create within a window, whatever the reason, a healing included (“Cost guard · servers created” … “Cost guard · within”);
- the euro ceiling, if you set one.
When one of these holds back capacity the load needs, the group’s timeline records it with the numbers. Servers that are on their way or warming up count as capacity, so the next decision does not ask for them again, and there is no cooldown on scale-out: the policy decides once a minute per group. Before it creates a server, a scale-out takes back a server that was released and is waiting out its paid hour.
When does it remove a server?
When every one of the group’s scale-in rules holds for its whole window, with fresh metrics for every metric the rules name. By default, that is CPU below 35% for 10 minutes. Then:
- it removes one server per decision;
- only after the cooldown, a wait after any change to the group, whether a scale-out, a scale-in, a healing, a change of yours or a schedule, before a server is removed (“Wait after any change before removing a server”);
- only if the load, spread over the servers that would remain, stays below the scale-out threshold with a margin, for every metric that has a scale-out rule, so a removal never sets off the next scale-out.
It never removes the seed or any other server of yours: they count toward the minimum and the maximum and are never removed. A server in maintenance or already leaving is not chosen either. Which server leaves, and when in its paid hour, is on Removing a server without dropping requests.
What if metrics are missing or Hetzner limits requests?
It never scales in without fresh metrics. A rule is decided only when its window is measured: a reading for every minute, with one missed reading allowed, and the newest reading recent enough. Otherwise the direction the rule decides is held; missing data never causes an action. When only the servers’ CPU readings are missing, rules on your load balancer’s metrics still decide.
When a metric your rules read has had no reading in the last 3 minutes, the node group’s overview says so: which metrics, since when, and what that holds back. When none of the scale-out metrics can be read, no server is added or removed; otherwise rules on the metrics that can be read can still add a server, and none is removed while a scale-in rule reads a metric that cannot be read. The timeline records when Hetscale could no longer read them and when it read them again. Healing goes on, because it reads the load balancer’s health checks.
A rate-limit answer from Hetzner backs off and pauses decisions; it is never read as a missing server. Polling stops early enough to keep a reserve of the API budget for the calls that create, drain and delete servers.
Which presets are there, and what can I set?
The group’s Policy offers three presets, Balanced, Conservative and Aggressive, each with rules on CPU and on requests per second per server; the panel describes each one by when it adds and removes a server. Custom holds your own rules on CPU, requests per second or open connections per server: “Add a server when any of these holds” and “Remove a server when all of these hold”, each rule a metric, a threshold and a window. Every scale-in rule needs a scale-out rule on the same metric with a higher threshold and a shorter window; the settings refuse anything else.
The fifth choice, Target tracking, on Pro and Team, holds one metric at the value you pick instead of thresholds: How does target tracking work?.
Beside the policy you set:
- Min and Max: the group never runs fewer or more servers than these, your own included.
- Cooldown, “Wait after any change before removing a server”.
- Warm-up, “Warm-up of a new server”: the time after a new server starts serving during which it counts as capacity but its metrics are left out.
- The rate cap, “Max rate of change · servers added” within a window.
- The cost guard, “Cost guard · servers created” within a window.
- The euro ceiling, optional: once the servers Hetscale created this month have cost that much at list prices, it creates no more until the month ends, replacements included; running servers keep running.
The cooldown, the warm-up, the rate cap and the cost guard come with the preset, and the group’s settings show their values. Settings open once the group is Live, and a change applies from the next minute.
A node group keeps the values its preset had when it took it. If a preset’s numbers change later, the group’s Settings names the preset with the day of its values, such as “Balanced (values of 22 Sep 2026)”, lists what would change, and takes today’s values only when you switch that on and save.
Before you save, Preview under “Preview on the last 14 days”, below the policy on the Settings page of a Live or paused node group, replays the settings on the form and the saved ones, side by side, through the same engine on the load the group’s servers carried. Each figure is a range over two runs: scale-outs and scale-ins, the busiest point, the typical servers, server hours and the minutes above the scale-out threshold. A group younger than 14 days is replayed over the time it has. It is a simulation, a guide and not a forecast: it saves and changes nothing, shows no cost or savings, and does not replay schedules, healing, fallback types, the euro ceiling or your organisation’s node cap.
How does target tracking work?
On Pro and Team, Target tracking holds one metric at the value you pick. Choose it beside the presets on a node group’s Settings page or in the Go Live step, with its Metric and Target value:
- CPU per server (%), from 10 to 90;
- Requests per second per server or Open connections per server, from 1. Open connections are offered only where the load balancer reports them.
A node group holds one target. Then:
- Scale-out: the metric above the target for 3 minutes adds, in one decision, the servers that bring it back to the target. Four servers at 72% CPU with a target of 60% need five, so it asks for one. The rate cap, the cost guard and the maximum still apply.
- Scale-in: below 90% of the target for 10 minutes removes one server at a time, and only when the remaining servers would stay below 90% of the target. It never happens without fresh metrics.
- The cooldown, the warm-up, the rate cap and the cost guard are Balanced’s.
On a plan without target tracking, the choice is shown but cannot be picked. A node group that holds
a target keeps it if the plan changes, and its other settings can still be changed. Through the API,
PATCH /v1/groups/{id} takes "preset": "target" with a target block:
Manage node groups through the API.
Which settings for my kind of app?
Read the group’s day-0 report in Observe first. It replays your own last 30 days under the group’s policy and shows how much more capacity was needed, the server range at the busiest point, the extra cost as a range, the days with CPU pinned and the stock of your server type. That is the measured answer for your group, so this page gives no other numbers. Where to look, by kind of application:
- A web application or API whose CPU follows its load: the presets above, set up as in the load-balancer-ready case.
- An API whose requests rise before its CPU does, because it mostly waits on a database or another service: the rule on requests per second per server. Every preset has one, Custom sets its threshold, and Target tracking on Pro and Team can hold it at a value. The setup is in the managed-database case.
- WebSocket, SSE or other long connections: a rule on open connections per server, which the presets never use, and a longer “Drain window” (How long is the drain window?). The report’s details show the typical and peak open connections per server.
- Peaks you know in advance, such as a campaign or a newsletter: a schedule, on Pro and Team (Adding servers before a known peak, the campaign case).
- New servers your CI deploys: a “Readiness deadline” that covers the time a run waits in the queue plus the deploy (GitHub Actions, the CI case).
- A seed of a type Hetzner sells as limited, CX or CAX: a fallback mode (Can it use another server type?).
- An application that must keep serving while a server is replaced: a minimum of 2 (What happens with a minimum of one server?).
What does this not cover?
- Decisions on RAM or latency reported by an optional agent on your servers are planned.
- Hetscale reacts to load it has measured; it does not forecast load.
- Capacity for a peak you know in advance: Adding servers before a known peak.
- A sold-out server type: When your Hetzner server type is sold out.
- A server that fails: What happens when a server dies.
- How long a new server takes to take traffic: How fast is a scale-out.