A pool groups the nodes you request under one name. Every node you run in ORC8R belongs to a pool, and every node in a pool shares the same setup: the same provider, the same size and resources, and the same apps. Pools live inside a project, and you create them with the request wizard.

Requesting a pool

You create a pool by requesting nodes. From the Nodes page click New Request (or Request first node). The wizard walks you through five steps:

  1. Select a project — choose which project the pool belongs to. You can create a project here if you need one.
  2. Choose apps — pick any apps to install on the nodes. This is optional; if you skip it, nodes start with just the agent. See Authoring apps.
  3. Where to run — choose a provider (the infrastructure the nodes run on). After you pick one, the wizard shows the settings that provider offers, such as CPU, memory, and operating system. Fill these in to describe the machine you want. This set of settings is called the spec. See Providers. Where your ORC8R prices nodes, an Estimated price panel appears under those settings and follows what you choose.
  4. Name your pool — give the pool a name using lowercase letters, numbers, and dashes (for example, worker-pool-1).
  5. Submit — review your choices and click Create Pool.

A live preview on the right shows the request being built as you go. After you submit, ORC8R starts creating the nodes and you are taken to your new pool.

Reading a pool

On the Nodes page each pool is shown as a card, and the Pools list shows them in a table with columns for Pool, State, Provider, Size, Nodes, and Created. The Nodes column shows how many nodes are online out of the total. Click into a pool to see its resource specification, its nodes, and (for some providers) its pool image. The pool page's tabs take you from its Details to its Nodes, its Requests, and its Audit history.

Scaling a pool

Scaling means changing how many nodes a pool runs. For pools that ORC8R manages for you, you set the number you want and it adds or removes nodes to match.

  1. On the Nodes page, find the pool and click its Size badge.
  2. In the Resize dialog, use the + and − buttons, or type a number.
  3. Click Apply.

The dialog tells you how many nodes you have left within your organization's limit. Setting the size higher requests more nodes; setting it lower (including down to zero) removes nodes. If your organization's per-pool node limit is set to zero, adding nodes is disabled and an owner must raise the limit (see Organizations).

Where nodes are priced, the dialog also prices the change: the nodes you are adding, per hour, beside the hourly room your organization and project have left. It is an estimate and it never blocks the resize — see What a pool costs below.

Self-hosted pools work differently: you add machines to them yourself rather than setting a size (see Providers).

Pool images and baking

Some providers create nodes from a pool image — a ready-made snapshot of a fully set-up machine, so every node in the pool starts identical and boots quickly. Building that snapshot is called baking.

Here is what happens, and what you see:

  1. ORC8R first starts a single builder node and installs the pool's chosen apps on it.
  2. While this runs, the builder node shows an orange dot and the state baking. On the pool's Requests page, the Bake column links to the builder's logs so you can watch progress.
  3. When it finishes, ORC8R captures the result as the pool image. The pool's Pool Image panel then shows the image reference, the version it was baked for, its size, and when it became ready.
  4. Every other node in the pool boots from that baked image, so they all come up the same way.

If a provider does not use pool images, you will not see a Pool Image panel, and nodes are set up individually instead.

App data

Some apps keep data that has to outlive the node it runs on: a database directory, an upload folder, a working set you do not want to rebuild. The app declares those paths itself (see Authoring apps); the pool provides the disk they sit on and the storage their copies go to. Every node in the pool gets its own App data volume, and the pool's tier decides how large it is. You set the tier with the App data (GiB) field in the request wizard's Where to run step, which appears once one of the apps you have selected keeps data: leaving it at 0 gives each node 500 MB, and any other value gives that many gibibytes. You can change the tier later by reconfiguring the pool, but making it smaller is refused while a node's stored data would no longer fit.

The tier is a property of the pool, not of the provider you run it on, so in a request document or an API call it sits beside provider and spec as a top-level app_data_gib rather than inside the spec:

- pool: web
  provider: virt
  spec: { cpu: 2, mem: 4 }
  app_data_gib: 20
  apps: [acme/api]

Leave it out and the pool keeps the tier it already has — the same way leaving out apps keeps its assignments — so switching a pool's provider never resets the volume its data sits on. A pool that has never named a tier has the 500 MB volume. A size sent inside spec is refused: no provider publishes the key, and it is never stored in a spec.

