# Default values for litellm. # This is a YAML-formatted file. # Declare variables to be passed into your templates. replicaCount: 1 # numWorkers: 2 image: # Bundles the prisma CLI and engines, which is what lets the migrations job # and the proxy's own schema check run without network access. repository: ghcr.io/berriai/litellm pullPolicy: Always # Overrides the image tag whose default is the chart appVersion. # tag: "latest" tag: "" imagePullSecrets: [] nameOverride: "litellm" fullnameOverride: "" serviceAccount: # Specifies whether a service account should be created create: false # Automatically mount a ServiceAccount's API credentials? automount: true # Annotations to add to the service account annotations: {} # The name of the service account to use. # If not set and create is true, a name is generated using the fullname template name: "" # annotations for litellm deployment deploymentAnnotations: {} deploymentLabels: {} deploymentMinReadySeconds: 0 # annotations for litellm pods podAnnotations: {} podLabels: {} # -- Deployment strategy configuration # Example: # type: RollingUpdate # rollingUpdate: # maxUnavailable: 0 # maxSurge: 1 strategy: {} terminationGracePeriodSeconds: 90 topologySpreadConstraints: [] # - maxSkew: 1 # topologyKey: kubernetes.io/hostname # whenUnsatisfiable: DoNotSchedule # labelSelector: # matchLabels: # app: litellm # At the time of writing, the litellm docker image requires write access to the # filesystem on startup so that prisma can install some dependencies. podSecurityContext: {} securityContext: {} # capabilities: # drop: # - ALL # readOnlyRootFilesystem: false # runAsNonRoot: true # runAsUser: 1000 # A list of Kubernetes Secret objects that will be exported to the LiteLLM proxy # pod as environment variables. These secrets can then be referenced in the # configuration file (or "litellm" ConfigMap) with `os.environ/` environmentSecrets: [] # - litellm-env-secret # A list of Kubernetes ConfigMap objects that will be exported to the LiteLLM proxy # pod as environment variables. The ConfigMap kv-pairs can then be referenced in the # configuration file (or "litellm" ConfigMap) with `os.environ/` environmentConfigMaps: [] # - litellm-env-configmap service: type: ClusterIP port: 4000 # If service type is `LoadBalancer` you can # optionally specify loadBalancerClass # loadBalancerClass: tailscale # Probes for LiteLLM gateway container livenessProbe: path: /health/liveliness initialDelaySeconds: 0 periodSeconds: 15 timeoutSeconds: 5 successThreshold: 1 failureThreshold: 5 readinessProbe: path: /health/readiness initialDelaySeconds: 0 periodSeconds: 10 timeoutSeconds: 5 successThreshold: 1 failureThreshold: 3 startupProbe: path: /health/readiness initialDelaySeconds: 0 periodSeconds: 10 timeoutSeconds: 5 successThreshold: 1 failureThreshold: 30 ingress: enabled: false className: "nginx" labels: {} annotations: {} # kubernetes.io/ingress.class: nginx # kubernetes.io/tls-acme: "true" hosts: - host: api.example.local paths: - path: / pathType: ImplementationSpecific tls: [] # - secretName: chart-example-tls # hosts: # - chart-example.local # masterkey: changeit # if set, use this secret for the master key; otherwise, autogenerate a new one masterkeySecretName: "" # if set, use this secret key for the master key; otherwise, use the default key masterkeySecretKey: "" # Optional: enterprise billable-request metering. When enabled, the proxy counts # successful requests to inference, MCP, and A2A endpoints and pushes them to # LiteLLM's collector over mutual TLS. Requires an enterprise license. # The client certificate identifies the deployment, so it is mounted read-only # from an existing Secret and never passed through the environment. billingMetrics: enabled: false endpoint: https://telemetry.litellm.ai # collector to push the counter to secretName: litellm-billing-metrics-mtls # existing Secret holding tls.crt and tls.key # Only for private or test collectors whose server certificate is not on the # public web PKI. The production collector needs no CA override. caSecretName: "" # existing Secret holding ca.crt exportIntervalMs: "" # push cadence; the proxy defaults to 60000 proxyConfigMap: # when true, creates a new configmap create: true # if create is false and name is set, use existing ConfigMap # create: false # name: "" # key: "config.yaml" # The elements within proxy_config are rendered as config.yaml for the proxy # Examples: https://github.com/BerriAI/litellm/tree/main/litellm/proxy/example_config_yaml # Reference: https://docs.litellm.ai/docs/proxy/configs proxy_config: model_list: # At least one model must exist for the proxy to start. - model_name: gpt-3.5-turbo litellm_params: model: gpt-3.5-turbo api_key: eXaMpLeOnLy - model_name: fake-openai-endpoint litellm_params: model: openai/fake api_key: fake-key api_base: https://exampleopenaiendpoint-production.up.railway.app/ general_settings: master_key: os.environ/PROXY_MASTER_KEY resources: {} # Unset by default so the chart installs on small clusters such as Minikube, and so an # upgrade never leaves a running pod Pending. Production deployments should set these. # A proxy at DB-connected steady state needs about 1 CPU and 4Gi of memory per worker; # sizing below that gets the pod OOMKilled once traffic and DB connections ramp up. # Scale both figures with --num_workers, then uncomment the lines below and remove the # curly braces after 'resources:'. See "Recommended Machine Specifications" in # https://docs.litellm.ai/docs/proxy/prod. # requests: # cpu: "1" # memory: 4Gi # limits: # cpu: "1" # memory: 4Gi autoscaling: enabled: false minReplicas: 1 maxReplicas: 100 # 60 is the documented recommendation. See "Recommended Machine Specifications" # in https://docs.litellm.ai/docs/proxy/prod. A new replica clears the startupProbe # above only after up to failureThreshold x periodSeconds = 300 seconds, so a target # high enough to trip near saturation adds capacity minutes after it was needed. targetCPUUtilizationPercentage: 60 # Deliberately left unset rather than given a value. The prisma query engine's # resident memory is a high-water mark that ratchets to the pod's worst-ever write # and is never returned, so a memory target reads the largest write a pod ever did # rather than what it is doing now, and replicas ratchet up without scaling back in. # Memory is a floor to provision under 'resources', not a signal to scale on. # targetMemoryUtilizationPercentage: 80 # behavior: {} # Autoscaling with keda is mutually exclusive with hpa keda: enabled: false minReplicas: 1 maxReplicas: 100 pollingInterval: 30 cooldownPeriod: 300 # fallback: # failureThreshold: 3 # replicas: 11 restoreToOriginalReplicaCount: false scaledObject: annotations: {} triggers: [] # - type: prometheus # metadata: # serverAddress: http://:9090 # metricName: http_requests_total # threshold: '100' # query: sum(rate(http_requests_total{deployment="my-deployment"}[2m])) behavior: {} # scaleDown: # stabilizationWindowSeconds: 300 # policies: # - type: Pods # value: 1 # periodSeconds: 180 # scaleUp: # stabilizationWindowSeconds: 300 # policies: # - type: Pods # value: 2 # periodSeconds: 60 # Additional volumes on the output Deployment definition. volumes: [] # - name: foo # secret: # secretName: mysecret # optional: false # Additional volumeMounts on the output Deployment definition. volumeMounts: [] # - name: foo # mountPath: "/etc/foo" # readOnly: true nodeSelector: {} tolerations: [] affinity: {} db: # Use an existing postgres server/cluster useExisting: false # How to connect to the existing postgres server/cluster endpoint: localhost database: litellm url: postgresql://$(DATABASE_USERNAME):$(DATABASE_PASSWORD)@$(DATABASE_HOST)/$(DATABASE_NAME) secret: name: postgres usernameKey: username passwordKey: password # Optional: when set, DATABASE_HOST will be sourced from this secret key instead of db.endpoint endpointKey: "" # Optional: when set, DATABASE_URL_READ_REPLICA will be sourced from this # secret key instead of db.readReplicaUrl. Prefer this over the plain # value: read-replica URLs typically embed credentials, and a value # written to db.readReplicaUrl ends up visible in the rendered pod spec # and the Helm release secret. readReplicaUrlKey: "" # Optional: when set, a DATABASE_READER_HOST env var is sourced from this # secret key, so db.readReplicaUrl can compose the reader URL from # individual secret components, e.g. # postgresql://$(DATABASE_USERNAME):$(DATABASE_PASSWORD)@$(DATABASE_READER_HOST):5432/$(DATABASE_NAME) # Use this when your secret store holds the bare reader hostname rather # than a full connection URL. Only takes effect when readReplicaUrl is # set; ignored when readReplicaUrlKey is set. readReplicaEndpointKey: "" # Optional read-replica routing. When set, the proxy sends read-only # queries (find_*, count, group_by, query_raw/_first) to this URL while # writes continue to go to db.url. Useful for Aurora-style clusters with # separate reader/writer endpoints. Leave empty to keep single-DB behavior. # When IAM_TOKEN_DB_AUTH is enabled, the reader URL is auto-refreshed # alongside the writer (host/port/user/db are parsed from this URL once # at startup; only the IAM token rotates). # # If the URL embeds credentials, prefer db.secret.readReplicaUrlKey over # this field — the plain value is rendered into the pod spec and the # Helm release secret. This field is intended for credential-less URLs # only (e.g. when IAM_TOKEN_DB_AUTH supplies the token at runtime). readReplicaUrl: "" # Use the Stackgres Helm chart to deploy an instance of a Stackgres cluster. # The Stackgres Operator must already be installed within the target # Kubernetes cluster. # TODO: Stackgres deployment currently unsupported useStackgresOperator: false # Use the Postgres Helm chart to create a single node, stand alone postgres # instance. See the "postgresql" top level key for additional configuration. deployStandalone: true # Lifecycle hooks for the LiteLLM container # # Prefer the native /health/drain preStop hook over a fixed `sleep`: it marks # the pod NotReady and blocks only until in-flight requests actually finish # (bounded by GRACEFUL_SHUTDOWN_TIMEOUT, default 30s), instead of always # waiting the worst-case duration. The drain runs once (the preStop hook and # the SIGTERM handler share it), so set terminationGracePeriodSeconds a few # seconds above GRACEFUL_SHUTDOWN_TIMEOUT to leave room for teardown before # SIGKILL. # # /health/drain is off by default; enable it with # general_settings.enable_drain_endpoint: true. The kubelet calls preStop # hooks without proxy credentials, so when the health port is reachable from # other pods (the common case) also set # general_settings.drain_endpoint_token (or the DRAIN_ENDPOINT_TOKEN env # var) and send the same value on the X-Drain-Token header from the hook. # Calls missing/wrong the token get a 401 and have no side effect. # Example: # lifecycle: # preStop: # httpGet: # path: /health/drain # port: 4000 # httpHeaders: # - name: X-Drain-Token # value: lifecycle: {} # Settings for Bitnami postgresql chart (if db.deployStandalone is true, ignored # otherwise) # # Bitnami retired the versioned tags under docker.io/bitnami and republished the # archived builds under docker.io/bitnamilegacy, so the subchart's own image # defaults no longer resolve. The repository below points at the same build the # subchart was released with, which keeps the on-disk data directory layout # identical for existing installs. # # Keep the tag pinned. docker.io/bitnami still publishes a floating `latest`, # and starting a newer PostgreSQL major against an existing data directory # leaves the server refusing to boot ("database files are incompatible with # server") with no way back other than a dump taken beforehand. Crossing a major # version is a dump-and-restore, not an image bump. The chart refuses to render # an unpinned tag for this reason postgresql: architecture: standalone image: repository: bitnamilegacy/postgresql tag: 16.2.0-debian-12-r6 volumePermissions: image: repository: bitnamilegacy/os-shell tag: 12-debian-12-r16 metrics: image: repository: bitnamilegacy/postgres-exporter tag: 0.15.0-debian-12-r14 auth: username: litellm database: litellm # You should override these on the helm command line with # `--set postgresql.auth.postgres-password=,postgresql.auth.password=` password: NoTaGrEaTpAsSwOrD postgres-password: NoTaGrEaTpAsSwOrD # A secret is created by this chart (litellm-helm) with the credentials that # the new Postgres instance should use. # existingSecret: "" # secretKeys: # userPasswordKey: password # Redis is the proxy's coordination store: cross-pod tpm/rpm rate limits, spend # tracking, and the pod lock manager. Enabling this deploys the bundled Redis # subchart, wires REDIS_HOST / REDIS_PORT / REDIS_PASSWORD into the proxy, and # renders a `general_settings.coordination_redis` block into the proxy config. # # To point at an existing Redis instead, leave `enabled: false` and pass a # secret for REDIS_HOST, REDIS_PORT, REDIS_PASSWORD or REDIS_URL; the proxy # falls back to those env vars for coordination. Set `cache: true` in the proxy # config only if you also want LLM response caching, which is independent of # coordination # # When `redis.sentinel.enabled` is set, the coordination block is rendered with # `sentinel_nodes` and `service_name` (from `redis.sentinel.masterSet`) instead # of host/port, because a plain Redis client cannot talk to the sentinel port # # The image repositories carry the same bitnamilegacy repoint as postgresql # above; the versioned tags the subchart ships with are gone from # docker.io/bitnami redis: enabled: false architecture: standalone image: repository: bitnamilegacy/redis tag: 7.2.4-debian-12-r9 sentinel: image: repository: bitnamilegacy/redis-sentinel tag: 7.2.4-debian-12-r7 metrics: image: repository: bitnamilegacy/redis-exporter tag: 1.58.0-debian-12-r4 volumePermissions: image: repository: bitnamilegacy/os-shell tag: 12-debian-12-r16 sysctl: image: repository: bitnamilegacy/os-shell tag: 12-debian-12-r16 kubectl: image: repository: bitnamilegacy/kubectl tag: 1.29.2-debian-12-r3 coordination: # Set to false to keep the bundled Redis for response caching only and leave # `general_settings.coordination_redis` out of the rendered config. A # `coordination_redis` block you define yourself in `proxy_config` always wins enabled: true # Prisma migration job settings migrationJob: enabled: true # Enable or disable the schema migration Job retries: 3 # Number of retries for the Job in case of failure backoffLimit: 4 # Backoff limit for Job restarts # Wall-clock budget for the whole Job, shared across every `backoffLimit` # retry rather than granted per attempt. Without it a migration that blocks # on the database never fails, and when the Helm hook is enabled the release # waits on it forever: `helm upgrade` and any GitOps controller driving it # stop reconciling the whole chart until someone deletes the Job by hand. # Set to null to opt out and restore the unbounded behaviour. activeDeadlineSeconds: 1800 disableSchemaUpdate: false # Skip schema migrations for specific environments. When True, the job will exit with code 0. # Optional service account for the migration job. # Only used when migrationJob.hooks.helm.enabled=true and serviceAccount.create=true. # In that case, pre-install/pre-upgrade hooks run before normal resources, so this defaults to "default". serviceAccountName: "" annotations: {} ttlSecondsAfterFinished: 120 resources: {} # Unset by default. This job runs the database migration and exits, so it does not # need the steady-state headroom the proxy does; size it from your own migration # runs rather than from the proxy figures above. extraContainers: [] extraInitContainers: [] # Hook configuration hooks: argocd: enabled: true helm: enabled: false # Log level for the litellm proxy (sets LITELLM_LOG in the deployment env). # Rendered as a direct `env:` entry, which in Kubernetes takes precedence over # any `envFrom:` source. If you currently source LITELLM_LOG from an # environmentSecret or environmentConfigMap, set `logLevel: ""` here to # disable injection — otherwise this value silently overrides your secret / # configmap entry. # # Setting LITELLM_LOG inside `envVars:` below also wins: the template skips # this injection entirely when envVars already defines LITELLM_LOG. logLevel: INFO # Additional environment variables to be added to the deployment as a map of key-value pairs envVars: {} # USE_DDTRACE: "true" # Additional environment variables to be added to the deployment as a list of k8s env vars extraEnvVars: {} # if you want to override the container command, you can do so here command: {} # if you want to override the container args, you can do so here args: {} # - name: EXTRA_ENV_VAR # value: EXTRA_ENV_VAR_VALUE # Additional Kubernetes resources to deploy with litellm extraResources: [] # - apiVersion: v1 # kind: ConfigMap # metadata: # name: my-extra-config # data: # foo: bar # Pod Disruption Budget pdb: enabled: false # Set exactly one of the following. If both are set, minAvailable takes precedence. minAvailable: null # e.g. "50%" or 1 maxUnavailable: null # e.g. 1 or "20%" annotations: {} labels: {} serviceMonitor: enabled: false labels: {} # test: test annotations: {} # kubernetes.io/test: test interval: 15s scrapeTimeout: 10s relabelings: [] # - targetLabel: __meta_kubernetes_pod_node_name # replacement: $1 # action: replace namespaceSelector: matchNames: [] # - test-namespace