Capacity

Size an app, pick Cap / Throttle / No throttle on the Node, meter it, and move it.

Capacity

An App of a Size runs on a Node. The Node has a CPU policy: Cap, Throttle, or No throttle. That is the whole model. Internal placement indexes still exist for packing and billing; they are not a third thing you have to name. Flipping the Node policy live-updates sized running apps; unslotted apps (no Size) are never touched.


The vocabulary

TermMeaning
SlotOne capped unit of capacity where a single workload lives.
RackA Node seen as its set of Slots ("this Rack has 20 Slots, 12 filled").
Workload / AppWhat fills a Slot.
FleetAll your Racks together; the Slot Board shows the whole fleet.

(Full definitions in Concepts.)


Slot sizes and what they actually enforce

When you deploy into a Slot, HostSSH enforces hard Docker resource caps on the container. Four sizes, each a multiple of the base envelope:

SizevCPUMemoryMax processes (PIDs)Multiple
s0.5512 MB2561×
m1.01 GB5122×
l2.02 GB10244×
xl4.04 GB20488×

These are enforced by --cpus, --memory, and --pids-limit on the container — a real isolation boundary, not a billing label. The same numbers are the single source of truth in the Agent (Go) and the control plane (TypeScript), and a drift guard fails the build if they ever diverge.

An unslotted deploy (no --slot-size) runs with no caps — fine for a box you own entirely. Use Slots when you're packing several apps onto one Node, or reselling capacity.

Buy Docker Space one Slot at a time from Billing or Pricing. Shared S is $3/mo; Reserved XL is $64/mo. Hard caps, daily encrypted backup, named volume you can move. Buying Space never changes your plan.


Slot classes: burstable vs reserved

Two classes make a deliberate trade between density and guaranteed performance:

  • Burstable — shared and oversubscribed, for workloads that are mostly idle (classic shared WordPress). Many Slots share the machine fairly, so a smaller box packs in a lot of them.
  • Reserved — a guaranteed slice, for production apps and databases. Each Slot gets a hard envelope so performance is predictable and billing is honest. Fewer Slots per box, but each is yours.

The platform recommends a Slot count for each Node from its CPU/RAM/disk (tunable per Rack). Roughly, a 4 vCPU / 8 GB box lands around 20 Slots and an 8 vCPU / 16 GB box around 50 — which is why two machines can offer different counts. The recommendation logic is recommendedSlotCapacity() in control-plane/web/lib/slots/types.ts.

Two numbers, two jobs — don't confuse them. The size caps above (0.5 vCPU / 512 MB for s, etc.) are what your container is actually limited to. Separately, to decide how many reserved Slots a box can hold, the platform reserves roughly 1 vCPU / 2 GB / 25 GB of planning headroom per reserved Slot — a capacity-planning/billing figure, not the per-container cap. You deploy against the size caps; the reserved envelope only sizes the board.


Deploying into a Slot (live)

Deploy-into-a-Slot is live. On the CLI:

$ hostssh deploy --name shop --source ./shop --slot rack1/3 --slot-size m

or pick a Size in the dashboard's Deploy drawer. What happens:

  1. The scheduler resolves a free Slot of the right size on the Node you chose (or bin-packs onto the first Rack with capacity).
  2. The deploy is created and the placement is recorded atomically — no orphaned Slots if something fails mid-flight.
  3. The container is tagged with its Slot (hostssh.slot=rack1/3) and launched with the size's caps.
  4. On success the App shows on the Slot Board as occupying that Slot. One workload per Slot — HostSSH refuses to double-book.

If a slotted deploy fails, the Slot is held (not silently freed) so you can inspect and retry or release it deliberately.


The Slot Board

The Slot Board at /slots shows your fleet the way you think about it: each Rack is a grid of Slots, filled ones colored by what they hold, empty ones open. You see at a glance how much capacity each Node has and how much is free. It reads live placement data (Postgres when connected, seeded in-memory otherwise).


Moving and metering

  • Move a Slot — capture one workload and restore it into a free Slot on another Node (a single-workload migration between machines).
  • Move a whole Rack — the same operation at its widest scope: drain every Slot off a Node onto others, then retire the box. This is how a full-server move or a machine-renewal migration is expressed.
  • Meter a Slot — size-weighted Slot units roll up per-Rack and fleet-wide into billable units and utilization, mapping onto plan tiers (burstable → shared, reserved → dedicated).

For the product rationale, reseller/MSP packaging, and how Slots map onto the codebase, see the Slots product spec.


Next steps