Quickstart
Last updated
Hetscale’s own setup takes about 15 minutes in every case. What comes before it depends on where you start; the onboarding cases list the prerequisite work and the time for each starting point.
What you need
- A Hetzner Cloud project.
- A Hetzner Cloud Load Balancer with a health check on your application’s health endpoint, with TLS terminated at it and DNS pointed at it. Cloudflare Load Balancing as the balancer is planned; until it ships, a site behind the Cloudflare proxy puts a Hetzner load balancer behind the proxy.
- At least one server behind the load balancer, running a stateless workload: the database, sessions and uploads live outside the servers that will scale.
- A way to bring a fresh server up: a snapshot of an existing server, one Coolify deploys to included, or a webhook to your CI.
Without a load balancer, onboarding gives you a “get load-balancer-ready” checklist first. Hetscale does not create the load balancer for you.
1. Connect read-only
Create a Hetzner API token with Read permission for the project and connect it under Projects → Connect a project (Connect a project). Then start the 14-day Observe trial from the project’s Groups tab with Start observing (Start observing). Hetzner tokens have exactly two levels, Read and Read & Write; a Read token cannot create, change or delete anything, and that is enforced by Hetzner, not by Hetscale.
Onboarding reads the project first: whether there is a load balancer and how many servers stand behind it. Then it asks what no read can show: what runs on the server, where the database is, how you deploy, and whether the domain is behind the Cloudflare proxy, two apps run on two servers or traffic comes in campaigns you know in advance. The answers map to a case with a fit score and a time estimate.
2. Read the day-0 report
Minutes after you start observing, Hetscale reads the last 30 days of metrics for the servers behind your load balancer and writes the report: how many times more capacity was needed than was available, an estimated node range with a confidence label, the extra cost as a range, the signals it used and the ones it cannot see, days with CPU pinned at 100%, and a recommended policy labelled “default”. For 14 days it then records every decision it would have taken live, prefixed “would”.
3. Choose the adapter and run one Rehearsal
The adapter is how a new node gets your application:
- Snapshot: Hetscale takes a snapshot of the server you point it at (the seed) and records it
as release v1. New nodes boot from it; your restart policies bring the containers up. The
snapshot contains everything on the seed’s disk, including
.envfiles, and stays in your project until you delete it: the group’s Deployment page deletes the snapshots no release or server needs, keeping the current release and the two before it (How do I delete old snapshots?). - Webhook: new nodes boot from the same snapshot of the seed. Hetscale sends a signed
node.createdevent with the node’s IPs; your pipeline deploys your current release to it and reportsready, and only then does Hetscale add the node to the load balancer. Afailedreport stops the node at once. The load balancer health check remains the final signal. - Coolify: your Coolify keeps deploying to the seed, and new nodes boot from a snapshot of it, as with Snapshot. Hetscale calls no Coolify API, holds no Coolify token, and Coolify never sees the new nodes. Coolify runs on another server, TLS ends at the load balancer, and you take a new release after each Coolify deployment: Coolify.
Going past Observe happens on the group’s Go Live page (Go Live) and needs a second, Read & Write token: Connect Read & Write puts it in the project in place of the Read token, and one per Hetzner project serves every group in it. Two steps follow. Hetscale turns on delete protection for the servers and the load balancer you confirm. Then, for the first release, it checks the preflight, what it can read from Hetzner and five lines you declare about state on the disk, the database, cron and queue workers, starting on boot and the disk copy (a sixth when Coolify deploys the seed: Coolify runs on another server), and snapshots the seed, while it runs, as release v1.
From then on, except while a Rehearsal runs, SSH keys, on the Go Live page or the node group’s Deployment page, lets you pick which of the project’s public keys new servers get. It offers the keys the latest read of the project found, and Hetscale stores only their ids. None is added until you pick one. Without a key, Hetzner gives each new server an expired root password and mails it to your Hetzner account, one mail per server: the keys in your snapshot are still accepted, but every scripted SSH command as root is refused, and an interactive login as root first asks for that password and a new one. With at least one key picked, Hetzner sets no root password, so the keys in your snapshot and the ones you picked both work. A change reaches the next new server; servers already running keep what they have. If your webhook pipeline deploys over SSH as root, pick the keys before the Rehearsal, or its server refuses the deploy and the Rehearsal fails.
Then run one Rehearsal: Hetscale creates one node from the template, deploys through the adapter, waits for the load balancer health check, drains it and deletes it while you watch the timeline. Between its health check and its drain the node serves real requests. Success unlocks Live; failure produces a report with the failing step and never leaves a node behind, and a run with no route within an hour fails and removes its server.
4. Go Live with a floor of two
Set the range. A minimum of 2 gives zero-downtime healing: when one node fails, the other keeps serving while the replacement comes up. Start from the range the report suggests; the Max field at Go Live says the most it allows. It must cover your own servers, and it stays one below what your load balancer can still take, so that a replacement always finds a free target. Targets on the load balancer that are not the group’s servers, and a crowded private network, lower it further (Hetzner limits that shape a node group). Pick one of the three named policies; Balanced is the default. Moving back to a safer mode takes effect immediately.
Hetzner limits Primary IPs per account: a new account holds 10 across all its projects, IPv4 and IPv6 together, load balancers included. Every server Hetscale adds takes one Primary IP for each public address the seed has, so one or two, and the Max field at Go Live shows how many each new server takes and how many this project already uses. If your maximum needs more, ask Hetzner to raise the limit in the Console first; otherwise a create is refused, the group pauses and you get a mail. A seed without public addresses gives servers without them, which take nothing from the limit (Servers without public addresses). The other Hetzner limits a node group meets are on Hetzner limits that shape a node group.
The seed server stays an adopted, protected member: scale-in never selects it and healing never replaces it. You can promote it to a managed member later, explicitly, with a confirmation that states the consequences: you turn its delete protection off in the Hetzner Console, Hetscale renames it and adds its labels next to yours, and there is no way back. A seed Coolify, Forge or Ploi deploys is not offered for promotion: it is the only server the tool knows.