Optimize performance

Red Hat OpenShift Dev Spaces 3.29

Make workspaces start faster and scale to meet demand

Abstract

Speed up workspace starts with image caching and scale your deployment automatically to handle growing teams.

Preface

Make workspaces start faster and scale your OpenShift Dev Spaces deployment to handle growing teams. Image caching removes cold-start delays, and autoscaling ensures the platform adapts to demand without manual intervention.

Chapter 1. What you can optimize in OpenShift Dev Spaces

Identify the performance areas you can tune in OpenShift Dev Spaces so that you choose the right optimization strategy for your deployment.

A default OpenShift Dev Spaces installation runs all server components with a single replica and no image pre-caching. This configuration works for small teams but can cause slow workspace starts and limited capacity as usage grows. You can optimize two areas independently:

Workspace startup speed
When a developer starts a workspace, OpenShift pulls container images from the registry. On a cold node, this can take several minutes. The Kubernetes Image Puller pre-caches images on every node so that workspaces start in seconds. For instructions on deploying and configuring the Image Puller, see Additional resources.
Platform scaling
By default, each OpenShift Dev Spaces server component runs with one replica. You can increase replicas for high availability and configure cluster autoscaling to add worker nodes when demand exceeds capacity. For instructions on configuring autoscaling, see Additional resources.

1.1. When to optimize

Consider optimization when you observe:

  • Workspace startup taking more than 60 seconds on nodes that have not previously run workspaces.
  • Dashboard or gateway timeouts during peak usage when many developers start workspaces simultaneously.
  • Workspace scheduling failures because of insufficient node resources.

1.2. What affects workspace startup and platform capacity

AreaControlDefault

Image pre-caching

CheCluster CR field spec.components.imagePuller.enable

false (disabled)

Server replicas

CheCluster CR field spec.components.<component>.deployment.replicas

1 for each component

Node autoscaling

MachineAutoscaler and ClusterAutoscaler custom resources

Not configured

Chapter 2. Speed up workspace starts with image caching

Speed up workspace starts by deploying the Kubernetes Image Puller to pre-cache container images on cluster nodes so that workspaces start in seconds instead of minutes.

2.1. How image caching speeds up workspace starts

To improve workspace start time, use the Image Puller, a community-supported OpenShift Dev Spaces-agnostic component that pre-pulls images for OpenShift clusters.

The Image Puller is an additional OpenShift deployment that creates a DaemonSet to pre-pull relevant OpenShift Dev Spaces workspace images on each node. These images are already available when a workspace starts, improving the workspace start time.

For instructions on deploying, configuring, and reviewing cached images, see Additional resources.

2.2. Deploy Image Puller from the command line

Deploy the Kubernetes Image Puller on OpenShift by using the oc CLI to cache images and reduce workspace startup time.

Important

If the Image Puller is installed with the oc CLI, it cannot be configured through the CheCluster Custom Resource.

Prerequisites

