Skip to main content

Optimizing Build Performance

1. Using Incremental Builds

Incremental builds in Jenkins help reduce build times by only rebuilding what has changed since the last successful build. This is particularly useful in large projects where full rebuilds can be time-consuming.

Feature Description Usage
Incremental Build Rebuilds only the parts of a project that have changed since the last build. Enabled via Incremental Build option in project configuration or using plugins like Build Name and Description Setter.
Build Triggers Triggers a build only when changes are detected in the source code. Configured under Build Triggers in project settings, often using SCM polling or webhooks.

Example: Enabling Incremental Build with Git

pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                git branch: 'main', url: 'https://github.com/example/project.git'
                // Jenkins will only rebuild if changes are detected
                sh 'mvn clean compile'
            }
        }
    }
}
Note: Incremental builds are most effective when combined with proper version control systems like Git, which can accurately detect file changes.

2. Implementing Build Caching

Cache Type Description Usage Notes
Build Cache Caches build artifacts and dependencies to speed up subsequent builds Configured via Jenkins plugins or configuration Reduces build time by avoiding recompilation of unchanged code
Dependency Cache Caches external dependencies like Maven or npm packages Used in conjunction with build cache to avoid re-downloading dependencies Improves performance for builds that rely on large external libraries
Workspace Cache Caches the workspace content between builds Can be configured to preserve or clear workspace content Useful for builds that require a stable environment across runs

Example: Using Jenkins Build Cache Plugin

pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                cache(paths: 'build/', restore: true) {
                    sh 'make'
                }
            }
        }
    }
}
Note: The cache directive is part of the Pipeline Utility Steps plugin and requires proper configuration to work effectively.
Warning: Ensure that cache paths are properly managed to avoid conflicts or stale data in builds.

3. Using Parallel Execution

Example: Parallel execution in Jenkins pipeline

pipeline {
    agent any
    stages {
        stage('Build') {
            parallel {
                stage('Frontend') {
                    steps {
                        echo 'Building frontend...'
                    }
                }
                stage('Backend') {
                    steps {
                        echo 'Building backend...'
                    }
                }
            }
        }
    }
}
Property Description Values
parallel Executes multiple stages in parallel stage('name') { steps { ... } }
agent Specifies where the pipeline will run any, none, or specific labels
Note: Parallel stages must be defined within a stage block.
Warning: Ensure that parallel stages do not share resources or state.

Benefits of Parallel Execution

  • Reduces overall build time by running independent tasks simultaneously
  • Improves resource utilization on multi-core systems
  • Enables faster feedback loops in CI/CD pipelines

4. Optimizing Agent Resources

Resource Description Configuration Notes
agent.executors Number of concurrent builds per agent 1 to 10+ Higher values increase resource usage; tune based on agent capacity
agent.workspace Workspace directory for builds /var/lib/jenkins/workspace Ensure sufficient disk space and permissions
agent.javaHome Java installation path for builds /usr/lib/jvm/java-11-openjdk Must match the Java version used by jobs

Example: Configure Agent Executors

agent {
    label 'linux-agent'
    executors 2
    workspace '/opt/jenkins/workspace'
}
Note: Increasing executors allows more parallel builds but may lead to resource contention if not properly managed.

Best Practices for Agent Resource Optimization

  • Monitor CPU and memory usage per agent
  • Use labels to assign jobs to appropriate agents
  • Set executors based on hardware capabilities and job requirements
  • Regularly clean up old workspaces to free disk space

5. Using Lightweight Checkout

The lightweight checkout option in Jenkins reduces build times and resource usage by checking out only the necessary files from version control, rather than the full repository.

Option Values Description
lightweightCheckout true Enables lightweight checkout for the build

Example: Configuring Lightweight Checkout in Pipeline

pipeline {
    agent any
    stages {
        stage('Checkout') {
            steps {
                checkout([
                    $class: 'GitSCM',
                    branches: [[name: 'main']],
                    extensions: [[$class: 'LightweightCheckout']]
                ])
            }
        }
    }
}
Note: Lightweight checkout is supported for Git repositories and requires Jenkins 2.307 or later.

6. Implementing Workspace Reuse

Option Values Notes
workspace reuse Enable workspace reuse for faster builds
workspace.cleanup false Disable automatic cleanup to preserve workspace

Example: Configure Workspace Reuse

pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                sh "echo 'Using reused workspace'"
            }
        }
    }
    post {
        always {
            // Preserve workspace for reuse
            cleanWs()
        }
    }
}
Note: Workspace reuse can improve performance but requires careful management to avoid conflicts between builds.
Warning: Enabling workspace reuse may lead to stale files if not properly managed.

7. Using Docker Layer Caching

Option Values Description
docker.build.args cache-from=type=registry,ref=your-registry/image:latest Specifies the Docker image to use for layer caching
docker.build.cache-from type=registry,ref=your-registry/image:latest Enables caching from a remote registry
docker.build.cache-to type=registry,ref=your-registry/image:latest Pushes built layers to a registry for reuse

Example: Jenkins Pipeline with Docker Layer Caching

pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                script {
                    docker.build(
                        "my-app:<BUILD_NUMBER>",
                        "--cache-from=type=registry,ref=your-registry/my-app:latest"
                    )
                }
            }
        }
    }
}
Note: Ensure Docker BuildKit is enabled for layer caching to work effectively.
Warning: Layer caching may not work as expected in environments with strict network policies or when using local registries without proper configuration.

8. Optimizing SCM Polling

Option Values Notes
scm.polling true Enable SCM polling for build triggers
scm.polling.interval 5m Polling interval (default 5 minutes)
scm.polling.disabled false Disable polling entirely for a job

Example: Configure SCM Polling Interval

pipeline {
    agent any
    triggers {
        pollSCM 'H/5 * * * *'
    }
    stages {
        stage('Build') {
            steps {
                echo 'Building...'
            }
        }
    }
}
Note: Using H/5 * * * * means polling every 5 minutes with a randomized offset to avoid load spikes.
Warning: Frequent SCM polling can increase load on the source control server and Jenkins.
SCM Polling Strategy Description Best Use Case
Polling with Random Offset Uses H/5 * * * * format to stagger polling High-volume repositories with many jobs
Build Periodically Triggers builds at fixed intervals using cron syntax Jobs that don't depend on SCM changes
Webhook-based Triggers Uses SCM webhooks instead of polling (e.g., GitHub Webhooks) Most efficient for real-time builds

9. Using Build Queues Effectively

Queue Item Description Actions
Build Queue Manages pending builds in Jenkins Manage Jenkins > Build Queue
Build Priority Allows prioritization of builds Configure in Manage Jenkins > Configure System
Queue Configuration Controls queue behavior and limits Adjust via Manage Jenkins > Configure System

Example: Prioritizing Builds

import jenkins.model.Jenkins
import hudson.model.Queue

def queue = Jenkins.instance.queue
def items = queue.items

// Sort items by priority or age
items.sort { a, b -> b.inQueueSince <=> a.inQueueSince }

// Display queue items
items.each { item ->
    println "Build: ${item.task.name} - Queued since: ${new Date(item.inQueueSince)}"
}
Note: Build queue management is essential for optimizing resource usage and reducing build times in high-traffic environments.

Key Points

  • Builds in the queue are managed by Jenkins' internal queue system
  • Priority can be adjusted to ensure critical builds run first
  • Queue configuration allows for limiting concurrent builds and managing build delays

10. Implementing Pipeline Optimization

Example: Parallel Stage with Resource Management

pipeline {
    agent any
    stages {
        stage('Build') {
            parallel {
                stage('Frontend') {
                    agent {
                        label 'frontend'
                    }
                    steps {
                        sh 'npm install'
                        sh 'npm run build'
                    }
                }
                stage('Backend') {
                    agent {
                        label 'backend'
                    }
                    steps {
                        sh 'mvn compile'
                        sh 'mvn test'
                    }
                }
            }
        }
    }
}
Option Values Description
agent any Allows any available agent to run the stage
label frontend, backend Assigns specific agents based on labels for resource isolation
parallel true Enables concurrent execution of stages to reduce total build time
Note: Using label ensures that stages run on agents with specific capabilities or resources.

Example: Caching Dependencies with Artifactory

pipeline {
    agent any
    stages {
        stage('Setup') {
            steps {
                sh 'mkdir -p .cache'
                sh 'cp -r .cache/* . || true'
            }
        }
        stage('Build') {
            steps {
                sh 'npm install --cache .cache'
            }
        }
    }
}

Optimization Strategies

  • Use parallel stages to run independent tasks concurrently
  • Assign agents with label for better resource allocation
  • Cache dependencies to avoid re-downloading in each build
  • Use sh with caching flags to speed up repeated operations

Was this article helpful?