Skip to main content

Optimizing Chart Performance

1. Minimizing Template Complexity

Template Type Description Impact on Performance Best Practice
Loops Iterating over lists or maps in templates High - nested loops increase rendering time Limit nesting levels to 2-3 levels max
Conditions Using {{ if }} blocks to conditionally render content Medium - multiple conditions increase template size Use {{- if }} to reduce whitespace; avoid deep nesting
Functions Using built-in or custom template functions High - complex functions can slow rendering Precompute values in values.yaml where possible
Partials Reusing templates via {{ include }} Medium - repeated includes increase memory usage Use {{- include }} to reduce whitespace; cache includes

Example: Reducing Template Complexity

# Instead of this:
{{- range .Values.items }}
  {{- if eq .type "web" }}
    <div class="web-item">
      <h3>{{ .name }}</h3>
      <p>{{ .description }}</p>
    </div>
  {{- end }}
{{- end }}

# Prefer this:
{{- range .Values.items }}
  {{- if eq .type "web" }}
    <div class="web-item">
      <h3>{{ .name }}</h3>
      <p>{{ .description }}</p>
    </div>
  {{- end }}
{{- end }}
Note: Complex templates increase the time required to render Kubernetes resources during chart installation or upgrade.

Key Tips for Minimizing Template Complexity

  • Avoid deeply nested {{ range }} and {{ if }} blocks
  • Use {{- include }} for reusable templates but avoid excessive reuse
  • Precompute values in values.yaml to reduce runtime logic
  • Use {{- if }} and {{- range }} to reduce whitespace in rendered output

2. Caching Template Results

Property Description Default Notes
helm.template.cache Enables caching of rendered templates false Improves performance by avoiding re-rendering of templates
helm.template.cache.ttl Time-to-live for cached templates (in seconds) 300 Set to 0 to disable TTL and cache indefinitely

Example: Enabling Template Caching

helm.template.cache: true
helm.template.cache.ttl: 600
Note: Caching is particularly effective in environments with frequent template reuse, such as CI/CD pipelines or high-traffic deployments.

3. Reducing Value Lookups

Approach Description Impact
Nested values config.database.host Increases lookup depth and complexity
Flattened values database.host Reduces nesting and improves performance

Example: Flattening nested values

# Before
config:
  database:
    host: "localhost"
    port: 5432

# After
database:
  host: "localhost"
  port: 5432
Note: Flattening values improves performance by reducing the number of lookups required to access configuration data.

4. Optimizing Loop Iterations

Feature Description Best Practice
range Iterates over a list or array in templates Use range for looping over lists of resources or configurations
until Repeats a block until a condition is met Use until for conditional rendering or retries in templates

Example: Looping over a list of services

services:
{{- range .Values.services }}
  - name: {{ .name }}
    port: {{ .port }}
{{- end }}

Example: Using until for retry logic

retries: {{ .Values.maxRetries }}
{{- range until (add .Values.maxRetries 1) }}
attempt: {{ . }}
{{- end }}
Note: Avoid deeply nested loops as they can impact chart rendering performance.

5. Using Conditional Rendering

Conditional rendering in Helm charts allows you to include or exclude resources based on values, improving chart flexibility and reducing unnecessary resource creation.

Property Description Usage
enabled Boolean flag to enable or disable a resource resources.enabled: true
nameOverride Override the default resource name resources.nameOverride: "custom-name"
labels Labels to apply to the resource resources.labels.app: "myapp"

