Skip to content

How it works, in full

The lifecycle of a GPU rental

A renter types one command and, eleven seconds later, has a shell on someone else's graphics card in Frankfurt. Between those two moments sit a placement decision, a challenge handshake, a relay hop and a meter that has already started charging.

01The request

A rental states what it needs, never where to go

The renter names a GPU model and a region, and says what they will pay. Choosing the machine is the control plane's job, and a request that named one would break the moment that machine went offline.

Both names come from a catalogue rather than free text. and a fixed list of GPU models, each keyed by code, so 7900xtx either resolves to a row or the request is rejected before it reaches placement. A typed-in model name would match nothing forever and fail as “no capacity”.

The rest of this page walks the same path the transcript above took, one step at a time. For the short version, the knowledge base answers the same questions one at a time.

requestedmatchedstartingrunningstoppingended
instances.state · one-way, left to right

02The fleet

Seven parts, and what each one is responsible for

Two runtimes over one database. Select any cluster, or any part standing on one, and the links it actually uses light up while everything more than one hop away recedes.

FIG 02 The fleet

RENTER CLIthe renter's own machineplacementisolationbillingCONTROL PLANEcp.kracht.ai, frankfurta100agentNODE-01eu-west, a1007900 xtxagentNODE-02eu-central, 7900 xtxHUBrelayh100agentNODE-03us-east, h100instancesusage_eventsledger_entriesPOSTGRESsupabase, one database

CONTROL PLANE / placement

Scores every node that could serve the request. Two callers can pass the same check in the same instant, so the winner is decided by a unique index in Postgres rather than by asking first. The loser retries and lands elsewhere, which is the correct outcome and not an error.

03Three shapes

The same fleet, carved three ways

One pool of hardware answers three different shapes of demand, and the difference is entirely in how much of a machine a rental is allowed to hold and for how long. The cards below are the same in all three views. Only the carving changes.

FIG 03 Three shapes

one rentera100a100node-01eu-west, 0 of 2 claimed7900 xtx7900 xtxnode-02eu-central, 1 of 2 claimedh100h100node-03us-east, 0 of 2 claimedwhat is billed60 of 360 card-seconds0s10s20s30s40s50s60snode-01 · card 0node-01 · card 1node-02 · card 0node-02 · card 1node-03 · card 0node-03 · card 1The whole bar is charged, busy or idle, because the card is held for the whole window.

Cloud GPU · one card, one renter, per second · 1 of 6 cards · 60 card-seconds of 360

A rental holds a single card on a single box for as long as it is running, and is billed to the microeuro every second it holds it. The renter gets a shell: one card scoped into the container, the other cards on that box still available to other renters.

04Placement

Scored, not queued

Every request is scored against every node that could serve it, and the winner is decided by a unique index in Postgres rather than by whichever process asked first.

FIG 04 Placement

pending requestsroutes on: gpu + regionrequestgpuregionmax €/hnode-01eu-west, a100rentalsnode-02eu-central, 7900xtxrentalsnode-03us-east, h100rentalsr_8f217900xtxeu-central€0.42r_c3d9a100eu-west€1.35r_a107h100us-east€2.90r_e4407900xtxeu-central€0.40r_8f217900xtxeu-central€0.42r_c3d9a100eu-west€1.35r_a107h100us-east€2.90r_e4407900xtxeu-central€0.40

placement · routes on gpu + region

Every request is scored against every node that could serve it. Two callers can pass the same check in the same instant, so the winner is decided by a unique index in Postgres rather than by whichever asked first. The loser retries and lands elsewhere, which is the correct outcome and not an error.

05The handshake

The secret never crosses the wire

The node agent has no inbound port and no certificate anyone signed. It proves itself the way a database driver does: a challenge out, a proof back, and the thing both sides hold stays where it is.

FIG 05 The handshake

node agentnode-02holds: enrolment secretcontrol planecp.kracht.aiholds: the same secrethello, node-02

1 of 4 · hello, node-02

The node agent opens the connection and names itself. It sends no secret, because anything it sent could be replayed by whoever was listening.

06The plan

Three states, and each adds a fact

The rental is rewritten twice before anything boots. You cannot scope a card before you know which machine, and you cannot freeze a price before you know whose.

FIG 06 The plan

instancesrequestedgpu_model7900xtxregioneu-centralmax_price_per_hour€0.42node_idnot yet knowndevicenot yet knownagreed_price_per_hournot yet knownstatenot yet known

