> ## Documentation Index
> Fetch the complete documentation index at: https://docs.abbyy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Scaling

The orchestrator sizes the worker pool from the queue. You set the bounds and how quickly it responds.

## How the pool is sized

```text theme={null}
workers = busy + ceil(queued units × average unit time / minimumThroughputSeconds)
```

clamped between `scaling.minWorkers` and `scaling.maxWorkers`. The average unit time starts at `scaling.defaultUnitSeconds` and follows measured times as units complete. For example, 80 queued units at 30 seconds each with a 120-second target asks for 20 more workers.

The pool grows as soon as the queue calls for it, and shrinks only after the queue has called for fewer workers for `scaling.scaleDownCooldownMs`.

| Value | Default | Effect |
| - | - | - |
| `scaling.minWorkers` | `0` | Workers kept running when the queue is empty. |
| `scaling.maxWorkers` | `20` | The most workers the pool runs. |
| `scaling.minimumThroughputSeconds` | `120` | How soon queued work should get capacity. Lower starts more workers sooner. |
| `scaling.defaultUnitSeconds` | `30` | Starting estimate of the time one unit takes. |
| `scaling.tickMs` | `15000` | How often the pool size is checked. |
| `scaling.scaleDownCooldownMs` | `300000` | How long the queue must call for fewer workers before the pool shrinks. |

Do not scale the worker Deployment yourself or attach a HorizontalPodAutoscaler to it. The orchestrator resets the replica count on its next check.

## Capacity

Each worker requests `worker.resources.requests`, 1 vCPU and 1 GB by default, and processes one unit at a time. Add throughput by raising `maxWorkers`, not by giving workers more CPU.

The orchestrator only creates pods, so the cluster needs a node autoscaler to add nodes for them. Before raising `maxWorkers` into the hundreds, check your cloud's CPU quota as well as the cluster's limits.

The chart sets requests but no limits. If workers are evicted for memory pressure on large or high-resolution pages, raise `worker.resources.requests.memory`.

## Cold starts

With `minWorkers: 0`, the first job after an idle period waits for a worker to be scheduled, pull its image, and start. Set `minWorkers` to keep workers ready. To speed up bursts on new nodes, see [Pre-pulling the worker image](https://docs.abbyy.com/fine-parser/enterprise/best-practices/scheduling.md#pre-pulling-the-worker-image).

## Unit size and leases

A PDF over `ingest.pageSplitThreshold` pages (25) is split into parts of that many pages, and each part is one unit of work. Smaller units spread a large document across more workers.

A worker must finish a unit within `orchestrator.workLeaseSeconds` (300). Otherwise the unit is given to another worker, and after `orchestrator.workMaxAttempts` (3) attempts the job fails with `timed-out`. Keep the lease above the time your slowest unit takes, or lower the split threshold.

## Ingest and the orchestrator

Ingest runs `ingest.replicas` pods. Raise it if uploads or PDF splitting keep ingest busy. The orchestrator always runs as one replica.
