Pipeline Performance Tuning Basics in Jenkins

Pipeline Performance Tuning Basics in Jenkins

Learn how to make Jenkins pipelines finish sooner and cost less: where the time really goes, how to measure it, and the everyday fixes for checkouts, caches, tests, agents, logs and the controller itself, without guesswork.

A slow pipeline is a tax on every developer, every day. A change that should take five minutes to verify takes forty. People push less often, batch their work into large risky changes, switch to other tasks while they wait, and forget what they were doing when the result finally arrives. Multiply that by a whole team and the loss is enormous, even though nobody ever sees it as a line on a bill.

The good news is that most slow pipelines are slow for a small number of ordinary reasons. Time is wasted downloading the same libraries again and again, cloning more history than needed, running steps one after another that could run side by side, waiting in a queue for a machine, or running work that nobody needed. These problems are easy to understand and often easy to fix, once you can see them.

This guide starts from zero. Every new word is explained when it first appears, everyday pictures make ideas stick, and the later chapters cover the basics that experienced engineers apply first: measuring before changing, finding the critical path, speeding up checkouts and caches, ordering and splitting tests, protecting the controller, keeping logs lean and watching for regressions over time.

1What Is Pipeline Performance Tuning?

A plain-language first look before any details.

Jenkins is a free, open-source automation server that builds, tests and delivers software. Its work is written as a pipeline, a recipe stored in a text file called the Jenkinsfile. A pipeline is divided into stages, such as Build, Test and Deploy, and each stage contains steps, the single actions Jenkins performs.

Performance tuning means changing how a pipeline is written and how Jenkins is set up so that the same work finishes sooner, uses fewer resources, or both. It is not about clever tricks. It is about finding where time goes, removing waste, and doing independent things at the same time.

Everyday Analogy

Think of getting ready for work in the morning. If you boil water, then wait, then toast bread, then wait, then shower, the whole routine takes an hour. If you start the water, toast the bread while it heats and shower while the toast cooks, it takes twenty minutes. You did not move faster; you stopped waiting for things one after another. You also stopped walking to the shop for milk every day and bought a week’s worth. Pipeline tuning is the same kind of work: overlap the waits, and stop repeating the shopping.

i
Remember

Never tune by guessing. A change that feels clever but does not touch the slowest part of the pipeline saves nothing. The first skill in performance work is measuring, and this guide comes back to that again and again.

The same ideas apply whether you run a small team on two machines or a large organization on hundreds. The numbers differ, but the method is identical: measure, find the biggest cost, fix it, and measure again.

2Why Speed Matters

The hidden costs of slow pipelines.

Feedback delayed is feedback lessened

The value of a build is the information it gives a developer: “your change is fine” or “your change broke something.” That information is most useful while the developer still remembers the change. After ten minutes the memory is fresh. After an hour, the developer has moved on, and coming back costs time to reload the context.

Slow pipelines change behavior

When feedback is slow, people push large batches of changes to avoid waiting several times. Large changes are harder to review and more likely to hide bugs. When the pipeline is fast, people push small changes, and small changes are safer.

Money and machines

Every minute a build runs holds a work slot, an executor, on a machine. On cloud machines billed by time, slower builds cost more. In a busy installation, slow builds also lengthen the queue for everyone else.

1

Nobody notices

The pipeline starts fast. Each new test or check adds a minute here and there.

2

Drift

After a year, the pipeline that took eight minutes takes thirty-five. No single change was to blame.

3

Complaints

Developers grumble, batch their changes and start skipping checks.

4

Tuning

Someone measures and finds that a few causes account for most of the time.

5

Guarding

Duration is tracked, so drift is caught early next time.

10 min
a common target for pull request feedback
80%
of delay often comes from a few causes
1
measurement before every change
A pipeline does not get slow in one day. It gets slow one harmless minute at a time.

3Core Concepts You Need First

A handful of small ideas that make everything else easy.

Wall-clock time

Wall-clock time is the time on the clock from the moment a build is requested to the moment it finishes. It is what the developer experiences, and it includes waiting.

Queue time and run time

Queue time is how long a build waits for a free machine. Run time is how long it takes once it starts. Tuning run time does nothing for a build that spends most of its life waiting in the queue, so always look at both.

Critical path

The critical path is the longest chain of steps that must happen one after another. Steps that run in parallel do not add up; the longest of them decides the total. Only shortening the critical path shortens the pipeline. Speeding up something that is not on it changes nothing.

Latency and throughput

Latency is how long one build takes. Throughput is how many builds the system can complete per hour. Some changes improve one but hurt the other, for example running many builds at once on one machine raises throughput but slows each build.

Cache

A cache is a saved copy of something expensive to produce, kept so it does not have to be produced again. Downloaded libraries and compiled code are the usual candidates.

Controller and agent

Jenkins has a main server, the controller, and worker machines called agents. Heavy work belongs on agents. The pipeline’s own decision-making runs on the controller and should stay light.

TermSimple meaningWhy it matters
Wall-clock timeTime the developer waitsThe number that people feel
Queue timeWaiting for a machineNeeds capacity fixes, not code fixes
Run timeTime from start to finish on a machineWhere most tuning happens
Critical pathLongest chain of dependent stepsThe only path worth shortening
LatencyDuration of one buildDeveloper experience
ThroughputBuilds completed per hourTeam capacity
CacheA saved result to reuseRemoves repeated work

4Architecture: Where the Time Goes

The parts of a Jenkins setup that each add a little delay.

A pipeline run is the journey of a change through several components. Each hop can add delay, and knowing the route tells you where to look.

flowchart LR
    DEV["Developer pushes code"] --> SCM["Source Control Server"]
    SCM -->|"webhook"| CTRL["Jenkins Controller"]
    CTRL --> Q["Build Queue"]
    Q --> AGT["Agent with free executor"]
    AGT --> CO["Checkout"]
    CO --> DEP["Download dependencies"]
    DEP --> BLD["Compile and package"]
    BLD --> TST["Run tests"]
    TST --> PUB["Publish artifacts and reports"]
    PUB --> NOTI["Notify and update status"]
    CTRL -.->|"runs pipeline logic"| AGT
    AGT -.->|"streams logs"| CTRL
Figure 1: The route of a build. Every box can hide wasted time.

Read the diagram from left to right. The push reaches the controller through a webhook, a message sent automatically when something happens. The build waits in the queue for an agent. On the agent, it checks out code, downloads libraries, compiles, tests and publishes. Meanwhile the controller runs the pipeline’s own logic and receives the log lines the agent sends. Time is spent in each box, and the biggest box is usually not the one people suspect.

Wait

Queue

Time before the build even starts. Depends on capacity and label choices.

Fetch

Checkout

Downloading the source code. Large repositories and full history make this slow.

Fetch

Dependencies

Downloading libraries and images. Often the largest hidden cost on fresh agents.

Work

Build and test

