Skip to content

Autoscale the AI Gateway by default - #119

Merged
Alex R (alexr17) merged 8 commits into
mainfrom
alexr/ai-gateway-autoscaling
Nov 12, 2026
Merged

Alex R (alexr17) merged 8 commits into
mainfrom
alexr/ai-gateway-autoscaling

Conversation

@alexr17

@alexr17 Alex R (alexr17) commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Autoscale the AI Gateway by default, the same way the AWS module's gateway ECS service does: 70% CPU or 75% memory, scaling up after 60s and down after 300s. minReplicas defaults to aiGateway.replicas (2) and maxReplicas to max(6, minReplicas), so a custom replica count stays the floor.

  • New ai-gateway-hpa.yaml (autoscaling/v2, ContainerResource on the ai-gateway container).
  • While autoscaling is on, the Deployment omits replicas. aiGateway.autoscaling.enabled: false restores fixed aiGateway.replicas.
  • Defaults are read with dig, so --reuse-values upgrades from older charts still render.

Without metrics-server (for example, stock EKS), the HPA holds minReplicas, the same count as today.

Input matrix

Input Behavior
gateway disabled no HPA
gateway enabled HPA with defaults, no Deployment replicas
custom bounds/targets rendered as set
custom replicas, no bounds minReplicas = replicas, maxReplicas = max(6, replicas)
replicas null 2–6
autoscaling.enabled: false no HPA, fixed replicas
--reuse-values from an older chart, with or without a partial --set HPA with defaults for unset fields
minReplicas or replicas < 1 or empty, maxReplicas < minReplicas, zero or empty targets, missing CPU or memory request render fails with one message
aws / azure / google HPA renders on each

Each row has a test in ai-gateway-autoscaling_test.yaml. HPA label isolation tests are in labels-merge-autoscaling_test.yaml.

Upgrade notes

On a release already running the gateway, the upgrade drops it to 1 replica for roughly 30–60s: up to about 15s for the HPA to restore the count, then image pull and the readiness delay. autoscaling.enabled: false only postpones this until autoscaling is turned on. Chart.yaml isn't bumped.

Validation

./test.sh passes (466/466). kubeconform -strict against Kubernetes 1.30 passed on aws, azure, and google at 76d4062 (not rerun for the replicas-default change). Not tested on a live cluster.

🤖 Generated with Claude Code

Co-authored by StarfolkAI (@starfolkai)[bot]

The gateway Deployment had a fixed replica count and no HPA, while the AWS
module's gateway ECS service autoscales 2-6 tasks on CPU and memory. Add
aiGateway.autoscaling, a standard autoscaling/v2 HPA on ai-gateway container
CPU (70%) and memory (75%) with the same bounds and scale windows, and an
optional aiGateway.podDisruptionBudget. Both default to disabled, so existing
releases render unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-12T02:01:39.074693Z 34f88b3 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 59131f4486

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "Codex (@codex) review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".

