What does HELM_DRIVER change, and what happens to existing releases when you switch it?
answer
- An environment variable, read per invocation
- Four backends, one of them the default
- Two of them are not for production use
- Nothing is migrated when you change it
- The external option needs a connection string
basics
~20 sHELM_DRIVER selects where Helm persists release records: secret (the default), configmap, memory, or sql against PostgreSQL. Switching does not migrate anything — records written under one driver are simply invisible under another, so releases disappear from helm list.
solid answer
~40 s`HELM_DRIVER` picks Helm's release storage backend. `secret` is the default and writes one Secret per revision in the release namespace; `configmap` writes the equivalent ConfigMaps; `memory` keeps the state in the process and loses it on exit, which is for embedding and tests, not for real clusters; `sql` persists to an external PostgreSQL database given by `HELM_DRIVER_SQL_CONNECTION_STRING`. It is read per invocation from the environment, so it must be set identically everywhere — a CI job with the variable set and an engineer's shell without it see different worlds. There is no migration: switching drivers does not move existing records, so previously installed releases vanish from `helm list`, and an `upgrade --install` will try to install fresh over objects that still carry the old release's ownership metadata.
code
bash · 3 linesexport HELM_DRIVER=sql
export HELM_DRIVER_SQL_CONNECTION_STRING='postgresql://helm@releases-db:5432/helm?sslmode=require'
helm list -n telemetrygo deeper
Know that the default backend is a Secret per revision and that HELM_DRIVER exists to change it. You are not expected to have run a non-default backend, only to recognise the variable when you see it in a pipeline.
Name all four values and say what each is for, then explain the key mechanic: no migration happens, so releases written under one backend are invisible under another and the next upgrade --install turns into a failing fresh install.
Show the diagnosis: an empty helm list with the workloads plainly running points at namespace, context or driver, and the driver is the one people miss. Insist the variable be set in one shared place rather than per job.
Own the trade. Keeping release state beside the workloads means one backup, one RBAC story and no extra dependency in the rollback path; moving it to an external database buys size and scale headroom and costs you a hard dependency on deploy and a split recovery story.
### What the driver actually is Helm's release storage is an interface with a handful of implementations, chosen at runtime from the `HELM_DRIVER` environment variable. Everything above it — install, upgrade, history, rollback, list, status — is written against that interface, which is why the command surface is identical no matter which backend is in use, and why the driver is an environment variable rather than a flag on individual commands. The four implementations: **`secret` (default).** One Secret per revision, in the release's namespace, typed `helm.sh/release.v1`. State travels with the namespace, inherits whatever Secret protections the cluster applies, and needs no infrastructure at all. **`configmap`.** The same records in ConfigMaps instead. Functionally equivalent for Helm's purposes, but it puts the stored values — which routinely include credentials someone passed at install time — into an object class that many clusters treat as non-sensitive: different RBAC habits, different treatment in logs and dumps, and outside whatever protections are applied to Secrets. There is essentially no reason to choose it today; you meet it on inherited setups. **`memory`.** State lives in the process and dies with it. This exists for embedding Helm as a library and for tests. Run a CLI install under it and the release is gone the moment the command exits, while the objects it applied stay behind. **`sql`.** Records go to an external PostgreSQL database, addressed by `HELM_DRIVER_SQL_CONNECTION_STRING`. This is the escape hatch for estates where cluster-object storage is the constraint: it removes the per-object size ceiling that bites on very large charts, and it moves thousands of revision records out of the cluster's own datastore. ### Switching is not migrating This is the part interviews probe. Nothing in Helm converts existing records from one backend to another. The drivers do not read each other's storage; they do not even look. So the moment you export a different `HELM_DRIVER`, every release installed under the previous one becomes invisible: `helm list` returns nothing, `helm history` reports the release is not found, `helm status` fails. The dangerous shape of that is not the empty list — it is the next deploy. A pipeline running `helm upgrade --install gateway ./chart` finds no record, decides this is a fresh install, and tries to create every object in the chart. Those objects already exist, and they carry the ownership metadata of the release Helm has forgotten, so the install fails partway with an ownership conflict, leaving a brand-new failed revision record in the new backend and a live workload that is now managed by nobody. Recovering means either switching the variable back, or deliberately re-adopting the existing objects into the new record. The same trap appears without anyone intending a migration, because the variable is per-invocation and per-environment. A CI image that exports `HELM_DRIVER=sql` while engineers debug from laptops without it produces two teams looking at the same cluster and disagreeing about which releases exist. If you use a non-default driver at all, it belongs in the shared wrapper or the base image every path goes through, not in one job's environment block. ### Choosing one For almost every estate the answer is: leave it alone. The default keeps release state in the same namespace, under the same RBAC and the same backup as the workloads it describes, with no extra component to run, no credential to distribute, and no second thing that can be down when you need to roll back at 2 a.m. The honest case for `sql` is scale and size: a very large chart whose record does not fit in a single cluster object, or an estate with enough releases and enough revisions that the accumulated records are a real load on the cluster's datastore. What you trade away is significant — release state now lives outside the cluster it describes, so a cluster restore no longer restores release history, the database becomes a hard dependency of every deploy and every rollback, and the connection string is a credential that every deploying identity must hold. Take that trade knowingly, and only after checking that the cheaper lever — retention, and shrinking what the chart carries — has been pulled. `configmap` and `memory` are not deployment choices. Treat seeing `configmap` in a live estate as inherited configuration to unwind rather than a preference to respect, and treat `memory` as a signal that somebody is embedding Helm rather than operating it. ### Where it shows up in diagnosis When a release that certainly exists is absent from `helm list`, the checks are: right namespace, right cluster context, and right driver. The third is the one people forget, and it is the only one that produces a completely empty listing while every workload the release created is visibly running.
- A release is running, but helm list in the right namespace shows nothing. How do you tell a driver mismatch from a wrong-context mistake?Check the cluster context first, then look directly for the records: list Secrets of type `helm.sh/release.v1` in the namespace. If the records are there but Helm reports nothing, your `HELM_DRIVER` is pointing somewhere else — unset it and retry. If the records genuinely are not there, either you are on the wrong cluster or the release was installed under a different backend, and the live objects' ownership metadata will tell you which release name to look for.
- What would make you move an estate to the sql driver, and what do you give up?Two things justify it: a chart whose release record cannot fit in a single cluster object, or so many releases and revisions that the records are a real load on the cluster datastore. The cost is that release state leaves the cluster it describes — a cluster restore no longer restores release history, every install and rollback now depends on a reachable database, and the connection string becomes a credential every deploying identity holds.
saying these in an interview costs you the question
- Thinks changing HELM_DRIVER migrates existing release records
- Says the driver is a flag on install rather than an environment variable
- Believes the memory driver is a lightweight production option
- Treats the configmap backend as equivalent in exposure to secrets
- Assumes the sql backend still keeps release state inside the cluster