Issue Details
Problem. When an upstream joins the pool (dynamic upstreams via SRV/A lookups, a config reload that adds a host) or flips back to healthy after failing health checks, every selection policy gives it its full traffic share immediately. A cold upstream (JIT not warmed, empty caches, connection pools not yet established) serves worse latency for its first seconds, and with least_conn (and least_latency, #7965) the cold host looks idle, so it is the one that gets hammered first. Envoy addresses this with slow_start (a ramp of the effective weight with slow_start_window, aggression, min_weight_percent).
Proposal. A lb_slow_start <duration> option on reverse_proxy, off by default and zero-cost when unset.
Host records a join timestamp, set when the host is created in the shared hosts pool and again on an unhealthy → healthy transition (both passive and active health checks).
- During the window, the host's effective weight ramps from a floor (10%, tunable) to 100%, linearly by default with an optional aggression exponent, mirroring Envoy's parameters so operators can reuse their intuition.
- Policies apply it in the shared selection path:
random, random_choose, least_conn, least_latency scale their score by the ramp; round_robin / weighted_round_robin probabilistically skip a warming host; hash policies (ip_hash, client_ip_hash, uri_hash, query, header, cookie) are exempt because stickiness matters more than warm-up there (Envoy makes the same choice).
- A warming host is never skipped when it is the only available upstream, so the ramp can never produce a 503 that would not have happened anyway.
Scope. Roughly 250 lines plus tests, entirely inside modules/caddyhttp/reverseproxy (hosts.go, selectionpolicies.go, healthchecks.go, Caddyfile adapter). I have the same design implemented for brpc (apache/brpc, cross-policy warm-up ramp with duration / curve / min-weight flags) and would be happy to open the PR here if maintainers want the feature. Happy to adjust the config shape — e.g. nesting it under lb_policy instead of a sibling option — to whatever fits Caddy's conventions.
Assistance Disclosure
AI used
If AI was used, describe the extent to which it was used.
I wrote this proposal and the design myself. If implemented, an AI coding assistant would help draft the implementation and tests from that design, which I would review and verify; this will be disclosed in the PR body as required.
Issue Details
Problem. When an upstream joins the pool (dynamic upstreams via SRV/A lookups, a config reload that adds a host) or flips back to healthy after failing health checks, every selection policy gives it its full traffic share immediately. A cold upstream (JIT not warmed, empty caches, connection pools not yet established) serves worse latency for its first seconds, and with
least_conn(andleast_latency, #7965) the cold host looks idle, so it is the one that gets hammered first. Envoy addresses this withslow_start(a ramp of the effective weight withslow_start_window,aggression,min_weight_percent).Proposal. A
lb_slow_start <duration>option onreverse_proxy, off by default and zero-cost when unset.Hostrecords a join timestamp, set when the host is created in the shared hosts pool and again on an unhealthy → healthy transition (both passive and active health checks).random,random_choose,least_conn,least_latencyscale their score by the ramp;round_robin/weighted_round_robinprobabilistically skip a warming host; hash policies (ip_hash,client_ip_hash,uri_hash,query,header,cookie) are exempt because stickiness matters more than warm-up there (Envoy makes the same choice).Scope. Roughly 250 lines plus tests, entirely inside
modules/caddyhttp/reverseproxy(hosts.go, selectionpolicies.go, healthchecks.go, Caddyfile adapter). I have the same design implemented for brpc (apache/brpc, cross-policy warm-up ramp with duration / curve / min-weight flags) and would be happy to open the PR here if maintainers want the feature. Happy to adjust the config shape — e.g. nesting it underlb_policyinstead of a sibling option — to whatever fits Caddy's conventions.Assistance Disclosure
AI used
If AI was used, describe the extent to which it was used.
I wrote this proposal and the design myself. If implemented, an AI coding assistant would help draft the implementation and tests from that design, which I would review and verify; this will be disclosed in the PR body as required.