The life of a job inside JES2
JES2 receives every batch job, checks and converts its JCL, queues it until an initiator picks it up, collects everything it prints on the spool, and finally removes it. Knowing which phase a job is in tells you who or what it is waiting for.
What JES2 is for
JES2 is the job entry subsystem used by most z/OS sites (a smaller number run JES3 or its successor JES3plus from Phoenix Software). It sits between the people and programs that submit work and the z/OS components that run it. JES2 owns the queues, the spool and the job's output; z/OS owns the running address space.
Phase by phase
| Phase | What happens | Where it can stop |
|---|---|---|
| Input | JES2 reads the JCL from TSO SUBMIT, the internal reader, a scheduler or another system, gives the job a number such as JOB04521, and stores the JCL and any instream data on the spool | Rarely; a JOB statement JES2 cannot accept is rejected here |
| Conversion | The converter merges PROCs and INCLUDE members, resolves symbols, and turns JCL into internal text | JCL errors: a missing PROC or bad syntax ends the job here with a JCL ERROR and no steps run |
| Execution queue | The converted job waits for an initiator that serves its class | Held job, held class, no free initiator, or a job of the same name already running |
| Execution | An initiator allocates datasets and runs each step | Waiting for datasets another job holds, or running long |
| Output | JES2 builds output groups from the job's SYSOUT | Output in a held class waits here until someone releases or purges it |
| Hard-copy | Output is printed, sent to another node, or picked up by an output product | No printer or writer started for that class |
| Purge | JES2 frees the job's spool space and its job number | Retention rules at some sites keep output for days |
Job classes and initiators
The CLASS= on the JOB statement puts the job into a job class. An initiator is a long-running address space that takes one job at a time from the classes it is set to serve, runs it, and then takes the next. If initiators for class A are busy, class A jobs wait even when the machine is idle.
| JES2-managed initiators | WLM-managed initiators | |
|---|---|---|
| Who starts them | Operators or automation, with $S | WLM, based on goals and queue delay |
| How many | A fixed number defined by the site | WLM adds or removes them |
| Set by | The job class's MODE=JES | The job class's MODE=WLM |
Which classes exist, what they mean (short, long, overnight, high memory) and how many initiators serve each is site configuration. A common pattern is a few classes for production batch, separate classes for test, and limits so that large jobs cannot starve everything else.
Why a job does not start
- Held: the job was submitted with TYPRUN=HOLD, held by an operator, or its class is held.
- No initiator: every initiator for that class is busy or drained.
- Duplicate job name: by default JES2 does not run two jobs with the same name at once, so the second one waits. This is controlled by the job class and site settings.
- Scheduling environment or affinity: the job asks for resources only some systems have.
- Dataset contention: the job has started but is waiting in allocation for an ENQ on a dataset.
10.14.02 JOB04521 ---- WEDNESDAY, 07 OCT 2026 ---- 10.14.02 JOB04521 IRR010I USERID VSAHA1 IS ASSIGNED TO THIS JOB. 10.14.05 JOB04521 $HASP373 PAYRUN01 STARTED - INIT 3 - CLASS A - SYS SYSA 10.16.41 JOB04521 $HASP395 PAYRUN01 ENDED - RC=0000
The gap between the submit time and $HASP373 is time spent queued. The gap between $HASP373 and $HASP395 is execution. Separating the two is the first step in answering 'why was my job slow?'
Sysplex and multi-access spool
In a sysplex, several z/OS systems usually share one JES2 spool and checkpoint as a multi-access spool (MAS). A job can be submitted on one system and run on another, and you can see its output from any member. That is why a job may run on SYSB even though you submitted it on SYSA.
Which JES2 message number in JESMSGLG shows that the job has started execution?
Show a hint
It comes just before the job ended message, $HASP395.
Show the solution
$HASP373 marks the start of execution, and shows the initiator and class.
Common mistakes
A job waiting for execution may simply be held or short of initiators. Check its status and class in SDSF before resubmitting, or you may end up with two copies.
A job that failed conversion or allocation never ran a program. Read JESMSGLG and JESYSMSG for the JCL error instead.
Classes are tied to resource limits and agreements with other teams. Moving production work into another class needs approval from operations.
What you will see at work
- 'My job has not run' is one of the most common support questions, and the answer is almost always found in the job's JES2 status.
- Schedulers submit jobs to JES2 through the internal reader; JES2 then decides when an initiator runs them.
- Capacity reviews look at queue time separately from run time to decide whether more initiators are needed.
Key terms
Check your understanding.
Take this lesson's quiz and save your progress. Free.