Skip to content

How to autoscale a service on CPU and memory

Turn on horizontal autoscaling for an Ownkube deployment: set min and max replicas and a CPU target, and see why idle replicas barely touch your bill.

Abhishek Jaiswal

5 min

On this page 6 sections

A single replica is fine until traffic isn’t steady: a launch post spikes requests for an hour, then it’s quiet again. Rather than picking one fixed size and living with either overpaying at 3am or falling over at noon, Ownkube can add and remove replicas of a deployment automatically, based on how hard CPU is actually working (and memory too, on your own cloud).

This guide turns on horizontal autoscaling for a web or worker deployment, explains what the CPU target actually controls, and covers what it does to your bill.

TL;DR

  • Autoscaling is a per-deployment setting: min and max replica counts plus a target CPU percentage. A memory target is available on your own cloud; Ownkube Compute sizes memory automatically.
  • Ownkube adds replicas when the target is exceeded and removes them as load drops, never going below your minimum or above your maximum.
  • New replicas roll in with zero-downtime rollouts, so scaling up (or deploying a new revision while scaled up) doesn’t drop traffic.
  • On Ownkube Compute’s metered billing, CPU and memory bill on actual per-minute usage, so a replica sitting idle between traffic spikes costs close to nothing.
  • On Ownkube Compute, set it through your coding agent (the update_deployment MCP tool), the API, or a manifest applied with the CLI. On your own cloud it is also on the deployment’s Settings tab.

Turn on autoscaling

Autoscaling works on web and worker deployments; jobs and databases don’t autoscale. On your own cloud the fields below are on the deployment’s Settings tab. On Ownkube Compute you set them through your coding agent, the API, or the CLI.

  1. Ask your coding agent to turn on autoscaling for the deployment. It uses the update_deployment tool on the Ownkube MCP server. You can also apply a manifest with the CLI, shown below.
  2. Set Min replicas and Max replicas. Min is your floor, the number of replicas that stay running even at zero load; max is your ceiling, how far Ownkube can scale up under sustained pressure.
  3. Set Target CPU %, the share of each replica’s CPU limit that triggers a scale-up when crossed. On your own cloud you can also set Target Memory %.
  4. Apply. The change takes effect without downtime; existing replicas keep serving traffic while the new target takes effect.
# manifest.yaml, applied with: okctl deploy update <deployment-id> -f manifest.yaml
appConfig:
autoscaling:
enabled: true
minReplicas: 1
maxReplicas: 5
targetCPUUtilizationPercentage: 70

How the targets actually work

Autoscaling here is horizontal: Ownkube changes how many replicas of your deployment are running, not the size of any single replica. Each replica still runs at the CPU and memory limits you set under Settings → Resources; the CPU target is how full the CPU limit needs to get before another replica joins.

  • If Target CPU % is 70 and a replica’s CPU usage sits above 70% of its limit for a sustained period, Ownkube adds a replica and spreads load across both.
  • On your own cloud, Target Memory % works the same way against each replica’s memory request. With both targets set, whichever is crossed first drives the scale-up.
  • Replicas never drop below Min replicas, even at zero traffic, and never exceed Max replicas, even under sustained load. Set the max to whatever ceiling keeps you comfortable, both for capacity and for spend.

A good starting point for most web apps is a CPU target in the 60 to 80% range: low enough to add capacity before things actually feel slow, high enough that you’re not scaling up on every minor blip.

Scaling and deploys stay zero-downtime

Autoscaling shares the same rolling-update mechanics as a normal deploy: a new replica has to pass its health check before it starts receiving traffic, and an old replica is only removed after its replacement is ready.

That holds whether the new replica showed up because you pushed a commit or because load crossed your CPU target, so a traffic spike and a deploy landing at the same time don’t fight each other or drop requests.

What autoscaling does to your bill

On Ownkube Compute, metered billing measures both CPU and memory on actual per-minute usage, not on the size you provisioned. That changes the economics of scaling up compared to a platform that bills per fixed instance-hour regardless of load:

  • A replica that autoscaling added during a traffic spike and then removed an hour later only metered for that hour, not for the rest of the month.
  • A replica sitting at your minimum during quiet hours draws almost nothing on CPU, since the meter reflects what’s actually used, not the limit it’s allowed to reach.
  • If a workload runs hot around the clock instead of bursting, a flat-rate reserved box can end up cheaper than metering continuously; you can put a steady worker on a reserved box and leave autoscaling for the bursty web app in the same project. See our breakdown of metered versus reserved pricing for how to decide per deployment.

In practice you pay for the shape your traffic actually took. A fixed-instance-hour platform charges the same setup for the ceiling you configured.

FAQ

What’s the difference between autoscaling and just setting a bigger resource limit?

A resource limit caps how much CPU and memory a single replica can use. Autoscaling changes how many replicas exist. A CPU-bound app that’s maxing out one replica benefits more from another replica (horizontal) than a bigger limit on the same one (vertical), especially since most web frameworks don’t use extra cores within a single process well.

Does scaling up cause downtime?

No. New replicas join through the same zero-downtime rollout path as a normal deploy: they pass a health check before receiving traffic, and old replicas are removed only after replacements are ready.

Can I autoscale a database or a scheduled job?

No. Autoscaling applies to web and worker deployments. Databases and caches are always reserved, fixed-size boxes, and a scheduled job runs to completion rather than serving ongoing traffic, so neither has a replica count to scale.

Will autoscaling make my bill unpredictable?

It can move month to month if your traffic does, but on metered billing each replica only draws the wallet for the minutes it actually runs and the resources it actually uses, capped by your max replicas. If predictability matters more than squeezing idle time, put the deployment on a reserved box instead and skip autoscaling.

What’s a reasonable max replicas to start with?

Whatever ceiling protects your wallet and your dependencies (like a database’s connection limit) if load spikes hard. Start conservative, watch how often you actually approach it on the deployment’s metrics, and raise it if you see autoscaling pinned at the max during real traffic.

For the full reference, see Autoscaling in the docs.

Where Ownkube fits

If your traffic isn’t flat, autoscaling saves you from choosing between overpaying for headroom you rarely use and getting paged when you didn’t provision enough. Set a floor, a ceiling, and a CPU target, and Ownkube adds and removes replicas through zero-downtime rollouts while metered billing keeps the cost tied to what actually ran.

For the bigger picture on right-sizing spend across a whole project, see our guide to Kubernetes cost optimization for startups. Deploy my first app.

Abhishek Jaiswal · Founder and Engineer

Abhishek Jaiswal is the founder and engineer behind Ownkube, a cloud for personal software. He builds the platform and writes here about cloud cost, migrations, and running production infrastructure in your own AWS account without a DevOps team.

Share

More posts

All posts

Ship my first app in the next five minutes.

Push a repo and get a live URL, with no cloud account or config.

Top up from $5, billed per minute with no subscription.