The App data section of the Details tab reports:

  • Tier — the size of each node's volume, either 500 MB or the number of gigabytes the pool asked for.
  • Usage per slot — how full that node's volume was the last time the node measured it. Nodes measure about once an hour, so the figure trails reality by up to that long.
  • Latest restore point — the newest copy held for each slot and app, and when it was committed.
  • Keys — how many keys the pool's App data keyring holds. Copies are encrypted with the newest key; the earlier ones are kept so that older copies stay readable.
  • Stored — how much storage the pool's retained copies actually occupy.

The Rotate App data key button lives in this section; rotation is described under Restore points below.

Restore points

A restore point is a point-in-time capture of every persisting app's declared paths on one node's App data volume. The agent on that node takes it, encrypts it before it leaves the node, and stores it in the pool's own repository for that app — App data is kept one repository per pool and app, so each app's points are a list of their own. When a node is replaced — because you reconfigured the pool, rotated its key, or the node failed — the node that takes over the slot restores from the newest point held for that slot before its apps start. A slot is a node's stable identity within the pool, so data follows the slot rather than the machine.

Points are listed on the node that captured them: open a node and its Restore points tab lists that node's points, newest first and paginated, with the slot and app they belong to, the point id, its kind, when it was committed and how long ago that was, the number of files it holds, its size, a download link, and a Pull control that shows the command for fetching it with the orc CLI. A periodic point was taken while the app was running; a final point is the last one taken before its node went away. Older points are thinned out over time, and the newest point for a slot and app is kept for as long as the pool exists.

Points outlive the nodes that made them, and the node is the generation: a slot that has been through several nodes has its earlier points on those earlier nodes' pages, which stay readable after the node has ended. To see every point a pool holds in one list, ask the API for /api/orgs/{org}/projects/{proj}/pools/{pool}/restore-points/; every row of that listing (and of the node's own /api/nodes/{node}/restore-points/) carries the tag the point is published under and the full reference orc pull takes. Neither listing ever carries a key.

The two size figures measure different things, and they are not meant to agree:

  • The size on a row is what the producing agent declared for that point's contents — the plain data it captured on the node.
  • The Stored figure on the Details tab is what the pool's retained points occupy in storage, encrypted and deduplicated.

Points share their content — an unchanged file is stored once however many points refer to it — so the row sizes do not add up to the stored figure.

Downloading a point. The Download button on a row streams the point as a single archive named <pool>-<app>-slot<N>-<point>.tar.zst, holding the app's declared paths as they stood when the point was taken. The server opens the point with the pool's keys and builds the archive as it streams it; nothing is written to server disk. This is the one place where the platform handles your App data unencrypted, so the door is narrow: only organization owners and project owners may download a point — members and viewers cannot, whatever else they may do with the pool — and every download attempt is written to the organization's audit history, whether it was allowed or refused, before the first byte is sent. Downloads are also rate limited per user and pool, and a server builds only a few archives at a time; over either limit the request is refused with 429 Too Many Requests and a Retry-After telling you when to come back. Because a download is recorded before it is served, it is taken with the button rather than a plain link: the address itself answers a bookmark with 405 Method Not Allowed and points back at the tab.

Pulling a point. Every point is also pullable, whatever its size: the Pull control on a row reveals the one command that fetches it,

ORC_ENCRYPTION_KEY=<key> orc pull v0.orc8r.com/<org>/<project>/appdata-<pool>/<app>:<tag>

with the point's own reference and the keys that open it filled in, ready to copy. The keys ride the environment rather than the command line so they stay out of your shell history and out of ps; the same pull spelled with --key flags is offered underneath, for a shell that cannot set a variable inline. The <app> in it is the last part of the app's name, and the <tag> is when the point was taken and which slot took it, so a plain listing of an app's tags reads in order. orc pull fetches the sealed layers straight from the registry and decrypts them on your machine, so the control plane opens nothing and there is no size limit to hit. The <registry host> in the revealed command is this server's configured public web URL; on a server where that setting is empty it is whatever host name your own request arrived on, which behind a proxy that rewrites it may not be the name your machine can reach — set the public web URL and the command is right for everyone.

Pulling takes the same download_app_data permission as the download link: an App data repository answers only organization owners and project owners, and to anyone else — a member, a viewer, someone outside the organization — it answers as it would to a stranger, listing no tags and serving no manifest or blob. That the layers are encrypted is not the gate. Sealed bytes carried away today become the data the moment a key is obtained, and rotating the key cannot take them back, because a new key never re-seals layers already stored. If you cannot get the key, you cannot get the bytes.