Procedure

  1. Gather a list of relevant container images to pull. See Section 2.7, “Review the default images cached by Image Puller”.
  2. Define the memory requests and limits parameters to ensure pulled containers and the platform have enough memory to run.

    When defining the minimal value for CACHING_MEMORY_REQUEST or CACHING_MEMORY_LIMIT, consider the necessary amount of memory required to run each of the container images to pull.

    When defining the maximal value for CACHING_MEMORY_REQUEST or CACHING_MEMORY_LIMIT, consider the total memory allocated to the DaemonSet Pods in the cluster:

    (memory limit) * (number of images) * (number of nodes in the cluster)

    Pulling 5 images on 20 nodes, with a container memory limit of 20Mi requires 2000Mi of memory.

  3. Clone the Image Puller repository and get in the directory containing the OpenShift templates:

    git clone https://github.com/che-incubator/kubernetes-image-puller
    cd kubernetes-image-puller/deploy/openshift
  4. Configure the app.yaml, configmap.yaml, and serviceaccount.yaml OpenShift templates using the following parameters:

    Table 2.1. Image Puller OpenShift templates parameters in app.yaml

    ValueUsageDefault

    DEPLOYMENT_NAME

    The value of DEPLOYMENT_NAME in the ConfigMap

    kubernetes-image-puller

    IMAGE

    Image used for the kubernetes-image-puller deployment

    registry.redhat.io/devspaces/imagepuller-rhel8

    IMAGE_TAG

    The image tag to pull

    latest

    SERVICEACCOUNT_NAME

    The name of the ServiceAccount created and used by the deployment

    kubernetes-image-puller

    Table 2.2. Image Puller OpenShift templates parameters in configmap.yaml

    ValueUsageDefault

    CACHING_CPU_LIMIT

    The value of CACHING_CPU_LIMIT in the ConfigMap

    .2

    CACHING_CPU_REQUEST

    The value of CACHING_CPU_REQUEST in the ConfigMap

    .05

    CACHING_INTERVAL_HOURS

    The value of CACHING_INTERVAL_HOURS in the ConfigMap

    "1"

    CACHING_MEMORY_LIMIT

    The value of CACHING_MEMORY_LIMIT in the ConfigMap

    "20Mi"

    CACHING_MEMORY_REQUEST

    The value of CACHING_MEMORY_REQUEST in the ConfigMap

    "10Mi"

    DAEMONSET_NAME

    The value of DAEMONSET_NAME in the ConfigMap

    kubernetes-image-puller

    DEPLOYMENT_NAME

    The value of DEPLOYMENT_NAME in the ConfigMap

    kubernetes-image-puller

    IMAGES

    The value of IMAGES in the ConfigMap

    {}

    NAMESPACE

    The value of NAMESPACE in the ConfigMap

    k8s-image-puller

    NODE_SELECTOR

    The value of NODE_SELECTOR in the ConfigMap

    "{}"

    Table 2.3. Image Puller OpenShift templates parameters in serviceaccount.yaml

    ValueUsageDefault

    SERVICEACCOUNT_NAME

    The name of the ServiceAccount created and used by the deployment

    kubernetes-image-puller

    KIP_IMAGE

    The image puller image to copy the sleep binary from

    registry.redhat.io/devspaces/imagepuller-rhel8:latest

  5. Create an OpenShift project to host the Image Puller:

    oc new-project <k8s-image-puller>
  6. Process and apply the templates to install the puller:

    oc process -f serviceaccount.yaml | oc apply -f -
    oc process -f configmap.yaml | oc apply -f -
    oc process -f app.yaml | oc apply -f -

Verification

  1. Verify the existence of a <kubernetes-image-puller> deployment and a <kubernetes-image-puller> DaemonSet. The DaemonSet needs to have a Pod for each node in the cluster:

    oc get deployment,daemonset,pod --namespace <k8s-image-puller>
  2. Verify the values of the <kubernetes-image-puller> ConfigMap.

    oc get configmap <kubernetes-image-puller> --output yaml

2.3. Deploy Image Puller from the web console

Deploy the Kubernetes Image Puller Operator on OpenShift by using the OpenShift web console to cache images and reduce workspace startup time.

Prerequisites

Procedure

  1. Install the Kubernetes Image Puller Operator. See This page is not included, but the link has been rewritten to point to the nearest parent document.Installing from OperatorHub using the web console.
  2. Create a KubernetesImagePuller operand from the Kubernetes Image Puller Operator. See Creating applications from installed Operators.

Verification

  • In the OpenShift web console, go to OperatorsInstalled Operators and verify that the Kubernetes Image Puller Operator status is Succeeded.

2.4. Cache default OpenShift Dev Spaces images on all nodes

Cache default OpenShift Dev Spaces images on all nodes by enabling Kubernetes Image Puller to reduce workspace startup time. The Red Hat OpenShift Dev Spaces Operator controls the image list and updates it automatically on OpenShift Dev Spaces upgrade.

Prerequisites

Procedure

  1. Configure the Image Puller to pre-pull OpenShift Dev Spaces images.

    oc patch checluster/devspaces \
        --namespace openshift-devspaces \
        --type='merge' \
        --patch '{
                  "spec": {
                    "components": {
                      "imagePuller": {
                        "enable": true
                      }
                    }
                  }
                }'