The real computation. Can be sped up with caches, incremental builds and parallel work.

Move

Publishing

Uploading artifacts and reports. Large files through the controller cause slowdowns.

Think

Controller logic

The pipeline script itself. Small when simple, expensive when it does heavy work.

5Measure First: The Tools You Already Have

You cannot fix what you cannot see.

Jenkins gives you several ways to see where time goes, and most cost nothing to switch on.

ToolWhat it showsBest used for
Timestamps in the logThe time of every log lineSpotting gaps and slow commands within a stage
Stage view or pipeline graphDuration of each stage across many buildsFinding the slowest stage and its trend
Pipeline steps pageDuration of individual steps in one buildDrilling down inside a slow stage
Build history trendTotal duration of recent buildsSeeing drift over weeks
Queue informationWhy and how long builds waitSeparating waiting from working
Monitoring pluginsNumbers exposed to dashboards such as PrometheusLong-term trends and alerts
Agent resource graphsProcessor, memory, disk and network on the machineFinding out whether a step is limited by computing or by waiting

Switch on timestamps

The timestamps option prefixes each log line with the time. It costs almost nothing and turns a wall of text into a timeline. With it, a gap of four minutes between two lines is immediately visible, and you can ask what happened there.

Separate queue time from run time

The duration shown for a build usually counts only the time after it started running. A build that shows twelve minutes may have waited fifteen minutes before that. Always check the queue separately, or you may spend a week tuning code when the real problem is a shortage of machines.

!
Common mistake

Comparing one fast build with one slow build and deciding what changed. Builds vary naturally. Look at at least twenty recent runs, and use the middle value and the slow tail, not a single sample.

Example: what timestamps reveal

A team believes their tests are slow. Timestamps show that the test stage starts eleven minutes after the build begins. The gap is a full dependency download on a fresh agent. The tests themselves take four minutes. Adding a package proxy removes ten of those eleven minutes without touching a single test.

6The Tuning Loop

A repeatable method that keeps you honest.

flowchart LR
    M["Measure: collect durations of many runs"] --> F["Find the biggest cost on the critical path"]
    F --> H["Form a simple hypothesis"]
    H --> C["Change one thing"]
    C --> V["Verify with new measurements"]
    V --> Q{"Improved?"}
    Q -->|"Yes"| K["Keep it and note the gain"]
    Q -->|"No"| R["Revert and try another idea"]
    K --> M
    R --> F
Figure 2: Measure, find, guess, change one thing, verify, and repeat.
1

Measure

Collect durations for the last twenty or more runs. Record queue time and run time separately.

2

Find the biggest cost

List the stages and steps by duration. Mark which are on the critical path.

3

Hypothesize

Say in one sentence why it is slow, such as “we download everything on every build.”

4

Change one thing

Make one change, not five. Otherwise you will not know which one helped.

5

Verify

Run enough builds to be sure. Compare the middle and slow values, not only the best one.

6

Record

Write down what you changed and what it gained, so the team learns and nobody undoes it by accident.

Amdahl’s insight

A simple idea from computer science says that the benefit of speeding up one part is limited by how much of the total that part represents. If tests are ten percent of the pipeline, making them twice as fast saves five percent. If dependency downloads are forty percent, halving them saves twenty. This is why the first step is always to find the biggest piece.

i
Rule of thumb

Attack the biggest piece on the critical path first. The best first fixes are usually boring: caching, shallow checkouts, running independent work in parallel and removing work nobody needs.

7The Anatomy of a Pipeline’s Duration

Where the minutes usually hide.

flowchart TD
    T["Total wall-clock time"] --> W["Waiting: queue and agent start-up"]
    T --> S["Setup: checkout and dependencies"]
    T --> B["Build: compile and package"]
    T --> X["Test: unit, integration, end to end"]
    T --> P["Publish: artifacts, reports, notifications"]
    T --> O["Overhead: step start-up, logging, pipeline logic"]
Figure 3: Six buckets that together make up the time a developer waits.
BucketTypical share in an untuned pipelineCommon fixes
Waiting10 to 40 percent at busy timesMore or better-labeled agents, warm pools, cancel redundant builds
Setup15 to 40 percentShallow checkouts, package proxies, caches, small images
Build10 to 25 percentIncremental builds, build caches, tool parallelism
Test20 to 50 percentSplit, order, remove sleeps, share fixtures
Publish3 to 10 percentUpload only what is needed, use repositories
Overhead2 to 10 percentFewer steps, lighter scripts, quieter logs

These shares are only typical ranges, not rules. Your own pipeline will differ, which is exactly why measuring matters. But the table shows a useful pattern: setup and waiting together often outweigh the actual building and testing. Many teams focus on the compiler and the test framework when the bigger wins are in the boring parts around them.

Illustration: the surprising breakdown

A thirty-eight-minute pipeline turns out to have this breakdown: 9 minutes waiting in the queue, 11 minutes of checkout and downloads, 4 minutes of compiling, 12 minutes of tests and 2 minutes of publishing. The team’s plan to buy a faster compiler would have addressed four minutes. Fixing the queue and the downloads addresses twenty.

8Queue Time: Waiting for a Machine

The delay before your code is even looked at.

When all the executors on suitable agents are busy, new builds wait in the build queue. Queue time is often the most annoying delay because it is pure idleness: nothing is happening for your change. It is also the delay that no amount of code tuning can fix.

Causes of long queues

  • Too little capacity for the number of builds at busy times.
  • Labels that split the fleet into small pools, so one pool is full while another sits idle.
  • Builds that hold executors while waiting, for example an approval prompt inside an agent block.
  • Redundant builds for commits that have already been superseded by newer ones.
  • Slow builds that hold slots longer, which lengthens the queue for everyone.
SymptomLikely causeFirst fix
Queue long at the same hours dailyPeak not covered by capacityScheduled warm capacity or a higher agent ceiling
Builds wait but agents look idleLabel mismatch or throttle rulesRead the queue reason; simplify labels
Queue grows steadily over monthsBuilds have become slowerTune the pipelines; measure duration trends
Many queued builds for the same branchRedundant commits piling upCancel older builds when a newer one arrives
i
A useful target

Aim for most builds to start within a minute of being queued. If the median queue time is much longer than that, fix the queue before anything else, because every other improvement is wasted on builds that spend their lives waiting.

Illustration: cancelling the outdated

A developer pushes five small commits in ten minutes. Without any rule, five builds are queued and run, and four of them test code that no longer matters. Cancelling older builds of the same branch when a newer commit arrives leaves one build, saves four builds’ worth of capacity and gives the developer the useful result sooner.

9Keep the Controller’s Work Light

The pipeline script runs on the controller, not on the agent.

This surprises many beginners. When a pipeline runs, the steps that execute commands run on the agent. But the pipeline script itself, the small program that decides what to do next, runs on the controller. Jenkins runs it with a special engine that can pause and resume, so that a pipeline can survive a restart. This engine is slower than ordinary code, and it uses controller memory and processor time.

