Guides

Scaling and RAM

Scale a project's RAM up or down in seconds, pay by the hour for what runs, and scale out the stateless tiers — how sizing works on nyxory.

Scaling on nyxory is a live dial, not a support ticket. Set a project’s RAM up or down in 256 MB steps and the CPU cap follows automatically — no separate knob to tune. And because everything above your plan’s baseline meters by the hour, right-sizing is real money, not a dashboard chore: a resource you stop using drops off the bill that same hour. That makes an agent — not a human watching graphs — the natural operator of scale.

Scaling RAM

RAM is the primary dial. Your agent reads and sets it over MCP:

  1. Read the state. nyx_project_state <project> returns allocatedMb, reservedMb, floorMb, and remainingPoolMb — what’s allocated, what running pods hold, and what’s free in the pool.
  2. Size from the repo, not a guess. Read the framework, sidecars, and any ML libraries to estimate what the workload actually needs.
  3. Set it. nyx_project_ram <project> --mb <needed> rounds up to the next 256 MB step. The CPU cap rises with it automatically.

There’s no separate CPU dial — the cap is derived from RAM at allocatedMb * 500 / 1024 millicores, summed across every pod in the namespace:

RAMCPU cap
256 MB125m
512 MB250m
1024 MB500m

The only way to raise CPU headroom is to raise RAM. If the pool has no room, shrink another project or surface the upgrade link from nyx_account_ram — never half-apply a deploy that’s short on RAM.

Right-sizing pays by the hour

Every project and app shows live CPU and memory against what you’ve allocated — the same signal an operating agent reads to decide when to resize.

Memory · 24h3.4 GB used · 4 GB allocated
Memory actually used Allocated — the GB-hours you're billed for

Your plan bills monthly — the flat fee covers a resource baseline. Everything above it meters hourly: the per-GB rate is quoted monthly (€5/GB/month) for easy comparison, but the meter runs every hour. That’s where the real saving lives, and it’s why scale belongs to an agent that acts just-in-time. An operating agent calls nyx_project_ram to scale a project down when it’s idle and back up before load returns, or tears an environment down entirely between runs — a nightly batch, a staging environment that only lives in office hours. Either way you pay for the hours it ran, not for peak capacity provisioned around the clock.

Want scaling on a clock rather than on demand — down at night, up in the morning? A CronJob running kubectl scale does exactly that today. A dedicated FinOps agent that watches usage and rightsizes continuously on its own is on the way — the hourly meter is already there for it to work against.

Scaling out — more than one replica

Vertical scaling (more RAM) covers most workloads. To scale horizontally — run multiple replicas behind one Service — two things have to hold, and they follow from how the tier stores state:

  • Stateless tiers scale freely. No local state between requests — no SQLite on disk, no uploads to a local directory, no in-process session store — and no PVC, or an emptyDir/object-storage scratch path. Set replicas as high as your quota allows.
  • Stateful tiers stay single-replica or go StatefulSet. A customer app PVC is ReadWriteOnce — it binds to one node — so a second replica on another node can’t mount the same volume and sits in ContainerCreating. That’s why databases, caches, and queues run at replicas: 1 by default; real HA for them is a StatefulSet with one PVC per pod plus app-level replication, not a larger replicas number. (Access mode is a property of the volume, set at provision time — you can’t widen it by editing the Deployment.)

So the rule of thumb: scale the stateless web/API tier out, scale the stateful tier up. Shared read-write storage across replicas of your own app isn’t a customer option today — the infrastructure supports it, and exposing it is a near-term unlock.

Sizing a pod

Size small web pods around 50–100m CPU — don’t copy a flat "1" or "200m" from somewhere else. limits.cpu and limits.memory are mandatory alongside requests, and both are checked against the cap:

  • Missing limits.cpu → rejected before deploy (quota declaration missing).
  • limits.cpu over the cap → exceeded quota: limits.cpu, FailedCreate — no pod is created.

Note: Shrinking a project’s RAM below what its running pods reserve fails with a 409 (below_reserved), returning requestedMb, reservedMb, and floorMb. Delete the app first — its reservation drops — or pick an mb value at or above floorMb.

What sits outside the dial

A few limits aren’t the agent’s to change — surface the upgrade path rather than working around them:

  • Pod count per project is capped by plan.
  • Storage is distributed from a separate pool (requests.storage), not from RAM.
  • The account-wide RAM pool grows only through a subscription purchase.
  • LoadBalancer / NodePort services are always 0 — the Traefik ingress is the one external entrypoint.

See Projects & accounts for how the account pool and project ceilings relate.

Ask any AI about nyxory