Verification

  • Verify that the image puller is enabled:

    oc get checluster devspaces -n openshift-devspaces -o jsonpath='{.spec.components.imagePuller.enable}'

2.5. Cache your organization’s custom images

Cache your organization’s custom images with Kubernetes Image Puller so that workspaces using organization-specific container images start without waiting for large image downloads.

Prerequisites

  • You have an instance of OpenShift Dev Spaces installed and running on a Kubernetes cluster.
  • You have Image Puller installed on the Kubernetes cluster.

Procedure

  1. Configure the Image Puller to pre-pull custom images.

    oc patch checluster/devspaces \
        --namespace openshift-devspaces \
        --type='merge' \
        --patch '{
                  "spec": {
                    "components": {
                      "imagePuller": {
                        "enable": true,
                        "spec": {
                          "images": "NAME-1=IMAGE-1;NAME-2=IMAGE-2"
                        }
                      }
                    }
                  }
                }'

    where:

    images
    The semicolon-separated list of images in name=image format.

Verification

  • Verify that the image puller is configured with the custom images:

    oc get checluster devspaces -n openshift-devspaces -o jsonpath='{.spec.components.imagePuller.spec.images}'

2.6. Cache additional images for faster starts

Cache additional images with Kubernetes Image Puller to reduce workspace startup time by ensuring that required images are already cached on each node.

Prerequisites

  • You have an instance of OpenShift Dev Spaces installed and running on a Kubernetes cluster.
  • You have Image Puller installed on the Kubernetes cluster.

Procedure

  1. Create k8s-image-puller namespace:

    oc create namespace k8s-image-puller
  2. Create KubernetesImagePuller Custom Resource:

    oc apply -f - <<EOF
    apiVersion: che.eclipse.org/v1alpha1
    kind: KubernetesImagePuller
    metadata:
      name: k8s-image-puller-images
      namespace: k8s-image-puller
    spec:
      images: "NAME-1=IMAGE-1;NAME-2=IMAGE-2"
    EOF

    where:

    images
    The semicolon-separated list of images in name=image format.

Verification

  • Verify that the image puller DaemonSet is running in the k8s-image-puller namespace:

    oc get daemonset -n k8s-image-puller

2.7. Review the default images cached by Image Puller

Review the default list of images used by Kubernetes Image Puller to decide which images to pre-cache. This list helps administrators configure Image Puller to use only a subset of these images in advance.

Prerequisites

Procedure

  1. Determine the namespace where the OpenShift Dev Spaces Operator is deployed:

    OPERATOR_NAMESPACE=$(oc get pods -l app.kubernetes.io/component=devspaces-operator -o jsonpath={".items[0].metadata.namespace"} --all-namespaces)
  2. Determine the images that can be pre-pulled by the Image Puller:

    oc exec -n $OPERATOR_NAMESPACE deploy/devspaces-operator -- cat /tmp/external_images.txt

Chapter 3. Scale the platform automatically

Scale OpenShift Dev Spaces container replicas and cluster nodes automatically so that the platform grows and shrinks with developer demand.

3.1. Scale OpenShift Dev Spaces for high availability

Scale OpenShift Dev Spaces for high availability by defining a Kubernetes HorizontalPodAutoscaler (HPA) resource for OpenShift Dev Spaces operands. The HPA dynamically adjusts the number of replicas based on specified metrics.

Prerequisites

Procedure

  1. Create an HPA resource for a deployment, specifying the target metrics and desired replica count.

    apiVersion: autoscaling/v2
    kind: HorizontalPodAutoscaler
    metadata:
      name: scaler
      namespace: openshift-devspaces
    spec:
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: <deployment_name>
      ...

    where:

    <deployment_name>

    One of the following deployments:

    • devspaces
    • che-gateway
    • devspaces-dashboard
    • plugin-registry
    • devfile-registry

      For example:

      apiVersion: autoscaling/v2
      kind: HorizontalPodAutoscaler
      metadata:
        name: devspaces-scaler
        namespace: openshift-devspaces
      spec:
        scaleTargetRef:
          apiVersion: apps/v1
          kind: Deployment
          name: devspaces
        minReplicas: 2
        maxReplicas: 5
        metrics:
          - type: Resource
            resource:
              name: cpu
              target:
                type: Utilization
                averageUtilization: 75

      In this example, the HPA targets the devspaces deployment with a minimum of 2 replicas, a maximum of 5 replicas, and scales based on CPU utilization.