A pool whose key has been rotated needs every key it holds, and the revealed command carries them all — comma separated, the key that sealed the point first. That is not belt and braces: points share their content, so a file unchanged since before the rotation is still stored as the layer that was sealed under the older key, and a pull given only the newest key fails on the first such layer with an authentication error naming it. The keys a rotated pool needs are exactly the ones the Pull control lists.

Either spelling works: the keys in ORC_ENCRYPTION_KEY — one or several, separated by commas — or --key repeated; the flags win over the variable if you give both, as a set rather than key by key. The point's own key is checked before anything is downloaded, so a wrong one costs a single request. By default the point lands as a directory tree named after its tag — the files, directories, symlinks, permissions and timestamps as they stood — in the directory you are standing in; -o <dir> puts it somewhere else, and --archive <file.tar.zst> writes the same single archive the download link produces. A pull that fails part-way leaves nothing behind rather than a tree that looks complete.

Revealing the keys is as sensitive as downloading the point, and is treated the same way: it takes that same download_app_data permission, so only organization owners and project owners see the control at all, and every reveal is written to the organization's audit history — as its own reveal_app_data_key decision naming every key id handed over, because what you were handed is not one point's contents but the pool's keys. Mind what they open: between them they open every point of the pool, and they keep doing so for as long as the pool holds them. A point whose own key has since been purged shows key no longer held instead of a command; there is nothing left that can open it.

A browser download is capped at 1 GiB of point contents. The archive is built on the control plane as it is sent, with no length known up front and no way to resume a broken transfer, so a bigger point belongs to the orc CLI, which reads the layers directly. A row over the cap offers its Pull control in place of the button — the control's help text says Over 1 GiB — download with the orc CLI, which is exactly what it hands you — and the download route answers 413 Payload Too Large before anything is opened, recorded, or spent. The cap is measured on what the point occupies in storage here, which the server verified when the point was committed, not on the size the row prints: that figure is the capturing agent's own account of the data, and a limit on what this server will spend cannot be set by the node it is spending it for.

Rotating the key. The Rotate App data key button appends a freshly minted key to the pool's keyring. Nothing is removed: existing points stay readable, downloadable and pullable under the key that sealed them, and new captures use the new key. Because the keyring is part of the pool's request, rotating commits a new request version, and that is a rolling replacement — every node in the pool is replaced one at a time, each new node restoring from its slot's newest restore point. Organization owners and project owners can rotate; a pool that runs no app keeping App data has no key to rotate.

What a pool costs

Where your ORC8R prices the nodes it runs, three places show you money, and all of them show the same number:

  • The request wizard estimates one node of the shape you are describing, per hour, broken down by what it charges for — compute, storage, an operating-system licence, network. The estimate follows your choices, including the apps you pick and the App-data size, because both change the disk a node is given.
  • The Resize dialog prices the nodes a resize would add.
  • A node's own page shows what that node is actually being charged, and every price it has been held at.

The first two are estimates. They reserve nothing, and the price a node is finally held at is the one its provider gives when the pool deploys it. Where the two differ, the node's own price is the one that counts.

If the price cannot be worked out — the provider is unreachable, or it says it has nothing to offer for that shape right now — the wizard says so and lets you submit anyway. Nothing is lost: the pool simply waits until it has a price before it deploys anything.

When a pool is waiting

A pool that is not creating the nodes you asked for says why on its card. Two of those reasons are about money:

  • Waiting for a price — no price could be obtained for the shape the pool asks for. The pool tries again by itself when the provider comes back or changes what it offers; there is nothing to do unless it persists, in which case the provider is the place to look.
  • Waiting for room in the hourly budget — the price is known, but your project's or your organization's hourly budget has no room for another node. The nodes already running stay running. The pool moves again when a node ends in that scope, or when an owner raises the budget (see Organizations).

One more waiting reason is worth knowing, and it is not about money:

  • Waiting for a reachable server address — the pool's nodes would be created outside your own network, and the address they were told to report back to is not one they could reach from there. An operator fixes it by setting the deployment's public web address; the pool moves again by itself once it is set.

Every other waiting reason is about capacity, images, or the network.

Managing a pool

A pool card's menu lets you pause or clean up a pool. You can Block a pool to stop it, Activate it again, Reject it, or Fork it (start a new request pre-filled from this one). A pool can only be deleted once it has been rejected, and deleting is permanent.

  • Nodes — the individual machines and their states.
  • Providers — where a pool's nodes run.
  • Projects — the workspace a pool belongs to.