Configure Upstream Slow Start
New application instances can need time to warm caches or initialize connections before handling their normal share of traffic. Upstream slow start gradually increases a new node's effective load-balancing weight while existing nodes continue serving requests.
Slow start changes the distribution of traffic, not the total request rate. A single-node upstream still receives every request. If every available node is new, those nodes still handle all traffic between them.
Prerequisite(s)
- Install Docker.
- Install cURL to send requests to the services for validation.
- Follow the Getting Started tutorial to start an APISIX instance in Docker.
Start Sample Upstream Services
Set GATEWAY_CONTAINER to your running APISIX container. Connect it and two echo servers to a dedicated network:
export GATEWAY_CONTAINER=replace-with-apisix-container-name
docker network create apisix-slow-start-net
docker network connect apisix-slow-start-net "$GATEWAY_CONTAINER"
docker run -d --name slow-start-existing --hostname existing \
--network apisix-slow-start-net jmalloc/echo-server:v0.3.7
docker run -d --name slow-start-new --hostname new \
--network apisix-slow-start-net jmalloc/echo-server:v0.3.7
The servers identify themselves in their responses. Both servers are running, but only the existing server will initially belong to the upstream.
Create an Upstream and Route
Create an upstream with one node and a 60-second warm-up window:
curl "http://127.0.0.1:9180/apisix/admin/upstreams/slow-start" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"type": "roundrobin",
"nodes": {
"slow-start-existing:8080": 100
},
"warm_up_conf": {
"slow_start_time_seconds": 60,
"min_weight_percent": 10
}
}'
Create a route referencing that upstream:
curl "http://127.0.0.1:9180/apisix/admin/routes/slow-start" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"uri": "/slow-start",
"upstream_id": "slow-start"
}'
Before adding the second node, send a request and confirm that the response identifies existing:
curl "http://127.0.0.1:9080/slow-start"
Send this request before adding the second node so APISIX records the existing node as already warmed. If you configure both nodes before the first request, APISIX treats both as initial members and does not ramp one relative to the other.
Add a Node and Observe Slow Start
Add the second node with the same configured weight. PATCH merges this node into the existing nodes map:
curl "http://127.0.0.1:9180/apisix/admin/upstreams/slow-start" -X PATCH \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"nodes": {
"slow-start-new:8080": 100
}
}'
Send batches of requests over the next minute and count the responses from each server. A batch provides enough samples to make the changing traffic share visible:
for elapsed in $(seq 0 10 60); do
echo "After ${elapsed} seconds:"
seq 1 100 | xargs -P 20 -I {} \
curl -sS "http://127.0.0.1:9080/slow-start" | \
grep -o 'Request served by [^[:space:]]*' | sort | uniq -c
[ "$elapsed" -lt 60 ] && sleep 10
done
The new node starts at an effective weight of 10 compared with the existing node's weight of 100. Its share grows toward half the requests as its weight reaches 100. Exact counts vary because configuration updates and requests are distributed across gateway workers. The minimum percentage is a percentage of the node's configured weight, not of all traffic.
Tune Slow Start
Configure these fields in the warm_up_conf object of the upstream:
| Field | Required | Default | Valid values | Description |
|---|---|---|---|---|
slow_start_time_seconds | Yes | N/A | Integer greater than or equal to 1 | Seconds for a new node to reach its configured weight. |
min_weight_percent | Yes | N/A | Integer from 1 through 100 | Minimum percentage of the configured node weight. |
interval | No | 1 | Integer from 1 through slow_start_time_seconds | Seconds between effective weight refreshes. |
aggression | No | 1 | Number greater than or equal to 0.01 | Ramp shape. 1 is linear, values above 1 increase weight faster initially, and values below 1 increase it more slowly. |
startup_grace_period_seconds | No | 0 | Integer greater than or equal to 0 | Seconds after the gateway starts during which newly observed nodes are treated as already warmed. |
Weights are integers and a positive node weight never falls below 1. Use sufficiently large configured weights when you need a gradual ramp: a node with weight 1 cannot have its weight reduced further.
Slow start applies to HTTP upstreams using weighted round robin with a single node priority. Other load-balancing algorithms, stream routes, and mixed node priorities do not support it. Inline upstreams in the traffic-split plugin reject slow-start configuration.
Each APISIX instance tracks new nodes independently. Existing nodes are treated as warmed when slow start is first enabled, and a new node's ramp begins when it first becomes eligible. A node returning within one ramp duration resumes its ramp; after a longer absence, it starts a new one. Slow start does not replace readiness checks.
Next Steps
Combine slow start with upstream health checks so newly deployed nodes receive traffic only when they can serve it. See the Admin API reference for upstreams for the complete configuration schema.