IBM i System Operations with CL in 2026: Subsystem Management, Job Control, Data Queues, Output Queues, and Job Scheduling

The previous post covered advanced DB2 for i SQL — the query optimiser, Index Advisor, and Materialized Query Tables. This post covers the operational CL commands that IBM i administrators and operators use every day: managing subsystems and jobs, controlling output and spooled files, working with data queues, and scheduling jobs.

These commands are the operational layer of IBM i. Understanding them is the difference between being able to respond to a production incident and being dependent on someone else who knows what WRKACTJOB does. CL programming (writing compiled CL programs) was covered in Post 20. This post is about interactive operational commands — the ones you type at a 5250 command line or call from automation scripts.

Subsystem management

Subsystems are the job environments on IBM i. Every running job belongs to a subsystem. Subsystems control which job queues feed them, which memory pools they use, and what routing entries determine the program a submitted job runs.

Common subsystems on a production IBM i:

  • QINTER — interactive workstation sessions
  • QBATCH — batch jobs submitted with SBMJOB (default)
  • QSYSWRK — system jobs (TCP/IP, database monitors, etc.)
  • QSERVER — server jobs (ODBC, JDBC, FTP, DDM)
  • QUSRWRK — user-defined server jobs
  • Custom subsystems — shops with high batch volume create dedicated subsystems with private memory pools

Key subsystem commands:

WRKSBS                    /* Work with Active Subsystems — interactive overview */
STRSBS SBSD(QBATCH)       /* Start a subsystem */
ENDSBS SBS(QBATCH) OPTION(*IMMED)   /* End immediately — use carefully in production */
ENDSBS SBS(QBATCH) OPTION(*CNTRLD) DELAY(300)  /* Controlled end — wait up to 300s for jobs to finish */
DSPSBS SBS(QBATCH)        /* Display subsystem description */

Working with subsystem descriptions (SBSD):

/* Display job queue entries for a subsystem */
DSPSBSD SBSD(QBATCH) OUTPUT(*PRINT)

/* Add a job queue entry to a subsystem */
ADDJOBQE SBSD(MYBATCH) JOBQ(MYBATCH/HIGHPRIQ) SEQNBR(10) MAXACT(5)

/* Change the memory pool for a subsystem */
CHGSBSD SBSD(MYBATCH) POOLS((1 *BASE) (2 *USERPOOL1))

Job management

Viewing and working with active jobs:

WRKACTJOB SBS(QBATCH)           /* Show only batch jobs */
WRKACTJOB SBS(*ALL) JOB(NGTBATCH)  /* Find a specific job by name */
WRKUSRJOB USER(BATCHUSR)        /* All jobs running under a user profile */
WRKJOB JOB(123456/BATCHUSR/NGTBATCH)  /* Work with a specific job by full job ID */

Changing a running job’s attributes:

/* Raise job priority (1=highest, 9=lowest) */
CHGJOB JOB(123456/BATCHUSR/NGTBATCH) JOBPTY(3)

/* Increase job's logging level for debugging */
CHGJOB JOB(123456/BATCHUSR/NGTBATCH) LOG(4 00 *SECLVL)

/* Change time slice (CPU quantum, in milliseconds) */
CHGJOB JOB(123456/BATCHUSR/NGTBATCH) TIMESLICE(3000)

/* Move a job to a different output queue */
CHGJOB JOB(123456/BATCHUSR/NGTBATCH) OUTQ(ORDLIB/BATCHOUT)

Holding, releasing, and ending jobs:

/* Hold a job (pause without ending) */
HLDJOB JOB(123456/BATCHUSR/NGTBATCH) SPLFILE(*YES)

/* Release a held job */
RLSJOB JOB(123456/BATCHUSR/NGTBATCH)

/* End a job — controlled (wait for current operation to complete) */
ENDJOB JOB(123456/BATCHUSR/NGTBATCH) OPTION(*CNTRLD) DELAY(60)

/* End a job — immediate (use only when controlled fails or process is hung) */
ENDJOB JOB(123456/BATCHUSR/NGTBATCH) OPTION(*IMMED)

Working with job queues:

WRKJOBQ JOBQ(QBATCH)     /* Show jobs waiting in a specific queue */
HLDJOBQ JOBQ(QBATCH)     /* Hold queue — prevent new jobs from starting */
RLSJOBQ JOBQ(QBATCH)     /* Release queue */
CLRJOBQ JOBQ(QBATCH)     /* Clear all held/released jobs from queue — irreversible */

Viewing job logs for completed jobs:

/* Display job log for a specific completed job */
DSPJOBLOG JOB(123456/BATCHUSR/NGTBATCH)