flowchart LR
    subgraph CT["Controller"]
        SC["Pipeline script logic"]
        LG["Log receiving and storage"]
        ST["State saving to disk"]
    end
    subgraph AG["Agent"]
        CM["Commands: compile, test, package"]
    end
    SC -->|"sends step"| CM
    CM -->|"output lines"| LG
    SC --> ST
Figure 4: Decisions and bookkeeping happen on the controller; heavy work happens on the agent.

Cheap for the controller

  • Choosing which stage to run.
  • Reading a few variables.
  • Calling a command that does the real work.
  • Short loops over a handful of items.

Expensive for the controller

  • Looping over thousands of items in the script.
  • Parsing very large data files in the script.
  • Complex string building in big loops.
  • Hundreds of tiny steps in a row.
  • Very many parallel branches at once.

The rule

Let agents do the heavy work through ordinary commands and small programs, and keep the pipeline script thin: a coordinator, not a calculator. If a script needs to process a large list or file, write that processing as a normal tool that runs in a command on the agent, and let the pipeline read the short result.

Illustration: the report parser

A pipeline parses a test report with twenty thousand entries inside its own script, summarizing them in a loop. On a quiet system, it takes two minutes and hardly anyone notices. On a busy morning with fifty such pipelines, the controller’s processor is saturated and the whole system slows. Moving the summary into a one-line command on the agent takes three seconds and puts no load on the controller.

10Durability Settings: Trading Safety for Speed

How often a pipeline saves its progress to disk.

To survive a controller restart, a pipeline saves its progress to disk as it goes. Frequent saving is safe but costs disk activity, and on a busy controller with many pipelines the disk can become the bottleneck. Jenkins offers a durability setting that lets you choose how careful to be.

SettingHow it savesSpeedIf the controller crashes
Maximum survivability (default)Saves after every step, atomicallySlowestRunning pipelines resume
Survivable but not atomicSaves regularly but with less strict guaranteesFasterUsually resume; small risk of trouble
Performance optimizedSaves only when the controller shuts down cleanlyFastestRunning pipelines cannot resume and must be rerun

Who should use which

  • Performance-optimized suits most ordinary build and test pipelines, which can simply be rerun if the controller crashes. Many teams see a noticeable reduction in disk load and faster pipelines.
  • Maximum survivability suits long-running pipelines that would be expensive to restart, such as those with long approvals or lengthy deployments.

The setting can be chosen per pipeline in its options, or as a default for the whole installation. A good approach is a fast default, with the safe setting for the few pipelines that need it.

!
Understand the trade

With the fastest setting, a controller crash loses the progress of all running pipelines. That is acceptable when controller crashes are rare and rerunning is cheap. It is not acceptable for a pipeline that waits three days for approval. Choose deliberately.

11Step Overhead: Fewer, Bigger Steps

Every step has a fixed cost, however small its work.

Each pipeline step involves some bookkeeping: the controller records it, sends it to the agent, waits for it, saves state and records the result. For a big step, this cost is invisible. For a thousand tiny steps, it adds up to minutes. A pipeline that runs many small commands one by one is slower than one that runs the same commands as a single script.

PatternEffectBetter
Many one-line shell steps in a rowFixed overhead paid each timeGroup related commands into one script step
Loop in the pipeline that calls a shell step per itemOverhead multiplied by the number of itemsDo the loop inside one shell script on the agent
Reading a small file many times through stepsRound trips between controller and agentRead once and keep the value
Echo statements for every line of progressEach one is a step and a log linePrint summaries, not every item

The balance

This is not a call for one giant, unreadable script. Steps also give you visibility: when a stage shows steps with names and durations, you can see where time goes. The balance is to group steps that belong together, and keep separate steps where separate timing or separate failure handling helps you.

i
Design tip

If a loop in your pipeline runs more than a couple of dozen times, suspect that it belongs inside a script on the agent. Loops in the pipeline are for coordinating; loops on the agent are for working.

Illustration: a hundred tiny steps

A pipeline validates 200 configuration files by running one shell step for each. With a fraction of a second of overhead per step plus start-up of the validator each time, the stage takes seven minutes. Rewriting it as one step that validates all files in a single run takes forty seconds.

12Faster Checkouts

Do not download the whole history to build one snapshot.

The first thing a build does is fetch the source code. By default, Git downloads the full history of the repository: every commit, every branch, every tag, going back years. For a large, old repository, this can be gigabytes, and on a fresh agent it happens on every build. Yet most builds need only the latest snapshot.

flowchart TD
    A["Build needs the source code"] --> B{"Which checkout style?"}
    B -->|"Full clone"| C["Download all history, branches and tags"]
    B -->|"Shallow clone"| D["Download only recent commits"]
    B -->|"Reference repository"| E["Reuse a local copy, fetch only new commits"]
    B -->|"Sparse checkout"| F["Download only needed folders"]
    C --> S1["Slowest, most complete"]
    D --> S2["Fast for most builds"]
    E --> S3["Very fast on warm agents"]
    F --> S4["Fast for monorepos"]
Figure 5: Four ways to fetch code, from the most complete to the most economical.
Shallow

Shallow clone

Fetch only the last few commits. Often cuts clone time from minutes to seconds. Some tools need more history, for example to compute version numbers or changed files, so choose a depth that covers them.

No tags

Skip tags and extra branches

Download only the branch being built, and skip tags unless needed. Less data to transfer and process.

Reference

Reference repository

Keep a shared local copy on the agent or a shared volume, so a checkout only fetches what is new.

Sparse

Sparse checkout

In very large repositories, check out only the folders this build needs.

Once

Check out once per build

Multi-stage pipelines with an agent per stage may check out again in every stage. Skip the default checkout, fetch once, and pass the files onward.

Large files

Handle large files carefully

Repositories using large-file storage can be slow to fetch. Fetch large files only when the build truly needs them.

!
Watch out

A shallow clone can break steps that inspect history: computing a version from tags, finding the merge base for a pull request or listing changed files against another branch. If such a step fails after you shorten the history, increase the depth or fetch just what that step needs.

Illustration: the eight-minute clone

A ten-year-old repository takes eight minutes to clone in full on a fresh agent. Switching to a shallow clone of the last fifty commits, without tags, brings it down to thirty seconds. With 400 builds a day, that returns about fifty hours of agent time daily.

13Dependency Caching

The same libraries, downloaded again and again.

Most projects depend on many outside libraries. On a fresh agent, the build tool downloads every one of them before compiling. A project with hundreds of libraries can spend more time downloading than building. Since the libraries rarely change between builds, this is wasted effort. Caching removes it.