Example: Conditional Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "mychart.fullname" . }}-deployment
  labels:
    {{- include "mychart.labels" . | nindent 4 }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      {{- include "mychart.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      {{- with .Values.podAnnotations }}
      annotations:
        {{- toYaml . | nindent 8 }}
      {{- end }}
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
          ports:
            - name: http
              containerPort: 80
              protocol: TCP

Example: Conditional Service

{{- if .Values.service.enabled }}
apiVersion: v1
kind: Service
metadata:
  name: {{ include "mychart.fullname" . }}-service
  labels:
    {{- include "mychart.labels" . | nindent 4 }}
spec:
  type: {{ .Values.service.type }}
  ports:
    - port: {{ .Values.service.port }}
      targetPort: http
      protocol: TCP
      name: http
  selector:
    {{- include "mychart.selectorLabels" . | nindent 4 }}
{{- end }}
Note: Use .Values.service.enabled to conditionally render the service resource. This allows users to disable services when they are not needed.

6. Minimizing File Reads

Configuration Description Impact
template.cache Enables caching of rendered templates to reduce file I/O Reduces repeated reads of template files
values.yaml Preload values to avoid repeated file reads during chart rendering Improves performance by reducing disk access
configMap Use configMaps to externalize configuration and reduce file reads Minimizes repeated file system access

Example: Using configMap to reduce file reads

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  config.yaml: |
    server:
      port: 8080
      host: localhost
Note: Caching strategies can significantly reduce file I/O in high-traffic environments.

7. Reducing Chart Size

Reducing the size of Helm charts is crucial for faster deployments, reduced storage requirements, and improved network efficiency. Smaller charts mean quicker downloads and less resource consumption during deployment.

Approach Description Impact
Exclude unnecessary files Use .helmignore to exclude large or irrelevant files such as logs, temporary files, or development artifacts. Significant reduction in chart size
Compress resources Compress large configuration files or templates using gzip or similar tools before including them in the chart. Moderate reduction in size
Use imagePullSecrets Specify imagePullSecrets in values.yaml to avoid embedding credentials directly in templates or manifests. Minimal size impact
Optimize Docker images Use multi-stage builds and minimal base images to reduce the size of container images referenced in the chart. Indirect size reduction

Example: Using .helmignore to exclude files

# .helmignore
.git
.gitignore
README.md
*.log
.env
Note: The .helmignore file works similarly to .gitignore, allowing you to exclude files and directories from being packaged into the chart.

8. Optimizing Dependencies

Dependency Type Version Notes
nginx chart 15.2.0 Used for reverse proxy and load balancing
postgresql chart 12.1.0 Primary database for application data
redis chart 17.0.0 Caching layer for performance

Example: Dependency Configuration

dependencies:
  - name: nginx
    version: 15.2.0
    repository: https://kubernetes.github.io/nginx
  - name: postgresql
    version: 12.1.0
    repository: https://charts.bitnami.com/bitnami
  - name: redis
    version: 17.0.0
    repository: https://charts.bitnami.com/bitnami
Note: Use specific versions to ensure reproducible deployments.
Warning: Avoid using ">=1.0.0" in dependency versions to prevent unexpected upgrades.

Best Practices for Dependency Optimization

  • Pin dependency versions to specific releases
  • Use official repositories for verified charts
  • Minimize the number of dependencies to reduce complexity
  • Regularly audit dependencies for security vulnerabilities

9. Using Lazy Evaluation

Lazy evaluation in Helm charts allows for deferred execution of template logic, which can improve performance by avoiding unnecessary computations or resource lookups.

Feature Description Usage
.Values.lazy Flag to enable lazy evaluation for specific values {{- if .Values.lazy -}} {{- $value := .Values.someValue | default "default" -}} {{- end }}
tpl function Template function to evaluate templates at runtime {{ tpl "{{ .Values.key }}" . }}

Example: Lazy Value Computation

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ include "chart.name" . }}-config
data:
  config.yaml: |
    {{- $lazyValue := include "chart.lazyValue" . }}
    {{- if $lazyValue }}
    value: {{ $lazyValue }}
    {{- end }}
Note: Lazy evaluation is particularly useful in large charts where some values may not be needed in all environments or scenarios.

10. Profiling Chart Rendering

Profile Type Description Command Notes
render Render chart templates to stdout helm template <release-name> <chart-path> Useful for debugging template issues
lint Validate chart structure and syntax helm lint <chart-path> Checks for common issues and best practices
get Retrieve values or chart metadata helm get <release> Can be used to inspect rendered values

Example: Render chart with debug output

helm template my-release ./my-chart --debug
Note: Use --debug flag to see detailed template rendering steps.
Warning: Large charts may produce extensive output when using helm template.

Performance Tips

  • Use helm template --debug to identify slow rendering steps
  • Validate charts with helm lint to catch structural issues early
  • Minimize use of complex template functions in loops

Was this article helpful?