/* Or via SQL — find jobs that ended with an error today */
SELECT JOB_NAME, JOB_STATUS, JOB_END_REASON,
       JOB_DATE, JOB_ENTERED_SYSTEM_TIME, JOB_END_TIME
FROM   QSYS2.JOB_INFO
WHERE  JOB_STATUS      = '*OUTQ'
  AND  JOB_END_REASON   'JOB COMPLETED NORMALLY'
  AND  JOB_DATE        = CURRENT_DATE
ORDER  BY JOB_END_TIME DESC;

Message queue management

Every IBM i user profile, job, and many system objects have a message queue. The operator message queue (QSYSOPR) receives important system messages.

DSPMSG MSGQ(QSYSOPR)     /* Display operator message queue */
DSPMSG MSGQ(*WRKSTN)     /* Display current workstation message queue */

/* Send a message to the operator queue */
SNDMSG MSG('Nightly batch completed successfully') TOUSR(*SYSOPR)

/* Send a message to a specific user */
SNDMSG MSG('Your report is ready in output queue BATCHOUT') TOUSR(JSMITH)

/* Clear old messages from a queue */
CLRMSGQ MSGQ(QSYSOPR)

Replying to a message waiting for operator response:

/* In DSPMSG, press 2 next to the inquiry message, then type the reply */
/* Or from command line: */
SNDRPY MSGKEY(xxxxxxxx) MSGQ(QSYSOPR) RPY('I')  /* I = Ignore, C = Cancel, R = Retry */

Monitoring message queues with MONMSG in batch:

A CL program can be dedicated to monitoring a message queue and taking action on specific messages — a pattern used for automated operations (restart failed jobs, send alerts, trigger downstream processes):

PGM
TOP:
    RCVMSG MSGQ(QSYSOPR) MSGID(&MSGID) MSG(&MSGDTA) WAIT(30)
    MONMSG MSGID(CPF0000) /* Timeout or error — loop back */

    SELECT
    WHEN (&MSGID *EQ 'CPF1241') DO  /* Job ended abnormally */
        CALL ALERTPRG PARM(&MSGDTA)
    ENDDO
    WHEN (&MSGID *EQ 'CPC2191') DO  /* Job completed normally */
        CALL LOGCOMPLETE PARM(&MSGDTA)
    ENDDO
    ENDSELECT

    GOTO CMDLBL(TOP)
ENDPGM

Output queues and spooled files

Spooled files are the IBM i equivalent of print jobs. Programs write output to spooled files in output queues. Managing spooled files is a routine operational task.

WRKSPLF SELECT(*ALL)                    /* All spooled files system-wide */
WRKSPLF SELECT(*CURRENT)               /* Current user's spooled files */
WRKSPLF SELECT(*ALL) OUTQ(ORDLIB/BATCHOUT)  /* Files in a specific output queue */

/* Delete old spooled files (7 days or older) */
DLTSPLF FILE(*SELECT) SPLNBR(*SELECT)  /* Interactive selection */

/* Or via SQL */
SELECT JOB_NAME, SPOOLED_FILE_NAME, PAGES, CREATE_TIMESTAMP
FROM   QSYS2.OUTPUT_QUEUE_ENTRIES
WHERE  OUTPUT_QUEUE_LIBRARY = 'ORDLIB'
  AND  OUTPUT_QUEUE_NAME    = 'BATCHOUT'
ORDER  BY CREATE_TIMESTAMP;

Moving or copying spooled files:

/* Move a spooled file to a different output queue */
CHGSPLFA FILE(QPRINT) JOB(123456/BATCHUSR/NGTBATCH) SPLNBR(1) +
          OUTQ(ORDLIB/ARCHIVEQ)

/* Copy a spooled file to an IFS stream file (PDF, text) */
CPYSPLF FILE(QPRINT) TOFILE(*TOSTMF) +
         TOSTMF('/home/reports/nightly-batch.txt') +
         STMFOPT(*REPLACE)

Data queues for inter-job communication

Data queues (*DTAQ) are IBM i objects designed for passing data between jobs — a producer-consumer pattern built into the OS. They are faster than database tables for this purpose because they use kernel-level locking and signalling.

Creating a data queue:

/* FIFO data queue, each entry up to 256 bytes */
CRTDTAQ DTAQ(ORDLIB/ORDNOTIFY) MAXLEN(256) SEQ(*FIFO) TEXT('Order processing notification queue')

/* Keyed data queue — entries retrieved by key rather than position */
CRTDTAQ DTAQ(ORDLIB/STATUSQ) MAXLEN(512) SEQ(*KEYED) KEYLEN(10) TEXT('Status keyed queue')

Sending and receiving from CL:

