Skip to content

reverse_proxy: slow-start warm-up for newly added or recovered upstreams #7966

Description

@rajvarun77

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions