Managing MiniMax API Keys in LiteLLM
Overview
LiteLLM proxy load-balances requests across multiple MiniMax API keys using
simple-shuffle routing. Each model group has N deployments (one per key),
and requests are distributed evenly.
Current setup: 2 keys × 10 model groups = 20 deployments.
Subscription seats drive the key count. We buy N user seats on the MiniMax Plus plan and provision N API keys; the model pool scales linearly (2 keys → 2 replicas per model group → 2× aggregate throughput per model under the same per-key rate limit). See
hungryhub-terraform#534for the most recent 13 → 2 reduction.
Model groups (all on MiniMax Plus plan — same per-key rate limit):
| Group | Model | Rate limits per deployment |
|---|---|---|
| Chat | minimax/MiniMax-M2.1 | rpm 120, tpm 240000 |
| Chat | minimax/MiniMax-M2.1-highspeed | rpm 180, tpm 360000 |
| Chat | minimax/MiniMax-M2 | rpm 120, tpm 240000 |
| Chat | minimax/MiniMax-M3 | rpm 100, tpm 200000 |
| Chat | minimax/MiniMax-M2.7 | rpm 120, tpm 240000 |
| Chat | minimax/MiniMax-M2.7-highspeed | rpm 180, tpm 360000 |
| Chat | minimax/MiniMax-M2.5 | rpm 120, tpm 240000 |
| Chat | minimax/MiniMax-M2.5-highspeed | rpm 180, tpm 360000 |
| TTS | minimax/speech-2.6-hd | (no per-deployment limit) |
| TTS | minimax/speech-2.6-turbo | (no per-deployment limit) |
Both keys are used in parallel per model group (order: 1 on every
deployment) since they’re all the same Plus tier.
Source of Truth
The key set and per-key pool size are Terraform-managed, not runtime.
The live Kubernetes secret litellm-env-secret is reconciled from:
AWS Secrets Manager: /hungryhub/dev (LITELLM_REDIS_PASSWORD, MINIMAX_API_KEY_*, ...)
|
v
helm-releases/litellm.tf (kubernetes_secret_v1.litellm_env, K8s secret)
|
v
helm-releases/values/litellm.yaml.tft (proxy_config.model_list, fed via helm release)
|
v
LiteLLM pods read both on startup; model_list lives in chart values, not in /config
Why this matters: the previous workflow (add to K8s secret +
POST /config/updatefrom a running pod) was effective in earlier LiteLLM versions, but in v1.88.1 the chart-loaded config takes precedence on pod restart and the runtime update is silently ignored (200 OK but no change to the router’s deployment list). The chart is now the single source of truth and must be updated for any change to take effect.
Adding a New Key
-
Append the new key to
keys.txt(local, gitignored, operator reference). Line N becomesMINIMAX_API_KEY_N. -
Add the key to AWS Secrets Manager (sandbox account for dev):
aws --profile=sandbox secretsmanager get-secret-value \ --secret-id /hungryhub/dev --region ap-southeast-1 \ --query SecretString --output text | \ python3 -c " import json, sys d = json.load(sys.stdin) d['MINIMAX_API_KEY_N'] = open('keys.txt').readlines()[N-1].strip() sys.stdout.write(json.dumps(d))" | \ aws --profile=sandbox secretsmanager put-secret-value \ --secret-id /hungryhub/dev --region ap-southeast-1 \ --secret-string file:///dev/stdinNote:
sys.stdout.writeinstead ofprint—printadds a trailing newline that AWS CLI persists inSecretStringand breaksjsondecodeon the next Terraform apply. Seehungryhub-terraform/AGENTS.md §6.6in thehh-infraworkspace root. -
Update
helm-releases/litellm.tfto declare the new key in thekubernetes_secret_v1.litellm_envdata block. Without this step, the nextterraform applywould wipe the key from the live K8s secret. -
Update
helm-releases/values/litellm.yaml.tftto add one new deployment per model group underproxy_config.model_list(10 groups × 1 new entry each). Use the existingMINIMAX_API_KEY_{1..N-1}patterns in the file as a template; the rate limits per model group are listed in the overview table above. -
Open a PR against
hungryhub-team/hungryhub-terraform. Theterraform-pr-plan.ymlworkflow runsterraform planautomatically and posts a comment. Review the plan diff (expect: 1 K8s secret update + 1 helm release update, 0 destroy). -
Apply via the
terraform.ymlworkflow (workflow_dispatch, env=dev, services=helm-releases, action=apply). The Helm upgrade rolls the LiteLLM pods; the newmodel_listis loaded on startup. -
Verify by counting unique
model_info.idvalues in the proxy log for any model — should match the new pool size (N distinct IDs once rollout settles).
Removing a Key
Reverse the add workflow:
- Remove the key from AWS SM
/hungryhub/dev(use the sameput-secret-valuepattern with the new JSON). - Remove the
MINIMAX_API_KEY_Nline fromhelm-releases/litellm.tfand fromproxy_config.model_listinvalues/litellm.yaml.tft(one entry per model group, 10 groups total). - PR + apply as above.
Rotating a Key
In-place rotation (key N → new value, no model_list change):
- Replace the value of
MINIMAX_API_KEY_Nin AWS SM. - Update line N in
helm-releases/litellm.tf(the value comes fromlocal._secrets["MINIMAX_API_KEY_N"]at apply time, so the .tf itself doesn’t need a literal value change, but the secret data will be reconciled). - PR + apply. Pods pick up the new env var via the secret volume mount within ~60s; the helm upgrade will roll pods explicitly anyway.
How Load Balancing Works
- Strategy:
simple-shuffle— random distribution across all deployments sharing the samemodel_name. - Failover: If a key returns 429 (rate limit) or 5xx, LiteLLM retries
with another key (up to
num_retries: 2). - Cooldown: After 3 consecutive failures on a key, it’s cooled down
for 30s. Cooldown state is shared across pods via the bundled Redis
(subchart of
litellm-helm, auth wired toLITELLM_REDIS_PASSWORD). - Fallback chain (chat models only):
- M3 → M2.1 → M2
- M2.1-highspeed → M2.1
- M2.5 → M2.1
- M2.5-highspeed → M2.1-highspeed
- M2.7 → M2.1
- M2.7-highspeed → M2.1-highspeed
Key Source
MiniMax API keys are created at https://platform.minimax.io (developer
console). Each key has its own per-key rate limit; more keys = higher
aggregate throughput under simple-shuffle.
Where Keys Are Stored
| Location | Purpose |
|---|---|
keys.txt (local, gitignored) | Operator reference, line N = MINIMAX_API_KEY_N |
AWS Secrets Manager /hungryhub/dev | Terraform source of truth (CI/CD) |
K8s secret litellm-env-secret (ns: litellm) | Runtime — pods read from here |
helm-releases/values/litellm.yaml.tft | model_list — defines which keys are pooled per model |
For Terraform-managed deployments, update AWS SM and the chart values
together in the same PR; re-run terraform apply on helm-releases.
History
| Date | Pool size | Change | PR |
|---|---|---|---|
| 2026-06-26 | 2 keys × 10 groups = 20 deployments | Downgraded MiniMax Plus subscription from 20 → 2 users; collapsed 13 → 2 keys (13 → 1 first, then 1 → 2 once a second key was issued). | hungryhub-terraform#534 |
| pre-2026-06 | 13 keys × 10 groups = 130 deployments | Steady state on MiniMax Plus, 20 seats provisioned (operational overhead: keys.txt had ~13 lines). | — |
| Earlier | 9 keys × 6 groups = 54 deployments | The pool size this runbook originally described. The 6-group model list was later expanded to 10 to include M2.5 / M2.5-highspeed / M2.7 / M2.7-highspeed. | — |