The Timeout Step in Jenkins
Learn how to give every part of your pipeline a deadline: how the timeout step works, where to place it, how to choose fair limits, how it combines with retries and approvals, and how to clean up when time runs out.
Every experienced engineer has met a hung build. A test waits forever for a network answer that will never come. A deployment tool asks a question nobody sees. An approval prompt sits unanswered over a long weekend. Nothing fails, nothing finishes, and the build simply stays on the screen, holding a machine and blocking the queue behind it.
Jenkins gives you a simple tool against this: the timeout step. You wrap it around part of your pipeline and give it a deadline. If the wrapped work finishes in time, nothing special happens. If not, Jenkins stops the work, marks the run clearly, and lets your pipeline clean up. A tiny piece of configuration turns an open-ended wait into a predictable one.
This guide starts from zero. Every new word is explained when it first appears, everyday pictures make the ideas stick, and later chapters cover what experienced engineers care about: choosing limits that are fair, telling a timeout apart from a person pressing stop, combining timeouts with retries, cleaning up leftovers, and keeping costs and queues under control.
1What Is the Timeout Step?
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.
The timeout step is a special kind of step called a wrapper. It does not do work itself. Instead, it surrounds other steps and watches the clock. You tell it how long the wrapped steps may take. If they finish within the limit, all is well. If the limit passes first, the timeout step interrupts the wrapped steps and ends them.
Think of a kitchen timer for a pot of pasta. You do not stand and stare at the pot. You set the timer, and when it rings you act. If the pasta was done early, you take it off the heat and the timer no longer matters. If the timer rings and something is still wrong, you stop and deal with it, instead of letting the pot boil dry for hours. The timeout step is the timer, and your pipeline steps are the pot.
A timeout is not a punishment or a guess about failure. It is a promise the team makes: “this should not take longer than this, and if it does, something is wrong and a human should know.”
The timeout step belongs to the standard set of pipeline steps that ships with Jenkins, so it is available almost everywhere. It works in both styles of pipeline, and it can be used at three levels: around a group of steps, around a whole stage, or around the entire pipeline. The rest of this guide explains how to choose among those.
2Why the Timeout Step Exists
The problem it solves and how the idea grew.
The problem: waiting has no natural end
Most things in a pipeline end on their own: a compile finishes, a test suite completes. But some things depend on the outside world. A network connection may stall. A remote service may never reply. A program may enter an endless loop because of a rare bug. A lock may never be released. A person may forget to answer a question. In all these cases, the pipeline has no built-in reason to stop.
The cost of such a hang is larger than it looks. The build holds an executor, a work slot on an agent machine, so other builds queue behind it. On cloud machines that are billed by the minute, the hang costs real money. The team may not notice for hours, because nothing is red; the build is just quietly running. When they finally do notice, the code change that started it is old news.
Hung jobs and manual kills
Administrators noticed stuck builds by chance and killed them by hand.
Build-timeout plugin
For classic web-form jobs, a plugin added the ability to abort builds that ran too long.
Pipeline as code
Jenkins 2.0, released in 2016, made pipelines central. Deadlines had to be expressed inside the pipeline file itself.
The timeout step
A wrapper step let any block of a pipeline carry its own deadline, as small or as large as needed.
Declarative options
Declarative Pipeline added a timeout option at pipeline and stage level, making deadlines part of the standard structure.
3Core Concepts You Need First
A handful of small ideas that make everything else easy.
Wrapper step
A wrapper step takes a group of other steps, called its body, and runs them with some extra behavior added around them. The timeout step adds a deadline. Other wrappers add retries, locks or credentials.
Executor and agent
Jenkins has a main server, the controller, and worker machines called agents. Each agent has a limited number of executors, the slots that run one job at a time. A hung build occupies an executor and prevents others from using it.
Build result
Every run ends with a result: success, unstable, failure or aborted. When a timeout expires, the normal result is aborted, shown in gray. This is important: a timeout is not reported as a failure by default, and the difference affects your alerts.
Interrupt
To interrupt a step is to ask it to stop right now. Jenkins does this by signaling the running work. Most well-behaved steps stop quickly. Some, such as programs that ignore stop requests, may need more effort.
Post section
The post section is a block that runs when a stage or pipeline ends, whatever the result. It has a condition named aborted that reacts to aborted runs, which is where timeouts land.
| Term | Simple meaning | Why it matters for timeouts |
|---|---|---|
| Wrapper | A step that surrounds other steps | The timeout step is one |
| Body | The steps inside the wrapper | What gets the deadline |
| Executor | A work slot on an agent | Freed when a hung build is stopped |
| Interrupt | A request to stop | How the timeout ends the body |
| Aborted | The gray result | What a timeout usually produces |
| Post section | End-of-run reactions | Where cleanup and alerts go |
4Architecture and Components
Which parts of Jenkins take part when a timeout is set.
The timeout step is not a separate service. It lives inside the pipeline engine on the controller. When a pipeline enters a timeout block, the engine starts a timer, runs the body, and keeps watching. Whichever happens first, the body finishing or the timer expiring, decides what comes next.
flowchart LR
JF["Jenkinsfile with timeout block"] --> ENG["Pipeline Engine on Controller"]
ENG --> TMR["Timer starts"]
ENG --> BODY["Body steps run on agent"]
BODY --> AGT["Agent executes commands"]
BODY -->|"finishes first"| OK["Timer cancelled, run continues"]
TMR -->|"expires first"| INT["Interrupt sent to body"]
INT --> AGT
INT --> AB["Result becomes aborted"]
AB --> POST["Post section: aborted and cleanup"]
POST --> NOTI["Alerts to team"]
POST --> FREE["Executor released"]
Read the diagram from left to right. The pipeline file contains a timeout block. The engine starts a timer and runs the body on an agent. If the body finishes first, the timer is cancelled and the run continues as normal. If the timer expires first, Jenkins interrupts the body, the result becomes aborted, and the post section runs. The post section can send alerts and clean up, and the executor is freed for other builds.
Controller
Holds the timer. Timers run on the controller, not on the agent, so they keep counting even if the agent is busy or slow.
Pipeline engine
Starts the timer, runs the body and decides which finishes first.
Agent
Runs the body’s commands. Receives the interrupt when the time runs out.
Basic Steps plugin
Provides the timeout step, along with retry, sleep and waitUntil, in the standard steps bundle.
Post section
Reacts to the aborted result by cleaning resources and telling people.
Build log
Shows a clear message that the timeout was exceeded, which is your first clue when investigating.
5Anatomy: The Three Settings
A timeout is described by three simple settings.
time
The length of the deadline, given as a whole number, such as 10 or 45. It has no meaning by itself until combined with a unit.
unit
What the number counts: seconds, minutes, hours, days and a few tiny units. If you leave it out, Jenkins assumes minutes.
activity
A switch. Off by default, meaning the clock measures total time. On, the clock measures silence: it restarts whenever the body writes something to the log.
The units
| Unit | Typical use |
|---|---|
| SECONDS | Short network calls, health checks, quick scripts |
| MINUTES (default) | Builds, tests, deployments, most everyday work |
| HOURS | Long test suites, whole-pipeline limits, approvals |
| DAYS | Sign-offs by other teams, very long approvals; use rarely |
| MILLISECONDS and smaller | Available but almost never useful in pipelines |
Reading a timeout in plain words
A timeout of “time 30, unit MINUTES” reads: “Everything inside this block must finish within thirty minutes.” A timeout of “time 5, unit MINUTES, activity on” reads: “If this block goes five minutes without printing anything, stop it.” These two are very different tools, as Chapter 9 explains.
Forgetting the unit. A timeout written as just “time 30” means thirty minutes, which may be very different from what the author had in mind, for example thirty seconds. Always write the unit explicitly so anyone can read it correctly.
Example: two deadlines for one stage
A deployment stage has a total limit of twenty minutes. Inside it, a health check that polls a service has its own limit of two minutes. If the service never becomes healthy, the inner deadline stops the polling after two minutes, and the outer limit remains as a safety net for anything else in the stage.
6Three Places to Put a Timeout
Around steps, around a stage, or around the whole pipeline.
flowchart TD
P["Pipeline level timeout: whole run"] --> S1["Stage: Build"]
P --> S2["Stage: Test with stage level timeout"]
P --> S3["Stage: Deploy"]
S2 --> ST1["Step group with step level timeout"]
S2 --> ST2["Other steps"]
S3 --> ST3["Health check with short timeout"]
| Level | Where it is written | What it limits | Best for |
|---|---|---|---|
| Pipeline | In the options of the whole pipeline | The entire run, from start to finish | A final safety net against anything going wrong anywhere |
| Stage | In the options of one stage | That stage only | Giving each phase a realistic budget |
| Step group | The timeout wrapper around specific steps | Just those steps | Risky operations such as network calls, polling, approvals |
Pipeline level
A timeout in the pipeline’s options applies to the whole run. It is a coarse tool: it protects against everything, but it cannot tell you which part was slow. It also includes any waiting for human approvals, so a pipeline with an approval prompt needs a total limit that is longer than the longest approval you allow.
Stage level
A timeout in a stage’s options applies to that stage only. It expresses a realistic budget for each phase: ten minutes to build, twenty to test, five to deploy. When a limit is hit, the report names the stage, which points directly at the problem.
Step level
The wrapper step is the most precise. You put it around exactly the operation that could hang, and leave everything else alone. It is the best tool for calls to outside systems and for polling loops.
Use all three. A pipeline limit as the last resort, stage limits as realistic budgets, and step limits around anything that depends on the outside world. The inner ones usually trigger first, giving the clearest message.
7The Life of a Timeout
What happens, in order, from the start of the block to its end.
flowchart TD
A["Pipeline reaches timeout block"] --> B["Timer starts on controller"]
B --> C["Body steps begin"]
C --> D{"Which happens first?"}
D -->|"Body finishes"| E["Timer cancelled"]
E --> F["Run continues normally"]
D -->|"Timer expires"| G["Interrupt sent to body"]
G --> H["Body stops"]
H --> I["Log shows timeout exceeded"]
I --> J["Result set to aborted"]
J --> K["Post section runs"]
Entry
The pipeline reaches the block. The engine records the current time and computes when the deadline will fall.
Execution
The body runs exactly as it would without the wrapper. The timeout adds no overhead worth mentioning.
Happy path
If the body finishes in time, the timer is cancelled and the pipeline moves on. Nothing in the log announces it.
Expiry
If the deadline arrives first, the engine interrupts the body. A message in the log says that the timeout was exceeded and that nested steps are being cancelled.
Unwinding
Steps inside the body stop, cleanup blocks inside them get a chance to run, and control leaves the timeout block.
Result
Unless something catches the interruption, the run ends as aborted, and the post section runs its aborted and cleanup conditions.
Two observations follow. First, the happy path is silent, so you cannot tell from the log alone how close a build came to its limit. Add your own timing measurements if you want that information. Second, the unhappy path leaves clear evidence in the log, which makes timeouts easy to find when you search for them.
8What Happens When Time Runs Out
Aborted, not failed, and why that matters.
The result is aborted
By default, an expired timeout ends the run as aborted, the gray state that Jenkins also uses when a person presses the stop button. It does not use the red failure state. This is a deliberate design: the timeout interrupts the work rather than reporting that the work failed on its own merits.
Why this matters to alerts
If your alerts listen only to failures, a timed-out build slips by in silence. Many teams discover this after a week of quiet hung builds. Use the aborted condition in the post section, or treat aborted as unsuccessful, so a timeout produces a message.
| Alert rule | Reacts to timeout? | Comment |
|---|---|---|
| Post: failure only | No | Timeouts pass unnoticed |
| Post: aborted | Yes | Also fires for people pressing stop |
| Post: unsuccessful | Yes | Covers failure, unstable and aborted together |
| Post: regression | Yes, if the previous run succeeded | Good for noise-free alerts |
What happens to the running work
When the interrupt arrives, Jenkins asks the running steps to stop. A shell command is sent a request to terminate, and Jenkins also tries to stop the programs it started. Most programs comply within seconds. Programs that ignore the request, or that started their own background helpers, may keep running for a while. Chapter 19 covers this in detail.
A timeout stops the pipeline’s work. It does not automatically undo the effects of that work. A deployment that was half finished when the time ran out stays half finished. Design your post section to check the state and repair or roll back.
Illustration: the half-finished deployment
A team’s deploy stage has a ten-minute limit. One night a slow network makes the upload take eleven minutes. The timeout aborts the pipeline with a partly uploaded package in place. Because the post section had an aborted block that verified and restored the previous version, customers never saw the half-finished state.
9Total Time Versus Inactivity
Two different clocks for two different problems.
By default, the timeout measures total time: from the moment the block starts, the clock counts, and when it reaches the limit the body is stopped. There is a second mode, switched on by the activity setting, that measures inactivity: the clock restarts every time the body writes something to the build log. It stops the body only if the log stays silent for the whole period.
flowchart LR
subgraph ABS["Total time clock"]
A1["Start"] --> A2["Log output"] --> A3["Log output"] --> A4["Limit reached: stop"]
end
subgraph ACT["Inactivity clock"]
B1["Start"] --> B2["Log output resets clock"] --> B3["Log output resets clock"] --> B4["Silence for full period: stop"]
end
| Question | Total time | Inactivity |
|---|---|---|
| What does it catch? | Anything that takes too long overall | Work that has gone silent, likely hung |
| Good for | Predictable tasks with a known size | Long tasks that print progress, such as big downloads or long test suites |
| Weakness | A legitimately long run may be cut off | A task that runs a long time without printing gets stopped wrongly |
| A runaway task that prints forever | Caught at the limit | Never caught, because it keeps printing |
Combining both
The two clocks complement each other. Wrap a long task in an outer total-time timeout, for example two hours, and an inner inactivity timeout, for example ten minutes. The inner one catches a hang within ten minutes. The outer one catches a runaway that keeps printing beyond two hours.
Inactivity timeouts only work well when the task prints regularly. Configure long-running tools to print progress lines, or the inactivity clock may cut off a perfectly healthy silent task.
10Choosing the Right Time
Too short causes false alarms. Too long defeats the purpose.
The hardest part of using timeouts is choosing the number. A limit that is too tight aborts healthy builds that were merely a little slow, teaching people to distrust the pipeline. A limit that is too generous lets hung builds waste hours. The right value comes from measurement, not from guessing.
flowchart LR
M["Measure recent successful durations"] --> P["Find a high percentile such as the 95th"]
P --> B["Add a safety margin of 50 to 100 percent"]
B --> S["Set the timeout"]
S --> O["Observe timeouts and near misses"]
O --> R{"Too many false alarms or too slow to catch hangs?"}
R -->|"Yes"| M
R -->|"No"| K["Keep and review every quarter"]
Collect data
Look at the duration of the last few dozen successful runs of the stage or step. Jenkins shows these on the job page.
Ignore the extremes
Take a high percentile, such as the one where 95 of 100 runs finished, instead of the average. Averages hide the slow days.
Add a margin
Multiply by one and a half to two. A stage that usually takes twelve minutes and at worst fifteen deserves a limit of about twenty-five.
Watch and adjust
After a few weeks, check how often the timeout fired and whether each firing was a real hang.
| Type of work | Typical duration | Sensible limit |
|---|---|---|
| Quick network call or health check | Seconds | 30 seconds to 2 minutes |
| Compile and unit tests | 5 to 15 minutes | 2 times the 95th percentile |
| Integration tests | 15 to 40 minutes | 1.5 to 2 times the 95th percentile |
| Deployment | 2 to 10 minutes | 2 to 3 times normal |
| Human approval | Minutes to hours | Match real working patterns, often several hours |
| Whole pipeline | Sum of stages | Sum of stage limits, plus approval time |
Illustration: the shifting baseline
A team sets a twenty-minute limit for tests that took twelve minutes. Over a year, the test suite grows, and the normal time climbs to nineteen minutes. Suddenly one build in five times out on slow days. The limit needed to move with the suite. A quarterly review of limits would have raised the number before anyone was annoyed.
11Nested Timeouts
Deadlines inside deadlines, and which one wins.
Timeouts can be nested. A step-level timeout can sit inside a stage-level one, which sits inside a pipeline-level one. Each has its own timer. Whichever timer expires first stops the work inside it, and the interruption unwinds outward.
flowchart TD
O["Outer: whole pipeline 2 hours"] --> M["Middle: Test stage 30 minutes"]
M --> I["Inner: database wait 3 minutes"]
I --> R1{"Inner expires first?"}
R1 -->|"Yes"| X["Inner interrupt: precise message about database"]
R1 -->|"No"| R2{"Stage limit reached?"}
R2 -->|"Yes"| Y["Stage interrupt: message names the stage"]
R2 -->|"No"| R3{"Pipeline limit reached?"}
R3 -->|"Yes"| Z["Pipeline interrupt: last resort"]
Why nest at all
- Better messages. The innermost timeout that fires tells you exactly which operation was slow.
- Defense in depth. If the inner limit is wrong or missing, the outer ones still protect you.
- Budget control. Stage limits add up to the pipeline limit, keeping the overall run predictable.
Rules for sane nesting
- An inner timeout should be shorter than its outer neighbor. An inner limit longer than the outer one can never fire.
- Leave room in the outer limit for the work between inner blocks, not only for the inner blocks themselves.
- Do not nest more than three levels. Beyond that, nobody can reason about which limit matters.
Timers run independently and at the same time. They do not add up unless you make them add up. A pipeline of five stages, each with a thirty-minute limit, may still be cut off by a pipeline limit of one hour, even though every stage was within its own budget.
12Timeout and Retry Together
Two wrappers that are often combined, where the order changes the meaning.
The retry step repeats its body a chosen number of times if it fails. Pairing it with a timeout is common for flaky operations, such as downloading from a slow server. But the two can be arranged in two different ways, and the arrangement decides what the deadline applies to.
flowchart TD
subgraph A["Design A: timeout outside retry"]
A1["Timeout 10 minutes total"] --> A2["Retry up to 3 times"]
A2 --> A3["Body attempts"]
end
subgraph B["Design B: timeout inside retry"]
B1["Retry up to 3 times"] --> B2["Timeout 3 minutes per attempt"]
B2 --> B3["Body attempt"]
end
| Arrangement | What the deadline covers | Best for | Risk |
|---|---|---|---|
| Timeout outside, retry inside | All attempts together | A hard cap on total waiting | One slow attempt can use up the whole budget, leaving no room for retries |
| Retry outside, timeout inside | Each attempt separately | Flaky operations where a single try may hang | Total time can reach attempts times limit |
| Both layered | Each attempt and the total | Critical steps needing tight control | Slightly harder to read |
The layered design
The most robust arrangement uses both: a short timeout inside each attempt, a retry around it, and a longer timeout around everything as a total cap. Each attempt gets, say, three minutes. Up to three attempts are allowed. Nothing may take more than twelve minutes in total.
Adding a pause between attempts
Retrying immediately often hits the same problem again. A short sleep between attempts gives an overloaded service time to recover. If you use a pause, remember to include it in the total budget.
How retry treats an interruption caused by a timeout inside its body can differ between versions of the plugin. Confirm the behavior on your own Jenkins by deliberately making an attempt hang, and check that the retry happens as you expect.
Example: fetching a large file
A pipeline downloads a large test dataset from a busy server. A single attempt normally takes forty seconds. The team allows three minutes per attempt, three attempts, ten seconds of pause between them, and a total cap of eleven minutes. A stuck connection is abandoned after three minutes and retried, and a truly dead server ends the step within eleven.
13Timeouts Around Approvals
The most important use for human waits.
The input step pauses a pipeline until a person clicks Proceed or Abort. By default it waits forever. That is almost never what you want: forgotten builds pile up, and someone may approve stale code weeks later. Wrapping the input in a timeout gives every approval a natural expiry.
How it behaves
- If a person answers in time, the timeout is cancelled and the pipeline continues.
- If nobody answers, the timeout interrupts the wait, and the run ends as aborted.
- In declarative pipelines, a timeout in the stage’s options also covers an input directive on that stage, because options are applied before the prompt appears.
Choosing approval limits
| Situation | Suggested limit | Reason |
|---|---|---|
| Quick confirmation from someone watching | 15 to 60 minutes | They are already at the screen |
| Normal release approval | 2 to 8 hours | Covers meetings and lunch |
| Approval across time zones | 24 hours | Allows for the other side’s working day |
| Weekend or holiday coverage | Avoid long waits; rebuild instead | Code becomes stale quickly |
A pipeline-level timeout also covers approval waits. If your pipeline has an approval that may last eight hours and a pipeline limit of two hours, the run will be cut off while the approver is still reading. Set the pipeline limit above the longest allowed approval, or place the approval in its own stage with its own limit.
Illustration: the approval that survived a holiday
A build reaches its production approval on a Friday afternoon, and nobody answers. Without a timeout, it sits until Tuesday, when an approver returns and clicks Proceed, deploying code that is now four days behind main. With a four-hour timeout, the build aborted on Friday evening, a message told the team, and a fresh build after the weekend deployed current code.
14Timeouts Around Waiting and Polling
Waiting for something outside Jenkins always needs a deadline.
Many pipelines wait for outside events: a service to become healthy after deployment, a scan result from a quality server, a database to accept connections, a file to appear. The waitUntil step exists for this. It repeatedly runs a check until the check reports success, pausing a little longer between tries each time. On its own, waitUntil never gives up. It must be wrapped in a timeout.
flowchart TD
T["Timeout: 5 minutes"] --> W["Wait until check succeeds"]
W --> C["Run the check"]
C --> Q{"Ready?"}
Q -->|"Yes"| DONE["Leave the wait, continue"]
Q -->|"No"| P["Pause, longer each time"]
P --> C
T -.->|"deadline reached"| X["Interrupt and abort"]
Service readiness
After a deployment, poll a health address until it answers. A limit of a few minutes is typical.
Analysis server verdict
The wait for a quality gate from a scanning server should be wrapped in a timeout, so a missing webhook cannot hang the pipeline.
Database availability
Starting a test database takes time. Poll until it accepts connections, with a limit that matches its normal startup.
Third-party jobs
If your pipeline triggers another system and waits for its answer, give that wait its own deadline and a clear message on expiry.
Do not hold an agent while waiting
If the wait happens inside an agent block, the executor is held for the whole waiting time. When the waiting involves only the controller, for example waiting for a webhook from a quality server, place the wait outside the agent so the slot is free for other builds.
A polling loop should also print one short line per attempt, or at least occasionally. This keeps an inactivity timeout happy if you use one, and gives you a trail in the log showing how long the service really took to become ready.
15Timeouts and Waiting for an Agent
The time spent in the queue can quietly count against you.
Before a stage can run on an agent, Jenkins must find a free machine. If all executors are busy, the build waits in a queue. Whether that waiting time counts toward your timeout depends on where the timeout is placed.
| Placement | Does queue time count? | Effect |
|---|---|---|
| Wrapper around steps inside the agent block | No, the timer starts after the agent is acquired | The limit measures only real work |
| Wrapper around the agent request itself | Yes | Limits how long you are willing to wait for a machine |
| Stage-level option in declarative pipeline | Often yes, because stage options are applied before the agent is allocated | A busy queue can eat into the stage budget; check on your version |
| Pipeline-level option | Yes, everything from start to finish | Includes all queueing |
Why this matters
Suppose your stage limit is twenty minutes and the stage normally takes eight. On a busy morning, the build waits twelve minutes for an agent. If the queue wait counts, only eight minutes remain, and the stage may be aborted for something that was not its fault. The symptom is timeouts that appear only at busy times and clear up when the system is quiet.
Two remedies
- Keep timeouts for real work inside the agent block, so queue time does not count, and add a separate, generous limit around the agent request.
- Add more agents or use on-demand agents, so queues stay short. A timeout is not a substitute for capacity.
Illustration: the Monday morning timeouts
A team sees random timeouts every Monday between nine and ten. The tests are unchanged. The cause: dozens of developers push at once, the agent pool is saturated, and stage timeouts are counting queue time. Moving the deadline inside the agent block, and adding a separate ten-minute cap on waiting for an agent, ends the mystery.
16Timeouts in Parallel Branches
Several clocks running at once.
Jenkins can run several branches side by side in a stage, for example unit tests, browser tests and code analysis at the same time. Each branch is its own path of execution, and each can have its own timeout. Timers in different branches run independently, all at the same time.
What happens when one branch times out
- That branch is interrupted and ends aborted.
- By default the other branches continue until they finish, and the stage’s overall result reflects the problem.
- If the stage uses the fail-fast setting, the other branches are stopped as soon as one fails or is aborted, saving time and machines.
flowchart LR
S["Parallel stage"] --> U["Unit tests: 10 minute limit"]
S --> B["Browser tests: 25 minute limit"]
S --> A["Static analysis: 8 minute limit"]
U --> J["Stage finishes when all branches end"]
B --> J
A --> J
B -.->|"timeout"| F["Fail fast option stops the others"]
Choosing limits for branches
Give each branch a limit based on its own history, not one shared number. A single limit chosen for the slowest branch makes the fast ones unprotected, and a single limit chosen for the fastest kills the slow ones wrongly. Also remember that the stage takes as long as the longest branch, so a stage-level limit should be based on that one.
Name each parallel branch clearly. When a timeout fires, the log and the visualization show the branch name, and a clear name such as “browser tests” turns a puzzling message into an immediate diagnosis.
17Telling a Timeout From a Person Pressing Stop
Both end as aborted. Sometimes the difference matters.
When a build ends as aborted, the reason might be a timeout, or it might be a person pressing the stop button, or a newer build cancelling an older one. For alerts and reports, these are different stories. A timeout suggests a hang that needs attention. A person pressing stop is a deliberate act that needs no alert.
flowchart TD
A["Body interrupted"] --> C["Read the cause of the interruption"]
C --> Q{"What caused it?"}
Q -->|"Timer exceeded"| T["Mark as timed out, alert the team"]
Q -->|"User pressed stop"| U["Record who stopped it, no alert"]
Q -->|"Other"| O["Treat as aborted and log the cause"]
T --> R["Run cleanup"]
U --> R
O --> R
How it is done
In a scripted section, you can catch the interruption and look at its cause. Jenkins attaches a description of why the body was stopped: a timeout cause for expired timers, or a user cause naming the person who pressed stop. Your code can then set a custom message, mark the result differently, or send a targeted alert. Because this uses lower-level features, some Jenkins setups require an administrator to approve the script’s use of them.
When it is worth the effort
- When timeouts and manual stops both occur often, and alerts on stops would be noise.
- When a timeout should count as a failure for reporting, for example on the main branch.
- When you want the message to say “timed out after 30 minutes” rather than a generic aborted notice.
Example: two different messages
A team’s pipeline catches interruptions. If the timer caused it, the pipeline marks the run as failed and posts “Test stage exceeded 25 minutes” to the team channel. If a person stopped it, the message is “Build stopped by Ravi” with no alert. The channel now contains only messages that need action.
18The Post Section: Cleaning Up After a Timeout
Stopping the work is half the job. Tidying up is the other half.
When a timeout interrupts a body, whatever the body had started may be left in an in-between state: a test database still running, a temporary environment still costing money, a lock still held, files half written. The post section is the place to put things right, because it runs whatever the result.
The aborted condition
Runs when the result is aborted, which includes timeouts. The natural home for teardown and alerts about the hang.
The always condition
Runs for every result. Good for saving whatever logs and reports exist, even partial ones.
The cleanup condition
Runs after all others, whatever the result. The safest place to delete workspaces.
Stage-level post
A stage’s own post block runs right after that stage, so its helper services are stopped before the next stage starts.
What to clean
- Helper services started for the stage, such as databases or mock servers.
- Temporary environments created in the cloud, which cost money every minute they exist.
- Locks and reservations held on shared resources.
- Half-finished deployments, to be verified and rolled back if needed.
- Workspace files, especially any containing sensitive data.
Assume every timeout leaves a mess, and write the cleanup before you need it. Teams that add cleanup after their first expensive incident always wish they had done it earlier.
Illustration: the forgotten test environment
A pipeline creates a temporary cloud environment for integration tests. A test hangs, the timeout aborts the stage, and the pipeline ends. Nothing tells the cloud to destroy the environment. It keeps running for eleven days before anyone notices the bill. A stage-level aborted block that destroys the environment would have prevented the whole affair.
19Shell Commands and Stubborn Processes
What actually happens to a running program when the timer expires.
Most of the work in a pipeline is done by external programs started through shell steps. When the timeout interrupts such a step, Jenkins asks the program to stop and also tries to stop the other programs that it started. Well-behaved programs respond at once. But a few do not.
| Situation | What may happen | What to do |
|---|---|---|
| Program ignores the stop request | It keeps running after the pipeline has moved on | Make sure the tool handles termination; add explicit kill steps in cleanup |
| Program started background helpers | Helpers survive as orphaned processes | Run them in containers that are removed at the end |
| Program is stuck in a system call | Stopping takes a long time | Use tool-level time limits as a second layer |
| Container left running | Uses memory and ports on the agent | Stop and remove containers in the post section |
A second layer of protection
Many tools have their own time limit options, such as a connection timeout or a maximum test duration. Use them as well as the Jenkins timeout. The tool’s own limit gives a cleaner error message and lets the tool clean up after itself, while the Jenkins timeout remains the safety net if the tool’s limit fails.
Disposable agents help
Running builds in containers or on machines that exist only for one build is the strongest protection against leftovers. Whatever survived the timeout disappears when the container is destroyed.
If you see the same machine getting slower over days, look for orphaned processes left by past timeouts. A simple scheduled check that lists and kills stray processes from old builds can rescue a long-lived agent.
20Older Job Types and the Build-timeout Plugin
How the same idea appears outside pipelines.
Classic freestyle jobs, configured through web forms, cannot use the pipeline step. For them, the Build-timeout plugin offers a setting that aborts builds that run too long. It comes with several strategies, which are also useful mental models for pipelines.
| Strategy | How it decides | Pipeline equivalent |
|---|---|---|
| Absolute | Fixed number of minutes | Timeout with total time |
| No activity | Silence in the log for a set time | Timeout with activity on |
| Elastic | A percentage above the average of recent successful builds | Compute the limit from history in your own code |
| Likely stuck | A multiple of the average duration | Similar to elastic |
| Deadline | A clock time by which the build must end | Compute the remaining time until the deadline |
The elastic idea
The elastic strategy is worth borrowing. Instead of a fixed number that goes stale, the limit follows the recent average and adds a margin, say 150 percent. When the suite grows slowly, the limit grows with it. In pipelines, you can approximate this by reading recent durations and computing the limit before entering the block.
Example: a nightly build with a deadline
A nightly build must finish before six in the morning, when the morning team starts. The deadline style limit computes how much time remains and aborts the build if it cannot finish, saving the machines for the day shift.
When moving a freestyle job to a pipeline, carry its timeout settings over on purpose. Teams often forget, and the new pipeline runs for months with no limit at all.
21Security and Resource Protection
Timeouts are also a safety fence.
Timeouts protect your system from more than accidents. They also limit the damage that misuse can do. Anyone who can run code in your pipeline can, on purpose or by mistake, run something that never ends.
Runaway builds from outsiders
In projects that build pull requests from strangers, a pipeline that mines coins or loops forever can burn through your machines. A strict pipeline-level limit caps the damage.
Cloud bills
Cloud agents are billed by time. A hung build on a large machine costs money every minute. Timeouts cap the bill.
Queue starvation
One stuck build holds one executor. A handful can freeze a small pool. Timeouts keep slots turning over.
Short exposure
A build holding secrets should not hold them forever. A limit on sensitive stages shortens the window in which credentials exist on a machine.
Protect the limits themselves
A deadline that anyone can remove is not a protection. Since timeouts live in the Jenkinsfile, anyone who can edit it can raise or delete them. For untrusted contributions, run the trusted pipeline definition from the target branch, and enforce a maximum through a shared library or a Jenkins-wide setting so that individual projects cannot lift it without review.
For any build that runs code you do not fully trust, set a firm total limit, run it on disposable agents and give it no credentials. The timeout is one layer of that defense, not the whole of it.
22Monitoring, Logging and Metrics
How to know your deadlines are healthy.
Make timestamps visible
The timestamps option adds a time to each line of the log. With it, you can see where the time went before a timeout fired. Without it, you must guess. It costs nothing and helps every investigation.
Metrics worth watching
| Metric | Why it matters | Warning sign |
|---|---|---|
| Number of timeouts per week | Shows how often hangs or bad limits occur | A rising trend |
| Timeouts by stage | Points to the unstable part of the pipeline | One stage causing most of them |
| Duration percentiles per stage | Shows drift toward the limit | 95th percentile above 70 percent of the limit |
| Near misses | Runs that finished within ten percent of the limit | Frequent near misses mean the limit is about to bite |
| Queue wait time | May explain timeouts that count queue time | Timeouts clustering at busy hours |
| Cost of aborted builds | Shows money spent on work that did not complete | Large share of agent time |
Monitoring plugins can expose these numbers to systems such as Prometheus, and dashboards make trends visible. A simple weekly report listing every timeout, its stage and its duration is often enough to turn scattered irritations into a clear list of things to fix.
Illustration: the drift alarm
A team adds an alert when a stage’s 95th percentile duration passes seventy percent of its timeout. Two months later the alert fires for the test stage. They split the slowest tests into a parallel branch before a single build is aborted. The limit never bothers anyone.
23Performance, Capacity and Cost
What deadlines do for queues, machines and money.
The timeout step itself is almost free. It starts one timer and cancels it. The value lies in what it prevents. A hung build occupies an executor, and executors are the scarcest resource in most Jenkins installations. A timeout is a guarantee that every slot returns to the pool within a known time.
Those numbers are only an illustration, but the effect is real. With ten executors and three of them stuck, the team has lost nearly a third of its capacity, queues grow, and every developer waits longer. A timeout of thirty minutes would return those slots within half an hour.
The cost side
On cloud agents billed by the minute, a hung build on a machine that costs a few dollars an hour, left for a weekend, costs real money for nothing. Timeouts cap this. Even better is to combine them with agents that shut down when idle.
| Lever | Effect on capacity and cost |
|---|---|
| Stage-level limits | Bounds the time any stage can hold an executor |
| Pipeline-level limit | Bounds the total time for a run |
| Short limits on waits | Frees slots quickly when outside systems misbehave |
| Limits on approval waits | Stops idle builds from lingering |
| On-demand agents | Pay only for what you use, and stop billing at abort |
| Fail fast in parallel stages | Stops sibling branches early when one fails |
Timeouts that fire very often waste capacity too, because each aborted build is work thrown away. If a stage is aborted daily, fix the cause or adjust the limit, instead of accepting it as normal.
24Useful Design Patterns
Reliable ways of arranging timeouts.
Pattern 1: Pipeline cap, stage budgets, step guards
Set a total limit for the run, realistic budgets for each stage, and tight limits around calls to outside systems. The most specific limit usually fires first and gives the clearest message.
Pattern 2: Outer total, inner silence
Around a long task, use a total-time timeout as a hard ceiling and an inactivity timeout as a hang detector. Together they catch both silent hangs and endless chatter.
Pattern 3: Timeout inside retry, cap outside
Limit each attempt so a hung attempt does not use the whole budget, allow a few retries with pauses, and cap the total. Flaky operations get a fair chance without unlimited waiting.
Pattern 4: Every wait has a deadline
Adopt a team rule that every polling loop, approval prompt and external wait sits inside a timeout. Review for it in every pipeline change.
Pattern 5: Cleanup in the aborted block
Pair each timeout with cleanup that stops helper services, releases locks and destroys temporary environments. The mess is handled the moment the timer fires.
Pattern 6: Limits from history
Compute limits from recent successful durations, using a high percentile plus a margin, and review them every quarter so they do not go stale.
Pattern 7: Shared library defaults
Provide a shared library function that applies the standard timeouts for each kind of stage. Projects call it with a few settings, and a small team keeps the numbers reasonable everywhere.
25Anti-patterns to Avoid
Habits that look fine at first and hurt later.
What people do
They set no timeout anywhere and trust that builds always end.
Why it hurts
A single hang can hold an executor for days, block the queue and cost money.
Better approach
Set at least a pipeline-level limit everywhere, and add finer ones where risk is highest.
What people do
They copy a limit from another project or pick a round number at random.
Why it hurts
Limits that ignore real durations cause false alarms or catch hangs far too late.
Better approach
Measure recent runs, choose a high percentile with a margin, and review regularly.
What people do
They alert only on failures, so timeouts go unnoticed.
Why it hurts
Aborted runs are silent, and hangs continue to recur unseen.
Better approach
React to the aborted condition or to unsuccessful results, and tell the team clearly that a timeout occurred.
What people do
They put a short pipeline-level limit on a pipeline that contains long approvals.
Why it hurts
The whole run is cut off while the approver is still reading.
Better approach
Give approvals their own limit, and set the pipeline limit above the longest allowed approval.
What people do
They use an inactivity timeout on a quiet task that prints nothing for long periods.
Why it hurts
Healthy work is aborted because it was silent.
Better approach
Make the task print progress, or use a total-time limit instead.
What people do
They retry over and over inside a timeout with no pause and no cap.
Why it hurts
Retries hammer a struggling service, hide real problems and may consume the whole budget on the first hung attempt.
Better approach
Limit each attempt, add pauses, cap the total and report every retry.
What people do
They assume a timeout undoes what the aborted work did.
Why it hurts
Half-finished deployments, running environments and held locks stay behind.
Better approach
Write explicit cleanup in the post section for every timeout-prone stage.
26Best Practices and Common Mistakes
A checklist to apply to any Jenkinsfile today.
Do this
- Set a limit at pipeline level as the final safety net.
- Give each stage a realistic budget.
- Wrap every external wait, poll and approval in a timeout.
- Always write the unit explicitly.
- Choose values from measured durations plus a margin.
- Keep inner limits shorter than outer ones.
- Use aborted and cleanup blocks to tidy up and alert.
- Add the timestamps option for easier investigation.
- Review limits every quarter.
Avoid this
- Leaving any wait without a deadline.
- Guessing limits without data.
- Relying on the failure condition alone for alerts.
- Placing short pipeline limits over long approvals.
- Counting queue time against work budgets by accident.
- Inactivity limits on silent tasks.
- Unlimited retries around hanging operations.
- Forgetting cleanup after an interrupted stage.
- Leaving limits unchanged for years.
Mistakes people make when they are new
Forgetting the default unit. A bare number means minutes. Someone reading “time 30” might think seconds. Always write the unit.
Expecting a failure result. An expired timeout gives an aborted result by default. Alerts and merge checks that look only for failure will miss it.
Timing the wrong thing. A timeout wrapped around too much, for example an entire stage, hides which operation was slow. Wrap the risky operation itself.
Ignoring queue time. Timeouts that count waiting for an agent cause mysterious failures on busy days.
Testing only the happy path. Make a step hang on purpose once, to see the message, the result, the cleanup and the alert, before you need them for real.
27Advantages, Disadvantages and Trade-offs
An honest look at what the timeout step does well and where it strains.
Advantages
- Turns open-ended waits into predictable ones.
- Frees executors and caps cloud costs.
- Simple to add, with only three settings.
- Works at step, stage and pipeline level.
- Leaves a clear message in the log.
- Adds no measurable overhead.
Disadvantages
- Result is aborted, which alerts may not cover.
- Does not undo the effects of interrupted work.
- Stubborn processes can survive the interrupt.
- Wrong limits cause false alarms or late catches.
- Queue time can silently count against some placements.
- Telling timeouts from manual stops needs extra code.
Trade-offs to weigh
| Choice | Benefit | Cost |
|---|---|---|
| Tight limit | Hangs caught quickly | False alarms on slow days |
| Generous limit | Few false alarms | Hangs waste more time and money |
| Total-time clock | Simple and predictable | May cut off legitimately long work |
| Inactivity clock | Catches silent hangs early | Needs tasks that print regularly |
| Pipeline-level only | One place to manage | Poor messages, coarse control |
| Many fine limits | Precise messages | More numbers to maintain |
| Retry with timeout per attempt | Resilience to flaky operations | Longer worst-case total time |
There is no universally right answer. The right settings depend on how predictable your work is, how costly your machines are and how much noise your team will tolerate. Choose on purpose and write down why.
28Real-World and Industry Examples
How the ideas look in the kinds of organizations that run Jenkins at scale.
An online retailer with many daily builds
Retail teams with hundreds of builds a day cannot afford slots held by hung jobs. They set stage budgets from historical durations, alert on any timeout, and review a weekly list of the slowest stages.
A bank with approvals
Regulated teams require a named person to approve production releases. Each approval prompt sits inside a timeout of several hours, so stale builds cannot be approved days later, and every expiry is logged for auditors.
A mobile team with device tests
Tests on real phones sometimes hang when a device disconnects. The team uses an inactivity timeout of a few minutes around device tests, a total limit around the whole stage, and a cleanup step that resets the device.
An open-source project
Public projects that build pull requests from strangers use strict total limits and disposable agents, so a malicious or broken contribution cannot tie up shared machines for long.
A cloud-heavy team
Teams that create temporary cloud environments for tests use stage-level timeouts with aborted blocks that destroy the environment, so a hung test never turns into a surprise bill.
A small startup
A team of six adds one pipeline-level limit of forty minutes, one five-minute guard around their health check and a four-hour limit on the production approval. Three lines of settings remove almost all hang-related surprises.
29A Complete Story: A Night of Deadlines
Follow one imaginary pipeline through an evening that goes wrong in a controlled way.
A team owns a booking service. Their pipeline has a total limit of ninety minutes. The Test stage has a thirty-minute budget and starts a temporary database. The Deploy stage has a health check guarded by a three-minute limit and an approval guarded by a four-hour limit.
Start
A push at half past five starts the pipeline. The controller records the total deadline of seven o’clock.
Test stage begins
The stage starts a temporary database and runs the tests. Normally this takes twelve minutes.
A test hangs
A test waits forever for a network reply. After thirty minutes the stage timeout fires. Jenkins interrupts the tests, and the log says the timeout was exceeded.
Cleanup
The stage’s aborted block stops the temporary database and saves the partial test report. The executor is freed at once.
Alert
The pipeline’s post section sees an aborted result caused by a timeout, and sends a message naming the stage, the limit and a link to the log. Nobody had to notice a silent hang.
Diagnosis
The next morning the developer reads the message, sees timestamps showing where the test stopped, and fixes a missing time limit on that network call in the test itself.
A clean run
The corrected build passes the tests, deploys, and the health check succeeds after ninety seconds, well within its three minutes. The approval is answered in twenty minutes, far inside its four hours.
The hang cost the team thirty minutes of one executor, not a weekend of three. Nothing was left running, the alert was clear, and the fix took an hour. A timeout did not prevent the bug, but it made the bug small, visible and cheap.
30Troubleshooting Guide
Symptoms, likely causes and calm fixes.
| Symptom | Likely cause | What to do |
|---|---|---|
| Build hangs for hours | No timeout around a wait | Add limits at pipeline, stage and step level |
| Timeout fired much earlier than expected | Unit left out, so minutes were assumed | Write the unit explicitly and recheck the number |
| Timeouts only at busy hours | Queue time counted against the stage limit | Move the limit inside the agent block; add capacity |
| No alert for a timed-out build | Alerts listen only to failure | Add aborted or unsuccessful handling |
| Approval cut off while reading | Pipeline limit shorter than the approval | Raise the pipeline limit or give approval its own stage |
| Inactivity timeout kills a healthy task | The task prints nothing for long periods | Print progress or switch to a total-time limit |
| Processes still running after abort | Program ignored the stop request or spawned helpers | Use containers, explicit kills and tool-level limits |
| Retry did not happen after timeout | Timeout placed outside retry, using the whole budget | Place the timeout inside the retry and cap the total |
| Cloud resources left behind | No cleanup after interruption | Add aborted and cleanup blocks that destroy resources |
| Same stage keeps timing out | Suite grew past the old limit or a real problem | Check duration trend; fix the cause or adjust the limit |
A calm debugging routine
- Find the timeout message in the log and note which block it names.
- Read the timestamps around it to see where the time was spent.
- Compare with history of the same stage to see whether it drifted or hung.
- Check queue time if the timeouts cluster at busy periods.
- Reproduce on a test branch and change one thing at a time.
31Plain-English Glossary
Every important word in this guide in one place.
| Word | Simple meaning |
|---|---|
| Jenkins | A free automation server that builds, tests and delivers software. |
| Pipeline | A written recipe of the steps Jenkins follows. |
| Jenkinsfile | The text file that holds the pipeline. |
| Stage | A named phase of the pipeline. |
| Step | One single action inside a stage. |
| Timeout step | A wrapper that stops its body if it takes too long. |
| Wrapper | A step that surrounds other steps. |
| Body | The steps inside a wrapper. |
| Executor | A work slot on an agent that runs one job at a time. |
| Agent | A worker machine or container that runs steps. |
| Controller | The main Jenkins server that holds the timers. |
| Interrupt | A request to a running step to stop. |
| Aborted | The gray result used for stops and expired timeouts. |
| Activity timeout | A timeout that measures silence in the log instead of total time. |
| Retry | A wrapper that repeats its body if it fails. |
| Polling | Checking again and again until something is ready. |
| Percentile | The value below which a chosen share of measurements fall. |
| Post section | A block that runs at the end of a stage or pipeline. |
| Fail fast | Stopping sibling parallel branches when one fails. |
32Frequently Asked Questions
Short answers to the questions that come up most often.
33Summary and Key Takeaways
The whole story in a few lines.
The timeout step is a small wrapper with a large effect. It gives any block of a pipeline a deadline, interrupts the block when the deadline passes, and ends the run as aborted so the post section can clean up and alert the team. It works at step, stage and pipeline level, measures either total time or silence, and combines with retries, waits and approvals. Used well, with limits chosen from real durations, placed sensibly, paired with cleanup and clear alerts, it keeps executors turning, costs bounded and hangs visible. Used carelessly, it aborts healthy work, hides behind silent alerts or leaves messes behind.
Key Takeaways
- Every wait needs a deadline. Wrap polls, external calls and approvals in timeouts, and add a pipeline-level limit as the final safety net.
- Layer the limits. Pipeline cap, realistic stage budgets and tight guards around risky steps, with inner limits shorter than outer ones.
- Always write the unit. The default is minutes, and a bare number is easy to misread.
- Timeouts end as aborted. React to the aborted or unsuccessful conditions, or timeouts will pass in silence.
- Choose numbers from data. Use a high percentile plus a margin, review quarterly and watch for drift toward the limit.
- Clean up after the interruption. A timeout stops work but does not undo it, so stop services, release locks and destroy temporary environments in the post section.
- Mind the corners. Watch queue time, silent tasks under inactivity clocks, retry ordering and stubborn processes, and test the timeout path once on purpose.