> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-postgresql-tls-support.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Understanding scaling recommendations in ClickHouse Cloud

# Scaling recommendations

export const Image = ({img, alt, size = "lg"}) => {
  const normalizedSize = ["sm", "md", "lg"].includes(size) ? size : "lg";
  return <div className={`ch-image-${normalizedSize}`}>
      <Frame>
        <img src={img} alt={alt} />
      </Frame>
    </div>;
};

<h2 id="introduction">
  Introduction
</h2>

Auto-scaling database resources requires careful balance: scaling up too slowly can risk performance degradation while scaling down too aggressively can trigger constant oscillations.

ClickHouse Cloud enables faster scale-downs, minimized scaling oscillations, and substantial infrastructure cost reduction for variable workloads, while maintaining the stability needed for production databases
by pairing a two-window recommendation framework with a target-tracking CPU recommendation system.

<h2 id="cpu-based-scaling">
  CPU-based Scaling
</h2>

CPU Scaling is based on target tracking which calculates the exact CPU allocation needed to keep utilization at a target level. A scaling action is only triggered if current CPU utilization falls outside a defined band:

| Parameter          | Value | Meaning                                                 |
| ------------------ | ----- | ------------------------------------------------------- |
| Target utilization | 53%   | The utilization level ClickHouse aims to maintain       |
| High watermark     | 75%   | Triggers scale-up when CPU exceeds this threshold       |
| Low watermark      | 37.5% | Triggers scale-down when CPU falls below this threshold |

The recommender evaluates CPU utilization based on historical usage, and determines a recommended CPU size using this formula:

```text theme={null}
recommended_cpu = max_cpu_usage / target_utilization
```

If the CPU utilization is between 37.5%–75% of allocated capacity, no scaling action is taken. Outside that band, the recommender computes the exact size needed to land back at 53% utilization, and the service is scaled accordingly.

<h3 id="cpu-scaling-example">
  Example
</h3>

A service allocated 4 vCPU experiences a spike to 3.8 vCPU usage (\~95% utilization), crossing the 75% high watermark.
The recommender calculates: `3.8 / 0.53 ≈ 7.2 vCPU`, and rounds up to the next available size (8 vCPU). Once load subsides and usage drops below 37.5% (1.5 vCPU), the recommender scales back down proportionally.

<h2 id="memory-based-recommendations">
  Memory-based recommendations
</h2>

ClickHouse Cloud automatically recommends memory sizes based on your service's actual usage patterns.
The recommender analyzes usage over a lookback window and adds headroom to handle spikes and prevent out-of-memory (OOM) errors.

The recommender looks at three signals:

* **Query memory**: The peak memory used during query execution
* **Resident memory**: The peak memory held by the process overall
* **OOM events**: Whether queries or replicas have recently run out of memory

<h3 id="how-headroom-is-calculated">
  How headroom is calculated
</h3>

For query and resident memory, the amount of headroom added depends on how predictable your usage is:

* **Stable usage (low variation)**: 1.25x multiplier — more headroom, since usage is consistent and unlikely to spike unexpectedly
* **Spiky usage (high variation)**: 1.1x multiplier — less headroom, to avoid over-provisioning for workloads that already vary widely

If OOM events are detected, the recommender applies a more aggressive **1.5x multiplier** to ensure the service has enough memory to recover.

<h3 id="final-recommendation">
  Final recommendation
</h3>

The system takes the highest value across all signals:

```text theme={null}
desired_memory = max(
  query_memory × skew_multiplier,
  resident_memory × skew_multiplier,
  resident_memory × 1.5,   // if query OOMs detected
  rss_at_crash × 1.5       // if pod OOMs detected
)
```

<h2 id="two-window-recommender">
  Two-window recommender
</h2>

Instead of using a single window, ClickHouse Cloud uses two lookback windows with different time ranges:

* **Small Window (3 hours)**: Captures recent usage patterns, enables faster scale-down
* **Large Window (30 hours)**: Ensures we scale up in a single step to the maximum usage seen in the longer lookback window, rather than multiple gradual scale-ups. This is critical because scaling takes time and invalidates local caches; so it is safer to scale up in a single step.

Each window independently generates a recommendation using both memory and CPU analysis.
The system then merges these recommendations based on the scaling direction each window suggests, as shown in the figure below:

<Image img="https://mintcdn.com/private-7c7dfe99-postgresql-tls-support/ie2pnLZPTjmhniJm/images/cloud/features/autoscaling/two-window-recommender.webp?fit=max&auto=format&n=ie2pnLZPTjmhniJm&q=85&s=5aba27dc47b609ae27887f47dc5525d0" size="lg" alt="Two-window recommender merging logic" width="2236" height="729" data-path="images/cloud/features/autoscaling/two-window-recommender.webp" />

For a deep dive into the design decisions of the recommender, see ["Smarter Auto-Scaling for ClickHouse: The Two-Window Approach
"](https://clickhouse.com/blog/smarter-auto-scaling#the-two-window-solution)