flowchart LR
    B["Build needs a library"] --> L{"In local cache on the agent?"}
    L -->|"Yes"| U["Use it: instant"]
    L -->|"No"| P{"In package proxy near the agent?"}
    P -->|"Yes"| PD["Download from proxy: fast"]
    P -->|"No"| N["Download from the internet: slow"]
    N --> PS["Proxy stores a copy"]
    PS --> LS["Agent stores a copy"]
    PD --> LS
Figure 6: Three layers of caching, from the agent’s own disk to a nearby proxy to the outside world.
LayerWhere it livesStrengthWeakness
Local cache on the agentThe agent’s diskFastest possibleLost when the agent is ephemeral
Persistent cache volumeA storage volume attached to agentsEphemeral agents start warmNeeds care against corruption and growth
Package proxyA server inside your networkShared by all agents; protects against outside outagesAnother system to run
Container image registry mirrorA nearby registryMuch faster image pullsStorage and upkeep

Keys and freshness

A cache is only safe if it is keyed by exactly what it contains. If dependencies are recorded in a file with exact versions, use a fingerprint of that file as the cache key. When the file changes, the key changes, and a fresh cache is built. Reusing a cache built for different versions causes confusing bugs.

i
Design tip

The package proxy is often the single best investment for teams using ephemeral agents. It needs no change to any pipeline beyond pointing the build tool at it, and it helps every project at once.

Illustration: the proxy effect

A build downloads 600 megabytes of libraries from the internet at about 10 megabytes a second, which takes a full minute. From a proxy on the local network at 200 megabytes a second, it takes three seconds. Multiplied by hundreds of builds a day, the difference is many hours of waiting removed.

14Build Tool Tuning

Letting the compiler and packager do less, and do it in parallel.

The build tool, whether Maven, Gradle, npm, a C++ compiler or another, does the actual compilation and packaging. Each has its own options for speed, and many teams never turn them on. Jenkins cannot make a slow tool fast, but it can give the tool a fair chance.

Incremental

Rebuild only what changed

Modern tools skip unchanged modules. This only works if the previous build’s outputs are available, which needs a warm workspace or a shared build cache.

Remote cache

Shared build cache

Some tools can store compiled results on a shared server keyed by their inputs. Another agent building the same code fetches the result instead of compiling.

Parallel

Parallel module builds

Many tools can build independent modules at once, using several processor cores. Turn it on, and check that the agent has the cores.

Daemon

Long-lived build processes

Some tools keep a helper process running to avoid start-up costs. This helps on warm agents, but gives no benefit on throw-away containers.

Skip

Skip what a stage does not need

Do not build documentation, run code formatting or create packages in a stage that only runs tests.

Memory

Right-sized memory

Too little memory makes tools slow through constant cleanup or swapping. Give builds enough, and watch memory graphs on the agent.

Match the tool to the agent

A build tool that runs eight parallel workers on an agent with two cores will not go faster; it will fight itself. Set parallelism to the number of cores available to the build, which in a container may be limited by its resource settings. Check the resource limits, not just the machine size.

i
Balance

Incremental builds and caches make pipelines faster but can hide problems that a clean build would reveal. Keep pull request builds fast with caches, and run a fully clean build on a schedule, such as nightly, to prove that the caches did not mask anything.

15Speeding Up Tests

Tests are usually the biggest block of real work.

Once the setup is lean, tests are often the largest share of a pipeline’s time. Speeding them up is a mix of running them smarter, running them side by side and removing waste inside them.

flowchart TD
    S["Whole test suite: 40 minutes"] --> SP["Split by past duration into balanced groups"]
    SP --> G1["Group 1 on agent A: about 10 minutes"]
    SP --> G2["Group 2 on agent B: about 10 minutes"]
    SP --> G3["Group 3 on agent C: about 10 minutes"]
    SP --> G4["Group 4 on agent D: about 10 minutes"]
    G1 --> J["Join results into one report"]
    G2 --> J
    G3 --> J
    G4 --> J
Figure 7: Balanced groups turn one long stage into several short ones running side by side.
TechniqueHow it helpsWatch out for
Split into balanced groupsRuns parts side by side; a plugin can compute groups from past test durationsRepeated setup per group; uneven groups waste time
Run fast tests firstQuick failures come earlyOrdering must be maintained as tests change
Remove fixed sleepsTests wait for a condition, not a guessed timeNeeds care to avoid flakiness
Share expensive fixturesStart a database once per group, not once per testTests must not depend on each other’s data
Use lighter test doublesReplace slow outside services with fast fakes in most testsKeep a few real end-to-end checks
Run only affected testsSkip tests unrelated to the changeRequires accurate dependency knowledge
Move slow tests off the pull requestKeeps feedback quick; run heavy suites after merge or nightlySome bugs are found later

The test pyramid

Many fast unit tests at the bottom, fewer integration tests in the middle and a handful of slow end-to-end tests at the top give the best speed for the confidence they provide. A pipeline with an inverted pyramid, mostly slow end-to-end tests, will always be slow and flaky.

Illustration: the hundred sleeps

A suite contains a hundred tests that each wait five seconds “to be safe” for a background job. That is over eight minutes of pure waiting. Replacing the fixed wait with a check that continues as soon as the job is done shortens each test to under a second, and the stage drops from fourteen minutes to six.

16Stage Order: Fail Fast

If something is going to fail, let it fail early and cheaply.

The order of stages affects how long a failing build wastes. If a formatting mistake is caught after forty minutes of tests, forty minutes were spent for nothing. If the cheap check runs first, the mistake is reported in thirty seconds.

flowchart LR
    A["Format and lint: 30 seconds"] --> B["Compile: 2 minutes"]
    B --> C["Unit tests: 5 minutes"]
    C --> D["Integration tests: 12 minutes"]
    D --> E["Security scan: 6 minutes"]
    E --> F["Package and publish: 3 minutes"]
    A -.-> X1["Fails here: wasted 30 seconds"]
    C -.-> X2["Fails here: wasted 7.5 minutes"]
    D -.-> X3["Fails here: wasted 19.5 minutes"]
Figure 8: Cheap, likely-to-fail checks first; expensive, unlikely-to-fail checks last.

How to order

  • Put cheap checks first: formatting, linting, compilation and quick unit tests.
  • Put likely-to-fail checks early if they are cheap, since they save the most time when they trigger.
  • Put expensive checks late, once the cheap ones have passed.
  • Run independent checks in parallel, for example static analysis and unit tests, so neither waits for the other.

Stopping parallel work early

When several branches run in parallel, the fail-fast option stops the remaining ones as soon as one fails, freeing their agents. Without it, the other branches run to the end, and the developer waits for results that no longer change the verdict.

i
Balance

Failing fast can hide other problems until the first is fixed, which means more rounds. For most teams the time saved on failing builds far outweighs this. For checks where developers want the full list of problems at once, such as linting, run them together in parallel instead.

17Skipping Work Nobody Needs

The fastest step is the one that does not run.

