HelmRepository: use conditional HTTP requests (ETag / If-Modified-Since) when fetching index.yaml
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 48/100
- Issue type
- Feature
- Clarity
- Mostly clear
- Activity status
- Quiet
- Tech stack
- go, kubernetes
- Domain
- backend, performance
Research direction
Start in internal/helm/repository/chart_repository.go at CacheIndex and DownloadIndex, then trace the no-op decision in internal/controller/helmrepository_controller.go around lines 464-468. Verify how response validators can be retained per object and how a 304 reaches the existing unchanged path without reading the body. Done means conditional requests are used when validators exist, while repositories without validators retain current behavior.
Written by the indexing model from the issue text.
Description
Problem
For HTTP(S) HelmRepository objects, source-controller downloads the full index.yaml on every reconcile interval, unconditionally: CacheIndex → DownloadIndex issues a plain GET, and only after the download completes is the digest compared against the current artifact to decide the reconcile is a no-op (helmrepository_controller.go#L464-L468). There is no If-None-Match / If-Modified-Since anywhere in the fetch path (the only ETag references in the codebase are the S3/GCS test mocks).
Real-world indexes are large (grafana ~2 MB, prometheus-community ~4 MB, bitnami historically >10 MB), and the cost is linear in the number of objects: N HelmRepository objects pointing at the same or different repos re-download N full indexes per interval, forever, even when nothing changed. In multi-tenant setups where each tenant namespace declares its own HelmRepository (cross-namespace refs disabled), N grows with the tenant count.
Measurements
Bench: k3s + source-controller v1.9.3, defaults; one HTTP helm repo with a 6.0 MB index; N HelmRepository objects with interval: 1m; server-side byte/request counters; idle steady state (index unchanged), 5-minute windows.
| N objects | index GETs / 5 min | bytes / 5 min | projected / day |
|---|---|---|---|
| 1 | 5 | 31.0 MB | 1,440 GETs / 8.9 GB |
| 10 | 50 | 309.7 MB | 14,400 GETs / 89 GB |
| 50 | 249 | 1.54 GB | ~72,000 GETs / ~444 GB |
Every one of those bytes is thrown away: the digest comparison concludes "unchanged" after each download.
Proposal
Remember the ETag / Last-Modified response headers per object (an in-memory map keyed by object UID is sufficient — a controller restart just pays one full fetch), and send If-None-Match / If-Modified-Since on the next reconcile. On 304 Not Modified, short-circuit to the existing no-op path without touching the body. When the server sends no validators, behaviour is unchanged.
GitHub Pages, S3/CloudFront, Cloudflare, nginx/static hosting and Harbor all emit validators for static index files, so the common cases are covered.
This mirrors what the controller already does for the other source kinds — GitRepository checks advertised refs before cloning, OCIRepository resolves the manifest digest via HEAD before pulling — HelmRepository/HTTP is the only kind that must download the full payload to discover nothing changed.
Happy to send the PR.
- Dominant language
- Go
- Stars
- 283
- Forks
- 252
- Avg merge
- 1h 6m
- Merged PRs (30d)
- 12
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from fluxcd/source-controller
-
area/docs good first issue help wanted
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
fluxcd/source-controller#666 · 2 comments ·
-
area/git bug
Difficulty 4/5 3-5 days Newbie friendliness 55/100
fluxcd/source-controller#2165 · 3 comments ·
-
Difficulty 4/5 3-5 days Newbie friendliness 45/100
fluxcd/source-controller#2150 ·
-
GitRepository `.spec.ref.commit` + `.spec.ref.branch` does not shallow clone, contrary to the docs Open
Difficulty 5/5 Over a week Newbie friendliness 42/100
fluxcd/source-controller#2146 · 2 comments ·
-
Difficulty 4/5 3-5 days Newbie friendliness 55/100
fluxcd/source-controller#2136 · 1 comment ·
All issues in fluxcd/source-controller
Similar issues
-
area/dev-productivity area/disaster-recovery area/ipcei kind/enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
-
Difficulty 1/5 Under an hour Newbie friendliness 85/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
-
kind/bug status/0-triage
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
-
🤔 refinement needed
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
equinor/radix-operator#1979 ·