What a cluster may buy for itself
On most platforms autoscaling is a switch. Once you turn it on, something you cannot see spends your money with nobody watching, and when the bill arrives the only record of why is a graph.
Flui has no such switch. Nothing on an installation buys a machine on its own until somebody writes down what a specific cluster may buy, where it must stop, and that it may act. That record is a scaling group, and this chapter explains how it is shaped.
The group is the consent
A scaling group is a resource on a cluster. A cluster can have more than one, for example one for general work and one for heavy jobs, because those two fleets differ in every field below.
A group says:
- Three bounds. A floor (
min), held now and always; a target (desired), where the fleet would like to sit; and a ceiling (max), as far as the urgent side may go right now. Being under the target buys nothing on its own. The fleet reaches it when the market allows, and returns to it after a burst. - Where it may buy: one or more regions. Several regions are what make “cheapest, anywhere” possible.
- What it may buy: machine shapes, in order of preference.
- A placement strategy:
cheapest,closest,roomiestoruniform. - A ceiling in money, a monthly figure. Optional on a manual group; an automatic group needs one above zero.
- A settle window: how long work must have been stuck before the group buys anything. Thirty seconds by default.
- Whether it may act.
provision: manualmeans the group decides and tells you.provision: automaticmeans it may go and buy, never past its money ceiling. This field is the consent.
Every cluster on a provider Flui buys from gets one manual group,
named default, holding the nodes it has. Nothing autoscales until
a person sets a group to automatic. There is no installation-wide
grant above it. A second ceiling outside the group would guard only
some of the ways money can be spent, and the group already carries
its own ceilings, in money and in nodes, where you can see them.
The consent needed is for acting without a person, and it is one
word on the group.
Removing a group takes no machine away. Where Flui buys a cluster’s
machines, the cluster’s last group cannot be removed, because its
nodes change through it. Set it to manual to stop it buying.
What the settle window is for
The thirty-second window makes sure the work is stuck rather than caught mid-placement: another workload shutting down, a node finishing a drain, the scheduler partway through. It has nothing to do with price. Once the window passes, the urgent side buys without holding out for a cheaper machine.
Three things do hold it back, and none of them is price:
- While one machine is on its way, nothing else is bought.
- A purchase the provider refuses as sold out pauses the group for ten minutes, then the next reading decides.
- Any other failed purchase holds the group until a person runs
flui scaling retry, so a broken purchase is not repeated every minute.
Two forces on one fleet
Two different pressures act on a fleet, and Flui keeps them apart.
Urgency. Work cannot be placed. Its clock is seconds and it never waits. It walks a ladder of fallbacks and takes the first rung that would work:
- the preferred shape, in the cluster’s own region;
- the preferred shape, in any region this group may buy in;
- anything that holds the work, in the cluster’s own region;
- anything that holds it, anywhere the group may buy.
“Anywhere” has one limit that no setting changes: a machine Flui buys has to join the cluster’s private network, so it can only land in a region that network reaches. Where the provider publishes live stock, Flui checks whether a shape is on sale with a fresh reading every few minutes instead of a cached result.
When no rung can be taken, the alarm names every machine on the list with its own reason (sold out and where, too small, over the ceiling), because the first choice alone is rarely the one a person can act on.
Opportunity. Patient growth toward the target when the market allows. Its clock is hours, and it works by waiting. Nobody is held up if it never fires. It also gives a machine back when the fleet has gone past its target, and replaces a stand-in that urgency bought in a hurry with the shape the group wanted.
Giving back has two conditions. Nothing is given back within ten minutes of a machine joining, because the load that called for it rarely leaves that fast, and a machine given back only to be bought again is paid for twice. And a machine is only given back if everything running on it fits on the machines that stay, so the work it holds always has somewhere to run.
The patient side also carries standing orders: a machine somebody
asked for by hand, bought when the market allows. An expand order
is a purchase that closes itself once the fleet reaches the target
it was written for. A replace order is a purchase plus the
draining of a named machine, with both nodes running for a while.
The one rule where they meet
Urgency always wins, and opportunity stands down entirely while anything is waiting.
That includes when Flui cannot ask the cluster whether anything is waiting. A cluster that does not answer may still have waiting work, so the patient side stays down and nothing is decided.
One thing still holds while the cluster is silent: the floor. The floor comes from the fleet’s own records, not from a reading of the cluster. Otherwise an installation could drop below its floor exactly when its cluster is in trouble, which is when the floor matters most.
Why the ceiling is money
A limit of “at most six nodes” tells you little. Six of one shape and six of another are different bills.
So the ceiling a group carries is an amount of money per month, weighed against what the fleet already commits. A shape that would push the total past it loses, and the row says so with both figures in it.
Two details follow from that:
- Flui refuses only on certainty. A machine with no published price adds nothing to the committed figure, so clearing the ceiling does not prove the fleet is under it. Where the fleet is only partly priced, the decision states that the figure is a lower bound and not the bill, and counts the machines it could not price.
- On an automatic group, a machine with no published price is not bought automatically, because a ceiling cannot be enforced against an unknown amount. The machine is named in an alarm for a person instead.
A group can also refuse shapes billed only by the month. They make autoscaling cost-neutral at best, because you cannot give the machine back at the end of the hour.
How placement chooses among shapes that fit
The four strategies choose among the shapes that already fit.
A shape that cannot hold the waiting work is not a candidate. If
fitting were only a preference, cheapest could pick a shape that
helps nobody: the money is spent, the machine arrives, and the work
is still waiting. So fitting is a filter that runs first, and the
strategy only breaks the tie among the shapes left:
- cheapest: lowest price first;
- closest: the cluster’s own region first;
- roomiest: the largest machine first;
- uniform: keep the fleet one shape. This is the default when nobody chooses.
Before asking whether the waiting work fits, Flui subtracts what the system itself needs on every machine. A machine that holds the request only with nothing left over does not count as holding it.
Every decision is a row, including the ones that did nothing
The question people ask an autoscaler is almost always why it did not scale.
So a decline is written down in the same shape as a purchase: what
it saw, what it did, why, and what it still needs from a person,
along with every rung it skipped and the reason that rung lost.
flui scaling why prints them, for the whole cluster by default,
naming the group each decision came from. Declines are not filtered
out, because they are the answer the command exists to give.
The rows are updated in place rather than appended like a log. The same answer is rewritten when it changes, and once an hour otherwise, so you can see the loop is alive without the one useful row being buried under a thousand copies of “still nothing to do”.
flui scaling preview asks the same engine what it would do if a
machine were needed right now, without spending anything. It shows
the whole ladder, the room left on each machine (counted on what
apps reserve), and the largest app that still fits. Anything bigger
than that app makes the group buy.
Why refused-by-limit has its own name
One reason a shape can lose is named separately from the others:
refused-by-limit means the shape was available and affordable,
and this group’s own rules excluded it.
From the outside that looks the same as the provider having nothing to sell. Someone sees an empty result and goes looking for an outage, when the cause is a rule they wrote themselves: a ceiling already reached, a region their cluster’s network does not reach, a shape marked deprecated, or an hourly-billing-only rule against a provider that bills by the month. The separate name tells you that changing one of your own settings would allow the purchase.
For the same reason, the reasons are ordered by how close the rung came to buying, and the decision reports the nearest miss, since that is the one a person can act on.
How Flui learns what a provider can do
Flui never infers a provider’s capabilities from its name. It takes them from what that provider has declared, on three separate questions:
- Can Flui create a server here?
- Is there a catalogue, a list of shapes with prices attached?
- How is it billed: by the hour, by the month, or not visibly at all?
These are three separate flags rather than levels on one scale,
because a provider that publishes a price list but has no create
API needs a different outcome, addressed to a person. There,
deciding is all that happens: the group raises an alarm that names
the shape, the region and the price, and asks somebody to buy one
and join it with flui node connect. Where no catalogue exists at
all, the alarm says what a machine has to hold instead.
A provider Flui knows nothing about gets the most restrictive answer: it buys nothing, publishes nothing, and is billed for nothing anyone can see.
This is also why flui scaling list shows clusters that seem to
need no attention. A cluster with no scaling group at all, and a
cluster whose provider can only raise an alarm, are both listed.
Hiding them would report that all is well in the two cases where
somebody is needed.
Bounds count the whole fleet
Every bound counts the master too, so all three sit between 1 and
20. A group never describes an empty fleet. To stop a group acting,
set provision: manual.
The group is a file
A scaling group can be written as a kind: ScalingGroup
document. flui scaling export writes one and
flui scaling apply -f reads it back. --dry-run shows what
would be written without writing it. Several groups can live
in one file, separated by ---.
The file describes the whole group: a field left out is reset to its default, not left as it was. A reviewer reads the file that way, so the command does too, and applying the same file twice leaves the same group.
Only what a person wrote is exported. What the provider can do, and what the market is doing today, are read fresh every time, since they would be out of date as soon as the file was committed.
When an agent asks for this
Writing or changing a scaling group is one of the actions that stops and asks a person when an agent is the caller. The person agrees to a standing figure rather than a single machine: how large this cluster may become and how much money it may spend with nobody watching. The question shows that figure, not just the word “scaling”.
Where this chapter goes from here
- Nodes and cluster topology: the machines a group decides about, and attaching or resizing one by hand.
- The cluster as a concept: what a cluster owns, and where its scaling groups sit.
- How Flui works across providers: why buying, cataloguing and billing are three capabilities a provider can have or lack.