Verification

  • Verify that the HPA resource is created and targeting the correct deployment:

    oc get hpa -n openshift-devspaces

3.2. Prevent workspace failures during node scaling

Prevent workspace failures during node scaling by configuring OpenShift Dev Spaces startup timeouts and pod annotations to work with the cluster autoscaler.

When the autoscaler adds a new node, workspace startup can take longer than usual until node provisioning is complete. When the autoscaler removes a node, workspace pods should not be evicted because eviction can cause interruptions and loss of unsaved data.

Prerequisites

Procedure

  1. Set the startup timeout and event handling in the CheCluster Custom Resource to handle autoscaler node additions:

    spec:
      devEnvironments:
        startTimeoutSeconds: 600
        ignoredUnrecoverableEvents:
          - FailedScheduling

    where:

    startTimeoutSeconds
    Set to at least 600 seconds to allow time for a new node to be provisioned during workspace startup.
    ignoredUnrecoverableEvents
    Ignore the FailedScheduling event to allow workspace startup to continue when a new node is provisioned. This setting is enabled by default.
  2. Add the safe-to-evict annotation to the CheCluster Custom Resource to prevent workspace pod eviction when the autoscaler removes a node:

    spec:
      devEnvironments:
        workspacesPodAnnotations:
          cluster-autoscaler.kubernetes.io/safe-to-evict: "false"

Verification

  • Start a workspace and verify that the workspace pod contains the cluster-autoscaler.kubernetes.io/safe-to-evict: "false" annotation:

    $ oc get pod <workspace_pod_name> -o jsonpath='{.metadata.annotations.cluster-autoscaler\.kubernetes\.io/safe-to-evict}'
    false

Chapter 4. Verify workspace performance after optimization

Verify that your optimization changes improved workspace startup speed and platform capacity so that you can confirm the investment is working.

4.1. Check replica counts, image cache, and workspace startup

Check replica counts, image-cache DaemonSets, and workspace startup time so that you can confirm optimization changes are working.

Prerequisites

Procedure

  1. Verify that OpenShift Dev Spaces server components are running with the expected replica count:

    $ oc get deployment -n openshift-devspaces \
      -o custom-columns='NAME:.metadata.name,REPLICAS:.spec.replicas,AVAILABLE:.status.availableReplicas'

    All components should show the configured number of replicas in the AVAILABLE column.

  2. If you enabled the Kubernetes Image Puller, verify that the DaemonSet is running on all schedulable nodes:

    $ oc get daemonset -n openshift-devspaces -l app=kubernetes-image-puller

    The DESIRED and READY columns should show the same number, matching your schedulable node count.

  3. Verify that the pre-cached images are present on a node by checking the DaemonSet pod logs:

    $ oc logs -n openshift-devspaces -l app=kubernetes-image-puller --tail=5
  4. Start a workspace and observe the startup time. With image pre-caching enabled, workspaces on nodes that have the DaemonSet pod should start within 30 seconds.
  5. Verify overall platform health:

    $ oc get pods -n openshift-devspaces -o custom-columns='NAME:.metadata.name,READY:.status.containerStatuses[*].ready,STATUS:.status.phase'

    All pods should show Running status with all containers ready.

Chapter 5. Configure automatic cleanup of inactive workspaces

For large Kubernetes deployments, particularly those involving a high number of custom resources such as DevWorkspace objects, which represent CDEs, etcd can become a significant performance bottleneck. Configure the Dev Workspace Operator pruner to automatically delete workspaces that have not been started within a configurable retention period.

Important