Many builds do work that cannot affect the result. A change to a documentation file does not need the full test suite. A change in one service of a large repository does not need every other service rebuilt. Declarative pipelines have conditions, written in a when directive, that decide whether a stage runs, and one of them looks at which files changed.

flowchart TD
    C["Change arrives"] --> Q{"Which files changed?"}
    Q -->|"Only documentation"| D["Skip build and tests; run link check"]
    Q -->|"Only service A"| A["Build and test service A only"]
    Q -->|"Shared library"| ALL["Build and test everything that depends on it"]
    Q -->|"Pipeline definition"| FULL["Run the full pipeline"]
Figure 9: Deciding what to run from what changed.
TechniqueSavesRisk
Run a stage only if certain paths changedWhole stages for unrelated changesA wrong path list can skip a needed check
Branch-based conditionsDeploy and slow stages on ordinary branchesConditions must be explicit and safe by default
Skip builds for tag-only or documentation commitsWhole buildsRules must be reviewed regularly
Reuse results of unchanged modulesRebuilding untouched partsNeeds a dependable build cache
Cancel outdated buildsBuilds for superseded commitsCareful with builds that must always finish
!
Safety first

Skipping is a risk trade. Always run the complete pipeline on the main branch and on releases, so that anything the shortcuts missed is caught before customers see it. Shortcuts belong on pull requests, where quick feedback matters most.

Illustration: the monorepo

A repository holds twelve services. Every change used to rebuild and test all of them, taking forty minutes. By running each service’s stages only when its own folder or a shared dependency changed, the typical change now takes eight minutes, and only shared changes trigger the full forty.

18Parallelism: How Much Is Enough?

Doing things side by side helps, until it does not.

The parallel step runs several branches at the same time. Used well, it shortens the critical path. Used carelessly, it wastes resources, overloads the controller and even slows the pipeline down.

1

Find independent work

Only steps that do not depend on each other can run in parallel. Look for stages that read the same input but produce separate outputs.

2

Check the setup cost

If each branch needs its own agent, checkout and dependency download, the extra setup may outweigh the gain for short tasks.

3

Balance the branches

The stage lasts as long as the slowest branch. Aim for branches of similar length.

4

Check the capacity

Four branches need four executors. On a busy fleet, they may wait in the queue and finish no sooner than one after another.

5

Limit the count

Hundreds of parallel branches in one pipeline burden the controller. Group them into a manageable number.

ApproachGood whenBad when
Parallel branches on separate agentsTasks are long and independentTasks are short; setup dominates
Parallel work on one agentThe agent has spare cores and the tasks are lightTasks compete for the same processor or memory
Tool-level parallelismThe build tool can use many coresLimits are set higher than the cores available
Very many small branchesNever, in most casesController overhead grows, results are hard to read

Illustration: too much of a good thing

A team splits their tests into sixty parallel branches. Each takes forty seconds of setup for ten seconds of tests, and the controller struggles to track sixty branches. Regrouping into six branches of ten groups each cuts the total from eleven minutes to four, and the controller load drops sharply.

19Agents, Workspaces and Reuse Within a Pipeline

Every time a stage asks for a new agent, something is set up again.

A pipeline can request an agent at the top, for the whole run, or separately for each stage. Each choice has costs and benefits. Requesting a new agent for every stage frees machines between stages, but every request may wait in the queue, and every new workspace needs a fresh checkout and dependencies.

DesignAdvantageCost
One agent for the whole pipelineOne checkout, warm workspace, no repeated queue waitsHolds the machine even during idle stages
An agent per stageMachine freed between stages; each stage may use a different environmentRepeated queue waits, checkouts and file transfers
Agent per stage with reuse of the same machineDifferent tools per stage without new queue waitsSlightly more complex definition
No agent while waitingExecutors freed during approvals and long external waitsFiles must be stashed or archived before

Container agents and the reuse option

When each stage runs in its own container image, such as one image for building and another for testing, a naive setup asks for a new machine for each stage. Declarative pipelines offer a reuse option for container agents inside a stage: it runs the container on the same machine and in the same workspace that the pipeline already holds, avoiding a new allocation and a new checkout.

Image size and pulling

Starting a container requires its image to be present on the machine. A large image takes time to download the first time. Keep images small, share common base layers, keep popular images on each machine or in a nearby mirror, and avoid pulling fresh copies on every run unless you need to.

i
Rule of thumb

Keep the pipeline on one agent while the work is continuous, and release the agent only when a long wait begins, such as a manual approval. Do not release and re-acquire agents between short stages, because each round trip costs more than it saves.

20Moving Files: Stash, Archive and Artifacts

Files that travel through the controller slow everyone down.

When a pipeline moves from one agent to another, files must follow. Jenkins offers stash and unstash for short hops within one build, and archiving for keeping files with the build record. Both normally send data through the controller, which is fine for small files and painful for large ones.

MethodSuitsPerformance note
Stash and unstashSmall sets of files passed to the next stageGoes through the controller; large stashes are slow
Archive artifactsReports and small packages worth keepingStored with the build; adding file fingerprints costs extra
External artifact repositoryLarge files, releases, imagesAgents talk to it directly and bypass the controller
Object storage through an artifact manager pluginLarge archives that still appear in the Jenkins interfaceFrees the controller’s disk and network

Practical rules

  • Stash only what the next stage needs, using precise include patterns, not the entire workspace.
  • Send big files to a repository, and pass only a version or address between stages.
  • Archive reports, not everything. Do not archive dependency folders or intermediate files.
  • Publish test results selectively. Extremely large result files slow down the reporting step and the page that shows them.

Illustration: the whole-workspace stash

A pipeline stashes the entire workspace, 1.2 gigabytes including dependency folders, so that the test stage can unstash it on another agent. The stash and unstash take four minutes and load the controller. Stashing only the compiled outputs, 40 megabytes, takes six seconds.

21Log Volume and Reporting

Every line of output travels to the controller and is stored there.

Commands running on an agent send their output to the controller as they run, and the controller stores it. A build that prints hundreds of thousands of lines creates real load: network traffic, disk writes and slow-loading log pages that few people can read anyway.

Quiet

Use quiet modes

Most tools have options that reduce output to warnings and errors. Turn them on for routine builds.

Progress

Avoid progress bars

Download progress bars print thousands of updates. Disable them in non-interactive builds.

Summary

Print summaries, not every item

Report counts and failures instead of listing thousands of passing items.

Files

Write details to files

Send verbose output to a file that is archived only when the build fails, so the log stays readable.

Debug

Debug output off by default

Turn on detailed logging only when investigating, and never leave it on in routine pipelines.

Time

Keep timestamps

Timestamps cost little and pay off in every investigation. Keep them on.

Reporting costs

Publishing test results, coverage and analysis reports is useful, but each report costs time to process, especially when files are large or numerous. Publish what people actually read, publish once at the end of a parallel group rather than per branch when possible, and watch the duration of the reporting steps themselves.