/* Send a data queue entry (producer) */
SNDDT DTAQ(ORDLIB/ORDNOTIFY) DTALEN(10) DATA('ORD00143  ')

/* Receive from a data queue (consumer) — waits up to 60 seconds */
RCVDTAQ DTAQ(ORDLIB/ORDNOTIFY) DTALEN(256) DATA(&DATA) WAIT(60)

/* Non-blocking receive — returns immediately if queue is empty */
RCVDTAQ DTAQ(ORDLIB/ORDNOTIFY) DTALEN(256) DATA(&DATA) WAIT(0)

Data queues from SQL (IBM i 7.3+):

-- Send to a data queue from SQL
CALL QSYS2.SEND_DATA_QUEUE(
    DATA_QUEUE_LIBRARY => 'ORDLIB',
    DATA_QUEUE_NAME    => 'ORDNOTIFY',
    MESSAGE_DATA       => 'ORD00143  '
);

-- Receive from a data queue from SQL
SELECT MESSAGE_DATA, MESSAGE_LENGTH
FROM   TABLE(QSYS2.RECEIVE_DATA_QUEUE(
             DATA_QUEUE_LIBRARY => 'ORDLIB',
             DATA_QUEUE_NAME    => 'ORDNOTIFY',
             WAIT_TIME          => 0));

Job scheduling with ADDJOBSCDE

IBM i has a built-in job scheduler. ADDJOBSCDE (Add Job Schedule Entry) schedules a command to run at a specific time or on a recurring schedule without external scheduling tools.

/* Run nightly batch every day at 22:00 */
ADDJOBSCDE JOB(NGTBATCH) CMD(SBMJOB CMD(CALL PGM(ORDLIB/NIGHTBATCH)) +
                              JOB(NGTBATCH) JOBD(BATCHJOBD) JOBQ(BATCHQ)) +
            FRQ(*WEEKLY) SCDDAY(*ALL) SCDTIME(220000) +
            USER(BATCHUSR) TEXT('Nightly order processing batch')

/* Run month-end close on the last day of each month */
ADDJOBSCDE JOB(MONTHEND) CMD(SBMJOB CMD(CALL PGM(ORDLIB/MTHEND)) +
                              JOB(MONTHEND) JOBD(BATCHJOBD)) +
            FRQ(*MONTHLY) SCDDATE(*MONTHEND) SCDTIME(010000) +
            USER(BATCHUSR) TEXT('Month-end close processing')

/* View all scheduled entries */
WRKJOBSCDE

/* Hold a scheduled entry (prevent it running while keeping the schedule) */
HLDJOBSCDE JOB(NGTBATCH)

/* Release */
RLSJOBSCDE JOB(NGTBATCH)

Checking job schedule via SQL:

SELECT JOB_SCHEDULE_ENTRY, SCHEDULE_DATE, SCHEDULE_TIME,
       NEXT_SUBMISSION_DATE, NEXT_SUBMISSION_TIME, STATUS
FROM   QSYS2.SCHEDULED_JOB_INFO
ORDER  BY NEXT_SUBMISSION_DATE, NEXT_SUBMISSION_TIME;

System request and attention key handling

In a 5250 session, pressing System Request (Sys Req) opens the System Request menu, which allows you to:

  • Transfer to another job or session
  • End a runaway interactive job
  • Send a message from an interactive session

ATTN key handling is controlled by the ATNPGM parameter on the user profile and can be customised to provide application-specific attention handling.

Practical operational command reference

NeedCommand
See all active jobsWRKACTJOB SBS(*ALL)
Find a job by nameWRKACTJOB SBS(*ALL) JOB(name)
Check job log of active jobWRKACTJOB → F10 on the job
End a hung jobENDJOB JOB(…) OPTION(*IMMED)
Check operator messagesDSPMSG MSGQ(QSYSOPR)
See jobs waiting in a queueWRKJOBQ JOBQ(QBATCH)
Clear a stuck print queueWRKSPLF → option 4 to delete
Check system resource statusWRKSYSSTS
Check disk spaceWRKSYSSTS → check %USED column
Restart a subsystemENDSBS SBS(name) OPTION(*CNTRLD) then STRSBS

These commands are the hands-on operational vocabulary of IBM i. An administrator who can work confidently through WRKACTJOB, DSPMSG, WRKSPLF, and WRKJOBSCDE can diagnose and resolve the majority of production issues without escalating. Adding data queue patterns and scheduled job entries to that knowledge covers the automation layer that keeps scheduled batch processing running reliably.

Next post: IBM i IFS advanced — journalling stream files, sharing the IFS as a Windows network drive with NetServer, backing up IFS data, handling large files, and CCSID and encoding in the Integrated File System.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top