Based on the load testing for 6,000 DevWorkspace objects, storage consumption for etcd was approximately 2.5GB.

Prerequisites

Procedure

  1. Configure the DevWorkspaceOperatorConfig object to enable the cleanup cron job:

    apiVersion: controller.devfile.io/v1alpha1
    kind: DevWorkspaceOperatorConfig
    metadata:
      name: devworkspace-operator-config
      namespace: openshift-devspaces
    config:
      workspace:
        cleanupCronJob:
          enabled: true
          dryRun: false
          retainTime: 2592000
          schedule: "0 0 1 * *"
    retainTime
    The number of seconds a workspace must be inactive before it is marked for deletion. The default value 2592000 equals 30 days.
    schedule
    A cron expression that defines how often the pruner runs. The default value "0 0 1 * *" runs the pruner once per month.
  2. Optional: To preview which workspaces would be deleted without removing them, set dryRun to true.

Verification

  • Verify that the cleanup cron job is scheduled:

    $ oc get cronjobs -n openshift-devspaces

Chapter 6. Disable the workspace CA bundle mount

By default, the Operator creates a ca-certs-merged ConfigMap in every user namespace. This ConfigMap contains the full Certificate Authorities (CAs) bundle. With a large number of Transport Layer Security (TLS) certificates in the cluster, these ConfigMaps consume significant etcd storage. Disable the full CA bundle mount to reduce etcd pressure.

Prerequisites

Procedure

  1. Configure the CheCluster Custom Resource to disable the workspace CA bundle mount:

    Edit the CheCluster Custom Resource on the cluster:

    $ oc edit checluster/devspaces -n openshift-devspaces
    spec:
      devEnvironments:
        trustedCerts:
          disableWorkspaceCaBundleMount: true

    With this configuration, OpenShift Dev Spaces no longer mounts the full CA bundle under /etc/pki/ca-trust/extracted/pem. Only custom certificates are mounted under /public-certs.

Verification

  • Verify that new workspaces no longer mount the full CA bundle:

    $ oc get configmap ca-certs-merged -n <user-namespace>

    The ConfigMap should not exist in namespaces for newly created workspaces.

Chapter 7. Disable Copied CSVs to reduce etcd usage

When an Operator is installed by the Operator Lifecycle Manager (OLM), a stripped-down copy of its ClusterServiceVersion (CSV) is created in every namespace the Operator watches. In clusters with many namespaces and cluster-wide Operators, Copied CSVs increase etcd storage usage, OLM memory consumption, and network bandwidth. Disabling Copied CSVs reduces the data stored in etcd and the memory footprint of OLM.

Prerequisites

Procedure

  1. Configure the OLMConfig object to disable Copied CSVs:

    apiVersion: operators.coreos.com/v1
    kind: OLMConfig
    metadata:
      name: cluster
    spec:
      features:
        disableCopiedCSVs: true

    Disabling Copied CSVs reduces etcd storage usage and the memory footprint of OLM.

Verification

  • Verify that Copied CSVs are no longer created in user namespaces:

    $ oc get csv -n <user-namespace>

    The command should return no Copied CSVs for namespaces that do not have their own Operator subscriptions.

Revised on 2026-07-27 19:48:00 UTC

Legal Notice

Copyright © Red Hat.
Except as otherwise noted below, the text of and illustrations in this documentation are licensed by Red Hat under the Creative Commons Attribution–Share Alike 3.0 Unported license . If you distribute this document or an adaptation of it, you must provide the URL for the original version.
Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent permitted by applicable law.
Red Hat, the Red Hat logo, JBoss, Hibernate, and RHCE are trademarks or registered trademarks of Red Hat, LLC. or its subsidiaries in the United States and other countries.
Linux® is the registered trademark of Linus Torvalds in the United States and other countries.
XFS is a trademark or registered trademark of Hewlett Packard Enterprise Development LP or its subsidiaries in the United States and other countries.
The OpenStack® Word Mark and OpenStack logo are trademarks or registered trademarks of the Linux Foundation, used under license.
All other trademarks are the property of their respective owners.