!
Also a safety matter

The more output you produce, the more chances a secret or sensitive value has to slip into the log. Lean logs are faster and safer.

Illustration: the chatty download

A dependency download prints a progress line for every one of 3,000 files, and 200 builds a day do this. That is 600,000 log lines daily from one step. Switching the tool to quiet mode cuts it to a few lines per build, shrinks log storage and makes real errors easy to find.

22Shared Libraries and Start-up Overhead

Reusable pipeline code has a cost at the start of every build.

A shared library is a reusable module of pipeline code that many Jenkinsfiles can call. It keeps pipelines short and consistent, which is excellent. But loading a library takes time. At the start of each build, Jenkins fetches the library from its source repository and prepares it, and a large library can add several seconds or more to every run. On a busy system with many pipelines, this also burdens the controller and the source server.

PracticeEffect on speed
Pin to a fixed versionAllows caching, and avoids surprises from library changes
Enable caching of fetched versions on the controllerAvoids fetching the library from source control on every build
Keep the library small and focusedLess to load and compile per run
Avoid heavy logic in library functionsHeavy logic runs on the controller and slows every pipeline
Load libraries only where usedSkip loading libraries in pipelines that do not need them
Load libraries implicitly only when truly universalImplicit loading adds cost to every job on the controller

Pipeline start-up in general

Before the first stage begins, Jenkins parses the pipeline definition, loads libraries, fetches the Jenkinsfile and prepares the run. For very large Jenkinsfiles with many stages and thousands of lines, this can take noticeable time. Keep the Jenkinsfile lean by moving repeated logic into libraries or scripts, and split enormous pipelines into smaller ones that call each other.

i
Design tip

If your pipelines take a long time between “started” and the first stage, suspect start-up overhead: library fetching, a huge Jenkinsfile or a slow source server. Timestamps at the very top of the log will show it.

23Concurrent Builds, Waiting and Polling

Three quiet ways to waste capacity.

Concurrent builds of the same branch

When commits arrive faster than builds finish, several builds of the same branch run or queue at once. Only the newest matters. Options exist to disable concurrent builds, or to abort the previous build when a new one starts, and a milestone step can make older builds stop when a newer one passes a checkpoint. These settings free capacity for useful work and give developers the freshest answer.

flowchart TD
    C1["Commit 1 starts build"] --> R1["Running"]
    C2["Commit 2 arrives"] --> Q{"Rule for older build?"}
    Q -->|"Let it run"| W["Both run: old result is stale"]
    Q -->|"Abort previous"| A["Old build stops; new build runs"]
    A --> F["Fresh result sooner, capacity saved"]
Figure 10: Aborting outdated builds saves capacity and gives the freshest result.

Waiting on agents

A build waiting for an outside event, such as an approval or an external system, should not hold an executor. Place long waits outside any agent block, so the slot returns to the pool. Files needed afterwards should be stashed or stored elsewhere.

Polling efficiently

Steps that poll, checking again and again until something is ready, should back off. The waitUntil step increases the pause between checks, which reduces load. Wrap polling in a timeout, avoid very short fixed sleeps in loops and print only occasional progress lines.

WasteCostFix
Builds for superseded commitsCapacity and stale resultsAbort previous builds or use milestones
Approvals inside an agent blockAn idle executor for hoursWait outside any agent
Tight polling loopsLoad on controller and target systemBack off between checks
Fixed long sleepsTime always spent even when ready earlierPoll for readiness with a deadline

Illustration: the fixed sleep

A deployment step sleeps two minutes to “let the service start.” The service is usually ready in twenty seconds. Replacing the sleep with a poll that checks readiness every few seconds, with a five-minute deadline, saves an hour of pipeline time across thirty deployments a day and catches real failures sooner.

24Monitoring, Metrics and Regression Alerts

Keeping the gains you worked for.

Performance work fades unless someone watches it. A pipeline that took eight minutes after tuning drifts back to twenty over a year as tests are added and caches go stale. Track the numbers, and raise an alarm when they drift.

MetricWhy it mattersWarning sign
Median and 95th percentile durationTypical and worst-case experienceSlow upward drift; a widening gap between the two
Queue timeSeparates waiting from workingMedian above a minute
Duration per stageFinds the stage responsible for driftOne stage growing week after week
Cache hit rateShows whether caches actually workFalling rate after a change to dependencies or agents
Flaky test rateReruns waste timeBuilds routinely rerun to get green
Executor utilizationShows over- or under-capacitySustained near 100 percent or near zero
Controller memory and disk activityShows whether the controller is the bottleneckFrequent long pauses; heavy disk waits
Cost per buildTies speed to moneySudden jumps

Regression alerts

Set an alert when a stage’s typical duration rises more than, say, twenty percent above its recent average, or when the 95th percentile crosses a chosen line. Catching a slowdown within a day means it can be traced to a single recent change. Catching it after six months means an archaeological dig.

A performance budget

Many teams agree a budget for each stage: ten minutes for pull requests, thirty for the main branch. When a change would break the budget, the team pays for it by speeding something else up, moving the check elsewhere or explicitly raising the budget with a reason. The budget turns performance from wishful thinking into a shared rule.

Illustration: the drift alarm

A team’s alert notices that the median test stage rose from 11 to 14 minutes in one week. Looking at the changes from that week, they find a new set of end-to-end tests added to the pull request pipeline. They move those tests to the main branch, and the median returns to eleven minutes before anyone had time to grumble.

25Useful Design Patterns

Proven ways of arranging fast pipelines.

Pattern 1: Cheap checks first, in parallel

Run formatting, linting, compilation and unit tests at the start, side by side where independent. Failures surface within a couple of minutes.

Pattern 2: Fast pull request lane, full main lane

Give pull requests a lean pipeline of quick checks, and run the slow suites on the main branch after merge or on a schedule. Developers get quick feedback and the full safety net still exists.

Pattern 3: Shallow clone, package proxy, warm cache

Combine three simple setup improvements: a shallow checkout, a nearby package proxy and a persistent cache volume. Together they usually remove most of the setup time on ephemeral agents.

Pattern 4: Change-aware pipelines

Use path conditions so each build runs only the stages relevant to what changed, with a full run on the main branch and on releases.

Pattern 5: Balanced test splits

Divide slow test suites into groups balanced by recorded durations, run them in parallel and merge the reports into one verdict.

Pattern 6: Thin script, heavy tools

Keep the pipeline script a coordinator, and move data processing into commands on agents. The controller stays responsive.

Pattern 7: Abort the outdated

Cancel older builds of a branch when a newer commit arrives, so capacity goes to the results that matter.

Pattern 8: Budgets and drift alerts

Agree stage duration budgets and alert on drift, so performance is protected as the code grows.

26Anti-patterns to Avoid

Habits that look fine at first and hurt later.

ANTI-PATTERN 01Avoid
What people do