Requested · 3 of 7 fields known

What the renter asked for, and nothing else. Naming a machine here would break the request the moment that machine went offline.

07Isolation

One card, and the edges around it

A rental is one card on a machine that is running other things, so the interesting question is not how the container is built but where its edges are. Everything below was checked by opening it.

FIG 07 Isolation

from a shell inside the rental4 of 8 openablePROVIDER BOX, NODE-02the machine this rental is one card ofthe rental's container✕card0card1renderD128card2card3/dev/kfdrental fshost filesystemprovider's sshdsession LANto the hubprovider's LANtheir other machines

8 things to test

what isolation is for, and what it is not · 4 of 8 openable

It keeps a rental off its neighbours: the other cards on that box, the host's filesystem, the provider's own daemons. It does not, and cannot, protect a renter from the person who owns the hardware. A provider has physical access to their own machine and no container changes that. Anything a renter needs kept from the host belongs in an encrypted volume they hold the key to, not in the isolation boundary.

provider hostprovider sshd:22session172.30.0.x · renderD128internethub10.93.0.0/16LAN10.0.0.0/8
routes from the session · the crosses are where iptables drops the packet

08Failure

When a node stops answering

Provider hardware is somebody's spare machine on a home connection, so the interesting case is the one where it disappears mid-rental. Powered on is not the signal. The heartbeat is.

FIG 08 Failure

node-02, heartbeat0s60s120s180s240s

heartbeating

Running normally, and it will keep running. Each beat bills ten seconds at the price frozen at match time. Pull the plug to stop them.

09Durability

A rental that outlives its machine

A snapshot is the volume plus its digest, and the restore has to work on a machine the first rental never touched, because the box it ran on has already gone back to its owner.

FIG 09 Durability

runningnode-02, eu-centralwrites/work/out.ckptsize2.4 GiBout.ckptsnapshotvolume frozen, copied outcapturedat t=41mdigestsha256 3f9a…c21dout.ckptgonenode-02 reclaimedcontainerdestroyedvolumereleasednothing survives hererestorednode-01, eu-westreads/work/out.ckptdigestsha256 3f9a…c21dout.ckpt

1 of 4 · running

A rental is a container with a volume. While it runs, that volume is a disk on somebody's box in Frankfurt, and nothing about it is portable.

10The meter

Per second, and never a float

Billing is per second, and per second is what makes the arithmetic dangerous: a week-long rental multiplies a rounding error by six hundred thousand ticks. The columns are numeric(16,6), the values arrive as strings, and they stay strings until they become a Decimal.

FIG 10 The meter

usage_eventsunique on (instance_id, seq)cumulative €, against elapsed rental time€0.039000 over 8m60s120s180s240s300s360s420s€0.0011€0.0200€0.0390

per second, to the microeuro · 36 accepted · 3 quiet stretches · 1 retry billed €0.000000

An illustrative window, derived once and held still. Each accepted heartbeat carries (instance_id, seq) and bills ten seconds at the price frozen at match time. Hover or tab to a ring on the board to see what happened there.

11Settlement

One split, and it has to add back

When the rental stops, the total is split once. The take rate is 15%, the arithmetic is on whole microeuros, and the two halves are required to reconstruct the whole.

FIG 11 Settlement

settlementtake rate: 15%provider85% €1.249500kracht15% €0.220500€1.249500

settlement · €1.249500 + €0.220500 = €1.470000

The split is integer arithmetic on whole microeuros and the remainder goes to the provider, so the two halves add back to the whole by construction rather than by rounding luck. No cent is lost on the way out.

ledger_entriessampleeur
charge-0.048167ik_7f3a91c2
provider_share+0.040942ik_7f3a91c2
charge-0.048167ik_9c114e0b
charge-0.048167ik_b2e07d55
provider_share+0.040942ik_b2e07d55

12Payouts

What a provider can actually withdraw

Settlement decides what a provider earned. What they can move to a bank account is a different number, and it is deliberately the smaller of two: card in with bank out is close enough to money transmission that a Netherlands entity should not be doing it by accident.

FIG 12 Payouts

billing.payable_balancethe lower of two boundsmin( €1,420.00, €1,420.00 ) = €1,420.00earnings less payouts€1,420.00bindsaccount balance€1,420.00bindspayable€1,420.00

Earned and untouched · payable €1,420.00 of €1,420.00 earned

Both bounds agree. Everything earned is still sitting there, so the whole of it is payable.