Jenkins Master-Worker Architecture: Scaling Your Builds Across Multiple Nodes
As you get more comfortable with Jenkins and your team grows, one server handling all your builds starts to show its limits. Builds slow down, the server gets overloaded, and eventually things start failing or timing out. The solution is the Jenkins master-worker architecture (also called master-agent architecture). This post explains why it exists, how it works, and exactly how to set it up.

Why One Server Is Not Enough
Imagine you have a Jenkins server with 1 GB of RAM and two build executors. That means Jenkins can run at most two builds at the same time.
Now your team has twenty developers, all pushing code throughout the day. Every push triggers a build. You could easily have ten or fifteen build requests queued up at any moment. Those builds will run sequentially, one after another, and each developer waits longer and longer for feedback on their code.
If you try to increase the number of executors on the single server, you are competing for the same limited RAM and CPU. More builds running in parallel on underpowered hardware means all of them run slowly, and the server risks crashing entirely under the load.
Master-worker architecture is the answer. Instead of running everything on one machine, you offload the actual build execution to separate, dedicated build servers (called worker nodes or worker nodes), while the Jenkins master server focuses on coordination.
How Master-worker Works
Here is the mental model:
The Jenkins master is where the Jenkins UI lives, where you configure jobs, and where builds are triggered. It is the brain.
The worker nodes (also called worker nodes or agents) are where the actual build commands run. They are the muscles.
A few important things to understand:
You only install Jenkins on the master server. worker nodes do not run Jenkins.
On each worker node, you install the tools the builds need: Java, Maven, and Git.
When you click Build Now (or a trigger fires), the master assigns the job to a worker. The build runs on the worker. The workspace is created on the worker.
Results and logs are reported back to the master, which displays them in the dashboard.
The master handles:
Job configuration and scheduling
Plugin management
Build history and reporting
Credential storage
The workers handle:
Actual compilation and testing
Artifact generation
Deployment steps
Setting Up the worker Nodes
For this demonstration, we will launch two Amazon Linux 2 EC2 instances: node-1 and node-2. These will become our worker nodes.
Step 1: Set the Hostnames
On node-1:
sudo hostnamectl set-hostname node-1
sudo -i
On node-2:
sudo hostnamectl set-hostname node-2
sudo -i
Step 2: Install Java, Maven, and Git on Both Nodes
The worker nodes need the tools the builds actually use. They do not need Jenkins itself.
yum install java-21-amazon-corretto maven git -y
Run this on both node-1 and node-2.
Configuring SSH-Based Authentication from Master to workers
Jenkins master connects to worker nodes over SSH. For this to work without password prompts, you need to set up SSH key-based authentication from the master to each worker.
Step 1: Generate SSH Keys on the Jenkins Master
On the Jenkins master server:
ssh-keygen
Accept all defaults. This creates two files in ~/.ssh/:
id_rsa- the private key (kept on the master, never shared)id_rsa.pub- the public key (copied to the workers)
Step 2: Start the SSH Agent and Add the Key
eval $(ssh-agent -s)
ssh-add ~/.ssh/id_rsa
This loads the private key into the SSH agent so that SSH connections from this session use it automatically.
Step 3: Copy the Public Key to the worker Nodes
ssh-copy-id -i ~/.ssh/id_rsa.pub ec2-user@<node-1-private-ip>
ssh-copy-id -i ~/.ssh/id_rsa.pub ec2-user@<node-2-private-ip>
This appends the master's public key to the authorized_keys file on each worker, allowing the master to log in without a password.
Step 4: Test the Passwordless Connection
ssh ec2-user@<node-1-private-ip>
If it connects without asking for a password, the setup is correct.
Adding worker Nodes to Jenkins
Now that the SSH connection works at the OS level, we need to register the worker nodes inside Jenkins.
Step 1: Install the SSH Agent Plugin
Before adding nodes, make sure the SSH Build Agents plugin (or Publish Over SSH plugin if you are using it for file transfers) is installed:
Go to Manage Jenkins.
Click Plugins.
Click Available plugins.
Search for
SSH Build Agents.Select it and click Install.
Check Restart Jenkins when installation is complete.
Step 2: Navigate to Node Management
Go to Manage Jenkins.
Click Nodes (or Manage Nodes and Clouds).
You will see the Built-In Node (the master). This is where all builds run by default.
Click New Node.
Step 3: Configure Node-1
Fill in the following:
Node name:
node-1Type: Permanent Agent
Click Create.
On the next screen:
| Field | Value |
|---|---|
| Number of executors | 3 (how many parallel builds this node can handle) |
| Remote root directory | /tmp (where Jenkins creates workspaces on this node) |
| Labels | node-1 (used to target this specific node in pipelines) |
| Usage | Use this node as much as possible (or "Only build jobs with label expressions matching this node") |
| Launch method | Launch agents via SSH |
| Host | Private IP address of node-1 |
Step 4: Add SSH Credentials
Under the Credentials field, click Add then Jenkins.
In the credentials dialog:
Kind: SSH Username with private key
ID:
node-1-creds(or any descriptive name)Username:
ec2-userPrivate Key: Select Enter directly and paste the contents of
~/.ssh/id_rsafrom the master server.
cat ~/.ssh/id_rsa
Copy the entire output (including the -----BEGIN and -----END lines) and paste it into the private key field.
Click Add, then select the newly created credential from the dropdown.
Step 5: Handle the Host Key Verification
Under Host Key Verification Strategy, select Non verifying Verification Strategy.
This skips the interactive "Are you sure you want to connect?" fingerprint verification that would block an automated connection.
Click Save.
Step 6: Repeat for Node-2
Follow the same steps for node-2 with its corresponding private IP address and label node-2.
Verifying the Nodes Are Online
After saving, Jenkins attempts to connect to the worker nodes. Go to Manage Jenkins, click Nodes, and you should see node-1 and node-2 listed alongside the built-in node.
If a node shows "offline," check:
Security groups: is port 22 open between the master and the worker?
The private IP address entered in the node configuration
That the SSH key was copied correctly
Give it a minute... Jenkins sometimes takes 30-60 seconds to establish the connection and mark the node as online.
Running a Build on a Specific worker Node
Once your nodes are online, you can target them in a pipeline using the label directive in the agent block.
Previously, your pipelines used agent any, which means "run on whichever node is available." Now you can be specific:
pipeline {
agent { label 'node-1' }
stages {
stage('Checkout') {
steps {
git 'https://github.com/your-username/java-app.git'
}
}
stage('Compile') {
steps {
sh 'mvn compile'
}
}
stage('Test') {
steps {
sh 'mvn test'
}
}
stage('Package') {
steps {
sh 'mvn clean package'
}
}
}
}
The agent { label 'node-1' } line tells Jenkins: run this entire pipeline on the node with the label node-1. The build will not run on the master or on node-2.
The job configuration, triggers, and pipeline script all live on the master. But when the pipeline executes, Jenkins SSH's into node-1 and runs the commands there. The workspace is created at /tmp/<job-name> on node-1.
Stage-Level Agent Assignment
You can also assign different stages to different nodes:
pipeline {
agent none
stages {
stage('Build') {
agent { label 'node-1' }
steps {
sh 'mvn clean package'
}
}
stage('Deploy') {
agent { label 'node-2' }
steps {
echo 'Deploying from node-2'
}
}
}
}
This lets you build on a node with more RAM and deploy from a node that is closer to the deployment environment. Setting agent none at the pipeline level requires each stage to declare its own agent.
Understanding the Number of Executors
Each node has a configurable number of executors. Think of an executor as a "slot" for a build to run in.
If node-1 has three executors, it can run three builds in parallel simultaneously. If all three slots are full and a fourth build is triggered, it waits in the queue until a slot opens.
To change the executor count on a node:
Go to Manage Jenkins.
Click Nodes.
Click the node name.
Click Configure.
Change Number of executors.
For production environments, set this based on the node's available CPU and RAM. A rough starting point is one executor per CPU core.
Summary
Jenkins master-worker architecture solves the scaling problem by distributing build execution across multiple worker nodes.
Key points:
The master coordinates, the workers execute.
Only Jenkins is installed on the master. workers only need Java, Maven, and Git.
SSH key-based authentication enables passwordless connections from master to workers.
Nodes are registered in Jenkins under Manage Jenkins, Nodes.
Each node gets a label that pipeline scripts use to target specific nodes.
agent anyruns on any available node.agent { label 'node-1' }runs specifically on the labeled node.Each node has a configurable number of executors controlling how many parallel builds it can handle.
With your build farm in place, your Jenkins setup can handle real-world build volumes. The next post covers deploying WAR files to a Tomcat server completing the "build and deploy" half of the CI/CD pipeline.