metadata:
name: {{ .Values.aiGateway.name }}
namespace: {{ include "braintrust.namespace" . }}
{{- with (merge (deepCopy .Values.aiGateway.labels) .Values.global.labels) }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Add isolation tests for the new label merges

Add cross-template label-isolation coverage for both new resources: the current test only checks that disjoint component and global labels appear on one HPA, while neither the HPA nor PDB is tested for mutation leakage or conflicting-label precedence against other rendered resources. The repository explicitly requires a corresponding isolation test for every new template that merges labels.

AGENTS.md reference: AGENTS.md:L32-L35

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added HPA label-isolation tests in 0443689 (labels-merge-autoscaling_test.yaml): global/gateway precedence on the HPA, and gateway labels absent from another rendered component. The PDB was removed from this PR in a675059.

Without the resource metrics API the HPA holds the gateway at minReplicas,
which matches the previous fixed count of 2, so a default-on HPA does not
regress clusters without metrics-server. Releases that already run the
gateway briefly drop to 1 replica on the upgrade that removes the fixed
Deployment replica count; the README documents how to avoid that.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@alexr17 Alex R (alexr17) changed the title Add optional autoscaling and disruption budget for the AI Gateway Autoscale the AI Gateway by default and add an optional disruption budget Nov 3, 2026
Drop the disruption budget, HPA annotations, configurable scale windows,
and the defaults/validation helper. Defaults are read inline with dig so
--reuse-values upgrades from older charts still render.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@alexr17 Alex R (alexr17) changed the title Autoscale the AI Gateway by default and add an optional disruption budget Autoscale the AI Gateway by default Nov 3, 2026
Cover global/gateway label precedence on the HPA and confirm gateway labels
do not reach another rendered component, per the label-merge test rule.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Copy link
Copy Markdown
Contributor Author

Codex (@codex) review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0443689873

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "Codex (@codex) review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".

Comment on lines +26 to +27
type: Utilization
averageUtilization: {{ dig "cpu" "targetAverageUtilization" 70 $autoscaling }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Require resource requests for utilization scaling

When an existing gateway configuration removes both aiGateway.resources.requests.cpu and .memory—for example, with null values retained by --reuse-values—these default-on utilization metrics have no request denominator. Kubernetes documents that utilization is undefined without the corresponding request and the autoscaler takes no action for that metric, so this HPA cannot scale the gateway under load even when metrics-server is healthy. Require the requests while autoscaling is enabled, use absolute-value targets, or preserve fixed replicas for this configuration, and add null/reused-values coverage. Kubernetes HPA resource metrics documentation

AGENTS.md reference: AGENTS.md:L14-L17

Useful? React with 👍 / 👎.

@alexr17 Alex R (alexr17) Nov 3, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 76d4062: rendering fails when the CPU or memory request is missing.

Fail rendering when autoscaling.minReplicas is below 1 or the gateway has no
CPU or memory request, since utilization targets need both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Copy link
Copy Markdown
Contributor Author

Codex (@codex) review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bfc0edb057

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "Codex (@codex) review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".

Alex R (alexr17) and others added 2 commits November 3, 2026 23:28
The API HPA has neither check, the default values set requests, and
Kubernetes rejects minReplicas 0 on its own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fail rendering when replica bounds or utilization targets are ones
Kubernetes rejects, or the gateway has no CPU or memory request.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Copy link
Copy Markdown
Contributor Author

Codex (@codex) review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 76d4062841

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "Codex (@codex) review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".

Comment on lines +80 to +83
- it: rejects zero minReplicas
set:
aiGateway.enabled: true
aiGateway.autoscaling.minReplicas: 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Complete the required autoscaling input-matrix tests

The validation tests cover only one input shape per setting, leaving null/empty replica bounds, null utilization targets, and partial nested CPU/memory maps on reused values untested. These exercise different Helm coalescing and dig paths from the covered zero/scalar cases, so the existing tests do not establish their intended rendering or rejection behavior. Add explicit cases for these shapes; the repository requires null/missing/empty/zero and partial reused-value coverage and explicitly treats unchecked input shapes as release blockers.

AGENTS.md reference: AGENTS.md:L14-L17

Useful? React with 👍 / 👎.

@erikdw Erik Weathers (erikdw) left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new validation looks right. One upgrade issue is worth fixing (inline), plus a README note.

Not blocking: scale-in is new and the chart has no preStop hook, so in-flight requests can be cut when a pod stops. Worth a follow-up to confirm the gateway drains before exit.

{{- $autoscaling := .Values.aiGateway.autoscaling | default dict }}
{{- if and .Values.aiGateway.enabled (dig "enabled" true $autoscaling) }}
{{- $minReplicas := int (dig "minReplicas" 2 $autoscaling) }}
{{- $maxReplicas := int (dig "maxReplicas" 6 $autoscaling) }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A custom aiGateway.replicas is still replaced by these 2–6 defaults. One GKE install we run uses replicas: 4 and would settle at 2; a gateway at 10 would be capped at 6. We're setting autoscaling.minReplicas for that install. To cover others, take minReplicas and maxReplicas out of values.yaml and default them here to replicas and max(6, replicas). While 2 and 6 are in values.yaml, Helm supplies them on every normal install and upgrade, so a dig default of replicas never runs.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 34f88b3. minReplicas/maxReplicas are out of values.yaml and now default to aiGateway.replicas and max(6, minReplicas). I used minReplicas in the max so an explicit minReplicas above 6 also renders. replicas: 4 gives 4-6, and replicas: 10 gives 10-10. Explicit bounds still win.

Comment thread braintrust/README.md Outdated

The AI Gateway autoscales by default. An HPA runs 2-6 replicas at 70% CPU and 75% memory, the same as the AWS module. It needs metrics-server, which GKE and AKS include; without it the gateway stays at 2. Set `aiGateway.autoscaling.enabled: false` to use a fixed `aiGateway.replicas`.

Turning on autoscaling for a running gateway briefly drops it to 1 replica until the HPA scales it back up.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This dip is roughly 30–60 seconds on one pod: up to about 15 seconds for the HPA to restore the count, then image pull and the readiness delay. Setting autoscaling.enabled: false only postpones it until autoscaling is turned on.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated in 34f88b3. The README and PR description now say roughly 30-60s, and that autoscaling.enabled: false only postpones the dip.

minReplicas now defaults to aiGateway.replicas and maxReplicas to
max(6, minReplicas), so a custom replica count is no longer reset to
2-6. The bounds leave values.yaml so the template default applies.
README notes the 30-60s dip on enabling autoscaling.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@alexr17

Copy link
Copy Markdown
Contributor Author

Codex (@codex) review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep them coming!

Reviewed commit: 34f88b3a73

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "Codex (@codex) review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".

@alexr17
Alex R (alexr17) merged commit 1b44b31 into main Nov 12, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants