Hi everyone! ![]()
I’m Preetham, a Third-year Computer Science undergraduate currently exploring Jenkins with the goal of becoming an active contributor and eventually applying for Google Summer of Code (GSoC) 2027.
This week, I wasn’t trying to learn Jenkins architecture for the sake of learning it—I actually got pushed into it while investigating Issue #26862, where the jenkins-cli.jar build command with the -s flag was aborting long-running builds after a Jenkins LTS upgrade.
At first, I jumped straight into the source code. Like many beginners, I started following classes, searching for methods, and trying to understand the execution flow. But after a while, I realized I was reading code without understanding how all the pieces fit together.
I couldn’t confidently answer questions like:
-
Where does a request first enter Jenkins?
-
Which component decides what Java method should be executed?
-
Where are builds actually scheduled?
-
When is an Executor assigned?
-
Which part of Jenkins is responsible for the build lifecycle?
-
How do plugins interact with the core?
So instead of continuing to guess, I paused my debugging session and spent time understanding the architecture first.
Honestly, it completely changed the way I look at the Jenkins codebase.
I thought I’d share my notes here in case they’re useful to someone else who’s just starting their Jenkins or GSoC journey.
High-Level Architecture
After reading the documentation, exploring the source code, and tracing request flows, this is the mental model that helped everything click.
Browser / CLI
│
▼
HTTP Request / CLI Command
│
▼
Stapler (Request Routing Layer)
│
▼
Jenkins Core
┌──────────────┼──────────────┐
▼ ▼ ▼
Job Management Security Extension Points
│
▼
Plugins (Optional)
│
▼
Build Queue
│
▼
Controller / Agent Node
│
▼
Executors
│
▼
Build Workspace
│
▼
Console Output • Artifacts • Build Status
Once I started thinking about Jenkins in these layers instead of as one huge application, reading the source became much easier.
1. Everything Starts with a Request
Whether we:
-
click Build Now
-
configure a job
-
install a plugin
-
trigger a pipeline
-
execute a CLI command
everything begins as a request sent to Jenkins.
That request needs to be routed somewhere inside the application.
This is where I found one of the most interesting parts of Jenkins.
2. Stapler – The Part I Never Knew Existed
Before reading the Jenkins source code, I expected to find something similar to Spring MVC controllers.
Instead, Jenkins uses Stapler, a web framework that maps incoming HTTP requests directly to Java objects and methods.
For example, when a user triggers a build:
Browser
↓
/job/MyJob/build
↓
Stapler
↓
Job.doBuild()
↓
Jenkins Core
While browsing the source code, I kept seeing methods such as:
doBuild()
doDelete()
doConfigSubmit()
doCheckName()
Initially, these method names looked random.
After understanding Stapler, I realized they are part of Jenkins’ request routing mechanism.
That single realization made navigating the codebase significantly easier because I finally understood why so many public methods begin with do.
3. Jenkins Core – The Brain of Jenkins
Once Stapler routes the request, it reaches Jenkins Core.
Jenkins Core is responsible for managing the overall system.
It handles responsibilities such as:
-
Job management
-
Scheduling builds
-
User authentication
-
Security
-
Build history
-
Node management
-
Queue management
-
Extension points used by plugins
Rather than performing every task itself, Jenkins Core coordinates the entire execution flow.
Thinking of Jenkins Core as the “orchestrator” helped me understand its role much better.
4. Plugins – How Jenkins Stays Flexible
One thing that genuinely surprised me was how much functionality comes from plugins.
Before exploring Jenkins, I assumed features like Git integration or Pipelines were built directly into Jenkins itself.
Instead, Jenkins Core provides extension points, and plugins add functionality on top of those extension points.
Some familiar examples include:
-
Git Plugin
-
GitHub Plugin
-
Pipeline Plugin
-
Docker Plugin
-
Kubernetes Plugin
-
Maven Plugin
This architecture explains why Jenkins is so flexible.
It also means that while debugging an issue, one important question is:
“Is this behaviour coming from Jenkins Core, or from a plugin?”
That distinction can save a lot of time.
5. The Build Queue
Another concept that became much clearer is the Build Queue.
Imagine ten developers trigger builds at the same time.
Jenkins doesn’t necessarily execute all of them immediately.
Instead, new builds enter the Build Queue and wait until computing resources become available.
Build A
Build B
Build C
↓
Build Queue
↓
Waiting for Executor
This prevents Jenkins from trying to execute more builds than the available resources can handle.
6. Executors – The Workers That Run Builds
An Executor is essentially a worker responsible for running a build.
For example:
Node
Executor 1
Executor 2
If a node has two executors, only two builds can run simultaneously on that node.
Any additional builds remain in the queue until an executor becomes available.
This helped me understand why builds sometimes wait even though they were successfully triggered.
7. Controller and Agents
Jenkins also supports distributed execution.
Instead of running every build on the controller, work can be delegated to multiple agents.
Controller
/ | \
/ | \
Agent 1 Agent 2 Agent 3
The Controller is mainly responsible for:
-
Scheduling
-
Configuration
-
Security
-
Queue management
Agents are responsible for:
-
Running builds
-
Executing tests
-
Compiling code
-
Producing artifacts
This separation allows Jenkins to scale efficiently across multiple machines.
8. Build Workspace
When an executor starts a build, Jenkins creates (or reuses) a workspace.
This workspace contains everything required during execution:
-
Source code
-
Dependencies
-
Temporary files
-
Compiled binaries
-
Test reports
-
Generated artifacts
A typical workspace looks something like:
workspace/
project/
src/
pom.xml
target/
Understanding workspaces also helped me understand where build outputs are actually generated.
9. End-to-End Request Flow
Putting everything together, this is the flow that now exists in my head whenever I read Jenkins code.
User Action
↓
HTTP Request / CLI Command
↓
Stapler identifies the target object
↓
Corresponding Java method executes
↓
Jenkins Core processes the request
↓
Plugins extend the behaviour (when applicable)
↓
Build enters Queue (if required)
↓
Executor starts the build
↓
Workspace is prepared
↓
Build executes
↓
Console output and build results are recorded
↓
Jenkins updates the UI and any configured notifications
This simple mental model made the source code feel much less intimidating.
How This Helped Me
When I returned to investigating Issue #26862, I wasn’t randomly jumping between classes anymore.
Instead, I could ask much better questions:
-
Where does the CLI request enter Jenkins?
-
Which class handles the command?
-
At what point is the build scheduled?
-
How is the client connection maintained while the build is running?
-
Where could the connection be getting interrupted?
I haven’t solved every part of the issue yet, but understanding the architecture gave me a much better framework for investigating it.
Final Thoughts
I’m still very early in my Jenkins journey, so these aren’t “expert notes.” They’re simply the observations that helped me move from feeling lost in the codebase to feeling much more comfortable navigating it.
If you’re also beginning your Jenkins or GSoC journey, I’d highly recommend spending some time understanding the architecture before diving into issues. Even a basic understanding of request routing, Jenkins Core, the plugin model, the build queue, executors, and controller/agent communication makes the source code much easier to follow.
If these notes are useful, I’d be happy to continue sharing what I learn as I explore more of Jenkins internals and contribute to the project.
Thanks for reading, and I’d love to hear from contributors with more experience—if there are other internals you think every beginner should understand, I’m always eager to learn!