They tune by intuition, changing several things at once without measuring.

Why it hurts

Nobody knows what helped, some changes make things worse, and effort goes to parts that were never slow.

Better approach

Measure many runs, change one thing, verify, and record the result.

ANTI-PATTERN 02Avoid
What people do

They do heavy data processing inside the pipeline script.

Why it hurts

It runs slowly on the controller, uses its memory and processor, and slows every other pipeline.

Better approach

Run processing as a command on the agent and read the short result.

ANTI-PATTERN 03Avoid
What people do

They clone the full history and re-download every dependency on every build.

Why it hurts

Setup dominates the run time on fresh agents, and the same bytes cross the network hundreds of times a day.

Better approach

Use shallow checkouts, package proxies and caches keyed by dependency versions.

ANTI-PATTERN 04Avoid
What people do

They stash the whole workspace or archive everything.

Why it hurts

Large transfers through the controller slow builds and fill its disk.

Better approach

Stash only what the next stage needs, and use artifact repositories for large files.

ANTI-PATTERN 05Avoid
What people do

They split work into dozens of tiny parallel branches.

Why it hurts

Setup repeats in each branch, the controller tracks too much, and the queue may make the branches run one after another anyway.

Better approach

Use a small number of balanced branches sized to the available capacity.

ANTI-PATTERN 06Avoid
What people do

They use long fixed sleeps and tight polling loops.

Why it hurts

Time is wasted when the thing is ready early, and load is created when checks are too frequent.

Better approach

Poll with backoff and a deadline, and continue the moment readiness is confirmed.

ANTI-PATTERN 07Avoid
What people do

They skip checks aggressively everywhere to gain speed.

Why it hurts

Bugs reach the main branch and production, and the time saved is repaid many times over in incidents.

Better approach

Skip work on pull requests where safe, and run the complete pipeline on main and releases.

ANTI-PATTERN 08Avoid
What people do

They fix performance once and never look at it again.

Why it hurts

The pipeline drifts back to its old slowness, and the effort is lost.

Better approach

Track durations, set budgets and alert on drift.

27Best Practices and Common Mistakes

A checklist to apply to any Jenkinsfile today.

Do this

  • Turn on timestamps and read the timeline.
  • Measure queue time and run time separately.
  • Find the critical path and attack the biggest piece.
  • Use shallow checkouts and check out once per build.
  • Put a package proxy and caches in front of downloads.
  • Order stages so cheap checks fail first.
  • Run independent work in parallel with balanced groups.
  • Skip unneeded work on pull requests, run everything on main.
  • Keep the pipeline script thin and logs lean.
  • Track durations and alert on drift.

Avoid this

  • Tuning without measuring.
  • Optimizing steps that are not on the critical path.
  • Heavy work in the pipeline script on the controller.
  • Hundreds of tiny steps in a row.
  • Stashing or archiving entire workspaces.
  • Dozens of tiny parallel branches.
  • Fixed sleeps and unbounded polling.
  • Verbose logs and progress bars in routine builds.
  • Skipping checks on the main branch.

Mistakes people make when they are new

Blaming the code when the queue is the problem. Check whether builds wait before they run.

Judging by one run. Builds vary. Use at least twenty runs and look at the middle and the slow tail.

Forgetting that shallow means less history. Steps that read history may fail after the change.

Trusting stale caches. Key caches by exact dependency versions and run a clean build on a schedule.

Over-parallelizing. More branches do not always mean faster, especially with repeated setup and a busy fleet.

Ignoring the controller. A slow controller slows every pipeline, no matter how well each one is written.

28Advantages, Disadvantages and Trade-offs

An honest look at tuning, its rewards and its costs.

Rewards of tuning

  • Faster feedback and happier developers.
  • Smaller changes, since waiting is short.
  • Lower cloud bills and better use of machines.
  • Shorter queues for everyone.
  • A calmer, more responsive controller.
  • Better understanding of how the pipeline works.

Costs and risks

  • Engineering time spent that could build features.
  • Caches and shortcuts can hide real problems.
  • More moving parts, such as proxies and shared volumes.
  • Parallel and skipped work makes pipelines harder to reason about.
  • Fast settings, such as relaxed durability, reduce safety.
  • Gains fade without monitoring.

Trade-offs to weigh

ChoiceBenefitCost
Shallow cloneMuch faster checkoutSteps that need history may fail
Persistent cachesWarm starts on fresh agentsRisk of stale or corrupted caches
Performance-optimized durabilityLess disk load, faster pipelinesRunning pipelines lost on a controller crash
More parallel branchesShorter critical pathMore setup and controller load
Skipping unrelated stagesFaster pull requestsA wrong rule can miss a needed check
Agent per stageFlexible environments, freed machinesRepeated queue waits and setup
Quiet logsFaster and saferLess detail when debugging
Strict budgetsSpeed is protectedOccasional friction when adding checks

There is no universally right answer. The right settings depend on how often builds run, how expensive your machines are, how much risk you accept and how much your developers value quick answers. Choose on purpose, measure the result and write down why.

29Real-World and Industry Examples

How the ideas look in the kinds of organizations that run Jenkins at scale.

An online retailer

Retail teams with hundreds of builds a day treat pipeline duration as a product metric. They publish dashboards of median and slow-tail durations per service, set budgets for pull requests and investigate whenever a stage drifts.

A company with a large monorepo

Organizations that keep many services in one repository rely on change-aware pipelines, sparse checkouts and shared build caches so that a small change does not rebuild the world.

A mobile studio

Mobile builds are heavy and machines are costly. Studios cache dependencies aggressively, split device tests across many agents, and run the slowest suites only on release branches.

A bank

Regulated teams cannot skip checks on release branches, so they tune elsewhere: fast lanes for pull requests, proxies for dependencies, quiet logs and balanced test splits, keeping the full gate quick enough to run often.

An open-source project

Public projects with volunteer capacity make every minute count. They use shallow clones, cache dependencies, cancel outdated pull request builds and keep the default pipeline small.

A small startup

A team of eight adds timestamps, a shallow checkout and a package proxy in one afternoon. Their pipeline drops from twenty-six minutes to twelve without touching test code.

30A Complete Story: From Forty-five Minutes to Eleven

Follow one imaginary team through a tuning project.

A team’s pull request pipeline takes about forty-five minutes. Developers complain, and the queue grows at busy hours. Instead of guessing, they start by measuring.

1

Measure

They switch on timestamps and collect the last thirty runs. The median is 45 minutes: 8 waiting in the queue, 12 in checkout and downloads, 5 compiling, 17 testing and 3 publishing.

2

Biggest cost on the critical path

Setup, at twelve minutes, is nearly as large as compiling and publishing combined, and tests are the largest block. Queue time is next.

3

Fix setup

They switch to a shallow clone without tags and add a package proxy. Setup falls from twelve minutes to about ninety seconds.

4

