Helm
Helm packages Kubernetes applications into versioned, configurable charts for repeatable installs and upgrades. Learn charts, values and releases.
Overview
Helm is the package manager for Kubernetes. A Kubernetes application is usually not one file but a bundle of many: a Deployment, a Service, a ConfigMap, a Secret, an Ingress, perhaps a ServiceAccount and some role bindings. Helm groups these files into a single versioned package called a chart, lets you fill in the parts that change between environments, and installs, upgrades or removes the whole bundle with one command.
An everyday picture helps. Think of a flat-pack furniture kit. The kit contains every panel and screw, an instruction sheet, and a few choices printed on the box: colour, height, left or right door. You do not redesign the wardrobe each time; you pick the options and assemble it. A Helm chart is the kit, the values file holds your choices, and a release is the wardrobe standing in a particular room. If the new version wobbles, Helm can put back the previous one.
Helm matters for AI and data teams because the systems they run on Kubernetes are rarely simple. A model server, a vector database, a monitoring stack or a workflow engine is often shipped by its maintainers as a Helm chart. Knowing how charts, values and releases work is therefore a basic skill for anyone deploying vLLM, KServe, Prometheus or Grafana into a cluster.
What it is
Helm has a small number of core parts.
| Part | What it is | Example |
|---|---|---|
| Chart | A directory or archive of templates, defaults and metadata describing one application | A chart for a model-serving API |
Chart.yaml |
The chart's metadata: name, version, app version, dependencies | version: 1.4.0, appVersion: 2.3.1 |
values.yaml |
Default configuration values the templates read | Replica count, image tag, resource limits |
| Templates | Kubernetes manifests written with Go template syntax | deployment.yaml using {{ .Values.replicaCount }} |
| Release | One installed instance of a chart in a cluster, with a name and a revision history | fraud-api in namespace prod, revision 7 |
| Repository | A place that stores packaged charts for others to install | An HTTP chart repository or an OCI registry |
| Helm client | The helm command-line tool and its Go SDK |
helm install, helm upgrade, helm rollback |
The key idea is the split between a chart, which is reusable, and values, which are specific to one installation. The same chart can be installed in development with one replica and no GPU, and in production with six replicas and GPU limits, simply by supplying different values files.
Where it came from
Helm began in 2015 as a project at Deis, introduced at the first KubeCon. That early version is now called Helm Classic. In January 2016 it merged with Google's Kubernetes Deployment Manager and moved under the Kubernetes project, and Helm 2.0 followed later in 2016. Helm 2 relied on an in-cluster component called Tiller, which applied changes on the client's behalf.
In June 2018 Helm became a full project of the Cloud Native Computing Foundation (CNCF). Helm 3, released in November 2019, removed Tiller entirely, so the client talks to the Kubernetes API directly and uses the user's own permissions. Helm graduated within the CNCF in April 2020.
Helm 4.0.0 was released on 12 November 2025 at KubeCon + CloudNativeCon North America, marking ten years of the project. Helm 4 makes server-side apply the default for new installations, redesigns the plugin system with an optional WebAssembly runtime, improves OCI registry handling such as installing a chart by digest, and stabilises the Go SDK. Existing charts using API version v2 keep working; a new chart API version v3 is experimental. The Helm project has stated that Helm 3 receives bug fixes until 9 September 2026 and security fixes until 10 February 2027.
How it works
1. Write or fetch a chart
A chart is a folder with Chart.yaml, values.yaml and a templates/ directory. helm create generates a starter. Most teams also install third-party charts from repositories or OCI registries.
2. Merge the values
When you install or upgrade, Helm builds one set of values by layering sources in order: the chart's values.yaml, then any files passed with -f, then individual --set flags. Later sources override earlier ones. A values.schema.json file, if present, validates the result so that a typo such as replicas: "three" fails early.
3. Render the templates
Helm runs every template through the Go template engine with the merged values, plus built-in objects such as .Release.Name and .Chart.Version. Helper functions from the Sprig library add string, list and maths operations. The output is plain Kubernetes YAML. You can see it without touching the cluster by running helm template.
4. Apply to the cluster
Helm sends the rendered manifests to the Kubernetes API. With Helm 4, new releases use server-side apply by default, which lets the API server track which tool owns which fields. Releases created by Helm 3 keep their earlier apply method unless you opt in.
5. Record the release
Helm stores a record of each revision, by default as a Secret in the release's namespace. The record holds the chart, the values and the rendered manifest. This history is what makes helm history and helm rollback possible.
6. Hooks and tests
Charts can define hooks that run at points in the lifecycle, such as a database migration job before an upgrade. A chart can also include test pods that helm test runs after installation to check the application responds.
A short, realistic session looks like this:
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm install monitoring prometheus-community/kube-prometheus-stack -n monitoring --create-namespace -f values-prod.yaml
helm upgrade monitoring prometheus-community/kube-prometheus-stack -n monitoring -f values-prod.yaml
helm history monitoring -n monitoring
helm rollback monitoring 1 -n monitoring
Key concepts and terms
| Term | Meaning |
|---|---|
| Chart | A package of templates, defaults and metadata for one application. |
| Values | Configuration inputs that templates read; supplied by files or flags. |
| Release | A named, installed instance of a chart in one namespace. |
| Revision | A numbered version of a release, created on each install, upgrade or rollback. |
| Template | A Kubernetes manifest with Go template placeholders. |
| Subchart | A chart included as a dependency of another chart. |
| Library chart | A chart that only provides shared template helpers, with nothing to install. |
| Hook | A resource run at a lifecycle point, such as pre-install or post-upgrade. |
| OCI registry | A container registry that also stores charts as OCI artefacts. |
| Server-side apply | A Kubernetes apply mode where the API server tracks field ownership. |
| Post-renderer | A step that modifies rendered manifests before they are applied. |
A worked example
This scenario is illustrative. A small machine learning team runs a fraud-scoring API in three environments: development, staging and production. Before Helm, each environment had its own copy of eight YAML files, and copies drifted. A staging fix for a memory limit never reached production.
The team creates one chart, fraud-api, version 1.0.0. The templates read four groups of values: image tag, replica count, resources and model storage path. They write three small files: values-dev.yaml sets 1 replica and 2 GiB of memory; values-staging.yaml sets 2 replicas and 4 GiB; values-prod.yaml sets 6 replicas, 8 GiB and one GPU per pod.
Deploying a new model version now means changing one line, the image tag, and running helm upgrade fraud-api ./chart -f values-prod.yaml. Helm records revision 12. Ten minutes later monitoring shows error rates rising from 0.2% to 3%. The on-call engineer runs helm rollback fraud-api 11, and the previous manifests return within a minute. The team then adds a values.schema.json so that a missing GPU setting fails validation instead of reaching the cluster.
Strengths and limitations
Strengths:
- One package and one command for a multi-resource application.
- Clear separation between reusable chart and per-environment values.
- Release history with straightforward rollback.
- A very large ecosystem; many open-source projects publish official charts.
- Charts can be stored in the same OCI registries as container images.
Limitations:
- Go templates applied to YAML are easy to break with indentation and quoting errors.
- Complex charts with many conditionals become hard to read and review.
- Helm state lives in the cluster, which can diverge from what is in Git unless a GitOps tool enforces it.
- Custom resource definitions (CRDs) have special handling and are not upgraded like normal templates.
- A chart can hide insecure defaults if values are not reviewed.
How it compares with alternatives
| Approach | How it works | When it fits better |
|---|---|---|
Plain manifests with kubectl apply |
Apply static YAML files directly | Very small applications with no environment differences |
| Kustomize | Overlays and patches over base YAML, no templating | Teams who prefer pure YAML and small per-environment changes |
| Argo CD | GitOps controller that syncs clusters from Git; can render Helm charts | Continuous, auditable delivery; often used together with Helm |
| Terraform Helm provider | Manages Helm releases as infrastructure resources | Teams already managing clusters and cloud resources in Terraform |
| Kubernetes operators | Custom controllers that manage an application's full lifecycle | Stateful systems needing ongoing automated operations, such as databases |
Helm and these tools are often combined rather than chosen between: a common pattern is Helm charts, rendered and synced by Argo CD, on clusters created by Terraform. See also infrastructure as code.
Practical guidance and best practices
- Keep templates simple; push logic into named helpers in
_helpers.tpland avoid deeply nested conditionals. - Add a
values.schema.jsonso invalid values fail before anything reaches the cluster. - Run
helm lintandhelm templatein CI, and review the rendered YAML, not just the templates. - Version charts with semantic versioning and bump
versionon every change; keepappVersionfor the application itself. - Pin dependency and image versions; never rely on
latesttags in production values. - Store secrets outside plain values files, using a secrets manager such as HashiCorp Vault or an encrypted secrets workflow.
- Use
--atomicor wait-and-rollback behaviour in pipelines so failed upgrades do not leave half-applied releases. - Prefer installing third-party charts by version or digest from trusted sources, and read their default values before use.
- Plan the move from Helm 3 to Helm 4 before Helm 3 security support ends in February 2027, and test plugins and post-renderers first.
Common mistakes
- Editing resources by hand with
kubectlafter a Helm install, then losing those edits on the next upgrade. - Committing passwords and API keys in
values.yaml. - Using
--setfor many values in scripts, which makes the real configuration hard to reproduce. - Forgetting that CRDs in a chart's
crds/folder are not upgraded or deleted automatically. - Copying a public chart and modifying it heavily instead of wrapping it as a dependency, making updates painful.
- Leaving default resource requests empty, so GPU or memory-heavy pods are scheduled badly.
Frequently asked questions
Is Helm required to use Kubernetes?
No. Kubernetes works with plain manifests. Helm adds packaging, configuration and release history, which become valuable once an application has many resources or several environments.
What is the difference between chart version and app version?
The chart version describes the package itself and changes whenever the chart changes. The app version describes the software the chart deploys, such as the container image release. They often move independently.
Does Helm still use Tiller?
No. Tiller was removed in Helm 3, released in November 2019. The Helm client talks directly to the Kubernetes API using the caller's credentials.
Should I upgrade to Helm 4?
For new work, yes, because Helm 4 is the current major version and Helm 3 is approaching the end of its support window, with security fixes announced until 10 February 2027. Test plugins, post-renderers and any automation that parses Helm output before switching.
Can I store Helm charts in a container registry?
Yes. Helm supports OCI registries, so charts can be pushed and pulled alongside container images, and Helm 4 can install a chart by its digest.
How does Helm work with GitOps?
Tools such as Argo CD can render a Helm chart from Git and keep the cluster in sync with it. Git becomes the source of truth, and Helm provides the packaging and templating.
Glossary
- Chart: a versioned package describing a Kubernetes application.
- Values file: a YAML file of settings that customises a chart.
- Release: an installed instance of a chart.
- Rollback: returning a release to an earlier revision.
- Go template: the text templating language Helm uses.
- Sprig: a library of template functions available in Helm.
- Hook: a lifecycle-triggered resource such as a migration job.
- OCI: the Open Container Initiative format used by container registries.
- Namespace: a Kubernetes scope that groups resources.
- Tiller: the in-cluster server component used by Helm 2 and removed in Helm 3.
Summary
Helm packages Kubernetes applications as charts, combines them with per-environment values, and installs them as releases with a history that supports rollback. It started at Deis in 2015, removed Tiller in Helm 3 in 2019, graduated in the CNCF in 2020, and reached Helm 4 in November 2025 with server-side apply by default, a new plugin system and better OCI support. It is most useful when kept simple, validated with schemas, tested in CI and paired with a GitOps tool so that the cluster always matches what is reviewed in Git.
Related
It belongs to Platform in my stack, under MLOps and AI infrastructure. Others in the same group: