Optimize custom workloads using CRDs

Configure Optimize Live to detect and optimize workloads defined by Custom Resource Definitions

By default, StormForge Optimize Live supports standard Kubernetes workload types such as Deployments, StatefulSets, and DaemonSets, as well as common third-party workload types, such as Argo Rollouts.

Optimize Live also supports custom workload types defined by Custom Resource Definitions (CRDs). If your CRD represents the workload itself, you can configure StormForge to recognize and optimize it using the workloadResourceTypes Helm parameter.

How Optimize Live handles custom workloads

  1. Discovery: The StormForge Agent monitors for resources matching the Group and Kind defined by the workloadResourceTypes Helm parameter.
  2. Recognition: StormForge treats discovered resources as workloads.
  3. Optimization: StormForge analyzes workload usage metrics and generates recommendations.
  4. Patching: StormForge generates one or more patches when a recommendation is applied. Different apply methods result in different kinds of patches.

Prerequisites

For StormForge to recognize your CRD as a workload type, ensure it meets the following requirements:

Define a custom workload type

Define custom workload types using the Helm parameter workloadResourceTypes in the StormForge Agent’s Helm configuration.

When defining a custom workload type, StormForge needs to know the resource’s API Group and Kind, and—to support patching—the specific CRD fields it might need to update.

Helm parameter: workloadResourceTypes

The workloadResourceTypes parameter is a list of objects with the following fields:

Field Description Required
group CRD API group (for example, actions.github.com). Yes
kind CRD Kind (for example, AutoscalingRunnerSet). Yes
resource API resource name (for example, autoscalingrunnersets). Yes
patchTargetTypeDefaults (Map) Default patch paths. Required for patching. Conditional

Patch target type defaults

StormForge uses patch paths to determine which workload fields to update when performing optimization operations.

Patch path values are Go templates that StormForge resolves into JSON pointers (with some extensions).

Common keys for patchTargetTypeDefaults:

  • live.stormforge.io/containers.cpu.requests.patch-path
  • live.stormforge.io/containers.cpu.limits.patch-path
  • live.stormforge.io/containers.memory.requests.patch-path
  • live.stormforge.io/containers.memory.limits.patch-path

Contact StormForge support for information on how to define patch path settings for your workload.

Example: GitHub ARC

Suppose you are hosting your own GitHub Actions runners with ARC, and you want to optimize the AutoscalingRunnerSet resource.

For StormForge to apply recommendations, you need to map ARC’s AutoScalingRunnerSet template and resource fields.

Accessing the memory and CPU requests involves navigating the spec to find the container template.

Your values.yaml may resemble the following:

workloadResourceTypes:
- group: actions.github.com
  kind: AutoscalingRunnerSet
  resource: autoscalingrunnersets
  # Configuration values for patch paths depend on your CRD structure.
  # For AutoscalingRunnerSet, the pod template is in the spec.
  patchTargetTypeDefaults:
    # Allows StormForge to rollout/restart the workload when recommendations are applied.
    live.stormforge.io/pod-template.metadata.patch-path: >
      /spec/template/metadata
    # These paths let StormForge patch the container resources on the workload
    # definition itself. Not required if using the webhook to patch pods on admission.
    live.stormforge.io/containers.cpu.requests.patch-path: >
      /spec/template/spec/containers/[name={{ .ContainerName }}]/resources/requests/cpu
    live.stormforge.io/containers.cpu.limits.patch-path: >
      /spec/template/spec/containers/[name={{ .ContainerName }}]/resources/limits/cpu
    live.stormforge.io/containers.memory.requests.patch-path: >
      /spec/template/spec/containers/[name={{ .ContainerName }}]/resources/requests/memory
    live.stormforge.io/containers.memory.limits.patch-path: >
      /spec/template/spec/containers/[name={{ .ContainerName }}]/resources/limits/memory
Last modified February 5, 2026