Fix the queue

They cancel outdated builds when a new commit arrives and keep some warm agents for the morning peak. Median queue time drops from eight minutes to under one.

5

Split the tests

They divide the 17-minute suite into four balanced groups on parallel agents. The stage falls to about six minutes, including setup.

6

Order the stages

They move linting and unit tests to the front and run static analysis in parallel with compilation. Failing builds now report in under three minutes.

7

Trim the rest

They stash only compiled output, switch tools to quiet mode and set performance-optimized durability for pull request pipelines.

8

Guard

They set a ten-minute budget for pull requests, plot the median per stage and alert on twenty percent drift. Six months later the median is still about eleven minutes.

The team never rewrote a test or bought a faster machine. They measured, found the boring causes, fixed them one at a time and kept watching. The result was four times faster feedback and lower cloud costs.

Fast pipelines are not built by genius. They are kept fast by measuring.

31Troubleshooting Guide

Symptoms, likely causes and calm fixes.

SymptomLikely causeWhat to do
Long gap before the first stageLibrary fetching, large Jenkinsfile or slow source serverCheck timestamps at the top; cache libraries and slim the file
Long gap after start on a fresh agentCheckout and dependency downloadsShallow clone, package proxy, persistent cache
Build durations look fine but developers waitQueue time not counted in the durationMeasure queue time separately
Parallel stage no faster than serialBranches waiting in the queue or sharing one small agentCheck capacity; reduce branch count; balance groups
Controller sluggish under loadHeavy script logic, many steps or disk pressureSlim the scripts; consider durability setting; check disk and memory
Builds slower after adding cachesCache download or restore costs more than it savesMeasure hit rate; cache only large, stable items
Version step fails after shallow cloneStep needs tags or historyFetch tags or increase depth for that step
Stash or unstash takes minutesStashing too much through the controllerNarrow includes; use an artifact repository
Log page slow to loadEnormous log outputQuiet modes; write details to files
Pipeline slowly gets slower over monthsDrift as tests and dependencies growTrack per-stage durations; set budgets and alerts

A calm debugging routine

  1. Separate queue time from run time for the last twenty or more builds.
  2. Read the timestamps of a typical slow run and mark the biggest gaps.
  3. Check the critical path, and ignore anything not on it.
  4. Check the agent’s graphs to see whether the step is limited by processor, memory, disk or network.
  5. Change one thing at a time, measure again and record the result.

32Plain-English Glossary

Every important word in this guide in one place.

WordSimple meaning
JenkinsA free automation server that builds, tests and delivers software.
PipelineA written recipe of the steps Jenkins follows.
JenkinsfileThe text file holding the pipeline.
StageA named phase of the pipeline.
StepOne single action inside a stage.
ControllerThe main Jenkins server that runs the pipeline logic.
AgentA worker machine or container that runs the commands.
ExecutorA slot on an agent that runs one build at a time.
Wall-clock timeThe time on the clock the developer actually waits.
Queue timeTime a build waits for a free machine.
Critical pathThe longest chain of dependent steps that decides total time.
LatencyHow long one build takes.
ThroughputHow many builds finish per hour.
CacheA saved result reused to avoid repeating work.
Shallow cloneFetching only recent history of a repository.
Package proxyA local server that stores downloaded libraries for reuse.
Durability settingHow often a pipeline saves its progress to disk.
Fail fastStopping early when something fails.
StashTemporary storage of files passed between stages.
PercentileThe value below which a given share of measurements fall.
Performance budgetAn agreed maximum duration for a stage or pipeline.

33Frequently Asked Questions

Short answers to the questions that come up most often.

Q1Where should I start when my pipeline is slow?
Turn on timestamps, collect at least twenty runs, and separate queue time from run time. Then find the biggest piece on the critical path and fix that first.
Q2Why does a build take longer than the duration Jenkins shows?
The shown duration usually counts only the time after the build started. Waiting in the queue happens before that, so measure queue time separately.
Q3What is the quickest win for most pipelines?
Reducing setup time: a shallow checkout, a package proxy and cached dependencies. Downloads and clones often take more time than compiling.
Q4Does the pipeline script run on the agent?
No. The steps that run commands run on the agent, but the pipeline script that decides what happens next runs on the controller, so keep it light.
Q5What does the durability setting do?
It controls how often a pipeline saves its progress. The performance-optimized setting saves less often, reducing disk load, but running pipelines cannot resume after a controller crash.
Q6Should I run everything in parallel?
No. Parallelism helps for long, independent tasks, but repeated setup, limited capacity and controller overhead can make many small branches slower than a few balanced ones.
Q7Is a shallow clone always safe?
Not always. Steps that need tags or history, such as computing a version or finding a merge base, may fail. Increase the depth or fetch what those steps need.
Q8How do I avoid rebuilding everything for a small change?
Use conditions that run stages only when related files changed, and use incremental builds or shared build caches. Always run the full pipeline on the main branch and releases.
Q9Why should I abort older builds of the same branch?
Only the newest commit’s result matters. Aborting older builds frees capacity, shortens queues and gives the developer the freshest answer.
Q10Do logs affect performance?
Yes. Output travels to the controller and is stored there. Huge logs add load and make pages slow. Use quiet modes, avoid progress bars and write details to files.
Q11How do I stop the pipeline from getting slow again?
Track median and slow-tail durations per stage, agree a budget, and alert when a stage drifts above it. Catching a slowdown early makes the cause easy to find.
Q12Should I buy faster machines or tune the pipeline?
Measure first. If time goes to waiting, downloads or repeated work, faster machines will not help much. Tuning is usually cheaper, and it makes any new machines more effective.

34Summary and Key Takeaways

The whole story in a few lines.

Pipeline performance tuning is the disciplined removal of waste. Start by measuring: timestamps, many runs, and queue time separated from run time. Find the critical path and attack its biggest piece. The usual culprits are ordinary ones: queue waits, full clones, repeated downloads, tests run in a poor order or one after another, oversized file transfers, chatty logs and heavy scripting on the controller. Fix them one at a time, verify each change, and keep watching with budgets and drift alerts so the gains last.

Key Takeaways

  • Measure before you change. Use timestamps and at least twenty runs, and separate queue time from run time.
  • Shorten the critical path. Only the longest chain of dependent steps matters, so attack the biggest piece first.
  • Fix setup first. Shallow checkouts, package proxies and keyed caches often remove the largest hidden delays.
  • Order and split the work. Run cheap checks first, run independent work in parallel with a small number of balanced branches, and skip unneeded work on pull requests.
  • Protect the controller. Keep pipeline scripts thin, use fewer and bigger steps, choose the durability setting deliberately and keep logs and file transfers lean.
  • Do not waste capacity. Abort outdated builds, never hold an executor during long waits, and poll with backoff and a deadline.
  • Keep the gains. Track medians and slow tails per stage, set duration budgets and alert on drift.