Everyone Can Learn Program
中文 Start learning
Specialty · Cloud and SRELesson 4 of 5Free to read

Autoscaling · Cloud and Reliability

How does a service grow when traffic rises, and shrink when it falls?

Course contents

Why you need it

Traffic isn't flat: lunchtime, a sale or a mention on social media can multiply it. Running enough servers for the peak all day wastes money; running too few makes the site slow or down. Autoscaling adjusts the number of copies automatically, and understanding its rule tells you how to set it up and why it sometimes surprises you.

The intuition

Kubernetes' Horizontal Pod Autoscaler (HPA) uses one formula (from its documentation):

desired = ceil( current_replicas × current_metric / target_metric )

With a CPU target of 50%: 4 pods averaging 80% CPU → ceil(4 × 80 / 50) = ceil(6.4) = 7 pods. The load spreads over more pods, so each one gets closer to 50%.

Two guards keep it sane:

  • Bounds: never below min or above max replicas. The max protects your bill and your database.
  • Tolerance: if the ratio current / target is within 10% of 1 (the HPA default), do nothing. Without it, small wobbles would add and remove pods all day ("flapping").

Scaling takes time: a new pod must start and pass its readiness probe. That's why targets are usually well below 100%: the headroom absorbs the rise while new pods start.

Definition

Autoscaling

Automatically changing the number of copies of a service based on a metric such as CPU or requests per second.

Target utilisation

The level of a metric the autoscaler tries to keep each copy at, such as 50% CPU.

Flapping

Scaling up and down repeatedly because of small changes. A tolerance or a cool-down prevents it.

Examples

The formula

Try it yourself

More load than the target → more pods; less → fewer.

import math

def desired(current, cpu, target):
    return math.ceil(current * cpu / target)

print(desired(4, 80, 50))
print(desired(4, 50, 50))
print(desired(10, 12, 50))
Output
7
4
3
Step by step
  1. L4Round up: a fraction of a pod still needs a whole pod.
  2. L64 × 80 / 50 = 6.4 → 7.7
  3. L8Quiet night: 10 × 12 / 50 = 2.4 → 3.3

With bounds

Try it yourself

min and max clamp the result.

import math

def desired(current, cpu, target):
    return math.ceil(current * cpu / target)

def bounded(current, cpu, target, lo, hi):
    return max(lo, min(hi, desired(current, cpu, target)))

print(bounded(4, 300, 50, 2, 10))
print(bounded(4, 5, 50, 2, 10))
Output
10
2
Step by step
  1. L7First cap at hi, then raise to at least lo.
  2. L9A spike asks for 24 pods; the max allows 10.10
  3. L10Nearly idle asks for 1; keep at least 2 for safety.2

Common mistakes

No maximum

A bug or an attack that burns CPU will scale you to hundreds of pods, and a matching bill. Always set max.

A target near 100%

New pods take time to start. With no headroom, the existing ones are overloaded while you wait.

Scaling something that can't scale

If the bottleneck is the database, more web pods just send it more queries. Find the real bottleneck first.

Quick quiz

1. What does this print?

import math

def desired(current, cpu, target):
    return math.ceil(current * cpu / target)

print(desired(3, 90, 60))
  1. A
    5
  2. B
    4
  3. C
    3
Show the answer

Answer: A

3 × 90 / 60 = 4.5, rounded up to 5.

2. Why does the autoscaler ignore changes within 10% of the target?

  1. ATo avoid adding and removing pods for tiny wobbles
  2. BBecause metrics are always 10% wrong
  3. CTo save memory in the autoscaler
Show the answer

Answer: A

A tolerance band stops flapping.

Practice

3 exercises in three steps: predict what a program prints, change a program to meet a new requirement, then write one from scratch. Your code runs in the browser and is checked the moment you submit.

  1. PredictA busy morning

    Type exactly what this prints.

  2. ModifyStop the flapping

    This autoscaler adds or removes a pod on every tiny change. Add the tolerance: if cpu / target is within 10% of 1 (from 0.9 to 1.1, inclusive), keep current unchanged.

  3. WriteReplay a day

    Write replay(start, readings, target, lo, hi) that returns the replica count after each CPU reading. For each reading:

    1. ratio = cpu / target; if it's from 0.9 to 1.1, keep the current count
    2. otherwise ceil(current × ratio)
    3. then clamp to lo…hi
    replay(2, [50, 90, 300, 10], 50, 2, 8)   # [2, 4, 8, 2]

Practise this lesson

Open the interactive lesson to edit and run these examples and solve the exercises with instant feedback. Free to start, no sign-up.

Interactive lessons open in order. If you have not done the earlier ones yet, you start at the course map.

Terms in this lesson

TermChineseDefinition
Autoscaling自动扩缩容Changing the number of copies to match load.
HPAHPA 水平自动扩缩Kubernetes' Horizontal Pod Autoscaler.
Flapping抖动Scaling up and down over and over.