CICS COMMAREA: Complete Guide to Inter-Program Communication and State Management

Introduction: The COMMAREA as CICS's State-Passing Mechanism
Every software application needs to maintain state between operations. In a web application, state lives in session objects, cookies, or tokens. In a batch COBOL program, state lives in working storage that persists for the program's entire run. In a CICS pseudo-conversational program, neither of those options is available — the task ends after every user interaction. The mechanism CICS provides to preserve state is the COMMAREA.
The COMMAREA (Communication Area) serves two distinct purposes in CICS: it is the channel through which data is passed between programs using EXEC CICS LINK and EXEC CICS XCTL, and it is the state repository that persists data from one pseudo-conversational task invocation to the next via EXEC CICS RETURN. Understanding how to design, size, and safely access the COMMAREA is a core skill for every CICS COBOL developer.
COMMAREA in the LINKAGE SECTION
In COBOL, the COMMAREA is declared as item 01 DFHCOMMAREA in the LINKAGE SECTION. This is a standard CICS convention — the name must be exactly DFHCOMMAREA for the CICS translator to recognise it.
IDENTIFICATION DIVISION.
PROGRAM-ID. EMPINQ.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-COMMAREA.
05 WS-CA-EMP-KEY PIC X(6).
05 WS-CA-SCREEN-ID PIC X(4).
05 WS-CA-FUNC-CODE PIC X(1).
88 WS-CA-BROWSE VALUE 'B'.
88 WS-CA-DISPLAY VALUE 'D'.
88 WS-CA-UPDATE VALUE 'U'.
05 WS-CA-MSG-AREA PIC X(60).
LINKAGE SECTION.
01 DFHCOMMAREA.
05 LK-CA-EMP-KEY PIC X(6).
05 LK-CA-SCREEN-ID PIC X(4).
05 LK-CA-FUNC-CODE PIC X(1).
05 LK-CA-MSG-AREA PIC X(60).The LINKAGE SECTION definition of DFHCOMMAREA must exactly match the structure that the calling program is sending. If the structures do not match in layout, data will be misread — a common source of subtle bugs in CICS programs that communicate with multiple other programs.
The Critical First Step: Testing EIBCALEN
Before accessing DFHCOMMAREA, always test EIBCALEN (the length field in the Execute Interface Block). EIBCALEN tells you how many bytes were passed in the COMMAREA for this invocation:
PROCEDURE DIVISION.
*── Safe COMMAREA access pattern ─────────────────────────────────
EVALUATE TRUE
WHEN EIBCALEN = ZERO
*> First entry: no COMMAREA passed, initialise
INITIALIZE WS-COMMAREA
PERFORM FIRST-TIME-SETUP
WHEN EIBCALEN < LENGTH OF DFHCOMMAREA
*> COMMAREA smaller than expected — version mismatch?
MOVE DFHCOMMAREA TO WS-COMMAREA(1:EIBCALEN)
PERFORM HANDLE-VERSION-MISMATCH
WHEN OTHER
*> Normal re-entry: copy COMMAREA to working storage
MOVE DFHCOMMAREA TO WS-COMMAREA
PERFORM PROCESS-USER-INPUT
END-EVALUATE.The rule: never access DFHCOMMAREA fields directly when EIBCALEN is zero. And never work directly from LINKAGE SECTION fields in production code — always copy DFHCOMMAREA to a WORKING-STORAGE mirror (like WS-COMMAREA above) before manipulating the data. LINKAGE SECTION storage is owned by CICS; working directly in it is unsafe.
Pseudo-Conversational State Preservation with RETURN COMMAREA
The most important use of the COMMAREA in CICS is preserving transaction state between pseudo-conversational task invocations. After each user interaction, the program issues EXEC CICS RETURN with both TRANSID and COMMAREA options:
*── After processing, save state and return control to CICS ─────
MOVE WS-COMMAREA TO DFHCOMMAREA
EXEC CICS RETURN
TRANSID(EIBTRNID)
COMMAREA(WS-COMMAREA)
LENGTH(LENGTH OF WS-COMMAREA)
RESP(WS-RESP)
END-EXEC.When the user presses an AID key (Enter, PF3, etc.), CICS starts a new task with the same TRANSID and passes the saved COMMAREA to the new task invocation. EIBCALEN will equal the length you specified on the previous RETURN, and DFHCOMMAREA will contain the data you saved.
This is the complete pseudo-conversational COMMAREA lifecycle:
Task 1: EIBCALEN=0 → initialise WS-COMMAREA → send initial map
→ EXEC CICS RETURN TRANSID('EMPI') COMMAREA(WS-COMMAREA)
↓ CICS saves COMMAREA
User presses Enter ────────────────────────────────────↓
Task 2: EIBCALEN=71 → MOVE DFHCOMMAREA TO WS-COMMAREA → process input
→ EXEC CICS RETURN TRANSID('EMPI') COMMAREA(WS-COMMAREA)
↓ CICS saves updated COMMAREA
User presses PF3 ──────────────────────────────────────↓
Task 3: EIBCALEN=71 → MOVE DFHCOMMAREA TO WS-COMMAREA → EXEC CICS RETURN (no COMMAREA)Designing a Good COMMAREA Structure
A well-designed COMMAREA is compact, version-aware, and clearly named. Here is a production-quality COMMAREA design:
*── WS-COMMAREA: State for the EMPLOYEE INQUIRY transaction ─────
01 WS-COMMAREA.
*> Version control
05 WS-CA-VERSION PIC 9(2) VALUE 01.
*> Navigation state
05 WS-CA-CURRENT-MAP PIC X(8) VALUE 'EMPLIST '.
05 WS-CA-FUNC-CODE PIC X(1) VALUE SPACES.
88 WS-CA-LIST VALUE 'L'.
88 WS-CA-DETAIL VALUE 'D'.
88 WS-CA-UPDATE VALUE 'U'.
88 WS-CA-DELETE VALUE 'X'.
*> Current record key
05 WS-CA-EMP-KEY PIC X(6) VALUE SPACES.
*> Browse state
05 WS-CA-BROWSE-KEY PIC X(6) VALUE SPACES.
05 WS-CA-BROWSE-DIR PIC X(1) VALUE 'F'.
88 WS-CA-FORWARD VALUE 'F'.
88 WS-CA-BACKWARD VALUE 'B'.
*> User message to display on next send
05 WS-CA-MSG PIC X(60) VALUE SPACES.
*> Padding to fixed length
05 FILLER PIC X(2) VALUE SPACES.Best practices for COMMAREA design:
Keep it small. The COMMAREA is stored in the CICS DSA (Dynamic Storage Area) for the duration of the transaction. Large COMMAREs increase storage pressure. If you need more than a few hundred bytes, store the bulk data in a Temporary Storage queue and keep only the TS queue name in the COMMAREA.
Include a version number. When two programs share a COMMAREA and one is updated to change the structure, a version byte lets the receiver detect the mismatch gracefully.
Use fixed-length layouts. The COMMAREA is a contiguous block of bytes. Variable-length layouts cause misalignment bugs. Every program that reads or writes the COMMAREA must use the same COPYLIB definition.
Put a shared COMMAREA definition in a COPYLIB. When multiple programs share a COMMAREA structure, define it in a single copybook and COPY it into each program. This eliminates the risk of definition drift.
*── Shared copybook: EMPICOMM ───────────────────────────────────
01 WS-COMMAREA.
05 WS-CA-VERSION PIC 9(2).
05 WS-CA-EMP-KEY PIC X(6).
05 WS-CA-FUNC-CODE PIC X(1).
05 WS-CA-MSG PIC X(60).
05 FILLER PIC X(2).
*── Total: 71 bytes ─────────────────────────────────────────────COMMAREA in EXEC CICS LINK (Calling a Subprogram)
EXEC CICS LINK invokes another CICS program synchronously — control returns to the calling program when the called program finishes. Data is passed via the COMMAREA option:
*── Calling program (EMPINQ) ─────────────────────────────────────
01 WS-LINK-COMMAREA.
05 WS-LINK-EMP-KEY PIC X(6).
05 WS-LINK-EMP-NAME PIC X(30).
05 WS-LINK-EMP-SAL PIC S9(7)V99 COMP-3.
05 WS-LINK-RESP-CODE PIC X(1).
PROCEDURE DIVISION.
MOVE WS-EMP-KEY TO WS-LINK-EMP-KEY
INITIALIZE WS-LINK-EMP-NAME WS-LINK-EMP-SAL
EXEC CICS LINK PROGRAM('EMPGET')
COMMAREA(WS-LINK-COMMAREA)
LENGTH(LENGTH OF WS-LINK-COMMAREA)
RESP(WS-RESP)
END-EXEC
IF WS-RESP NOT = DFHRESP(NORMAL)
PERFORM HANDLE-LINK-ERROR
END-IF
*> Called program has populated the COMMAREA
MOVE WS-LINK-EMP-NAME TO EMPNAMEO
MOVE WS-LINK-EMP-SAL TO EMPSALO.*── Called program (EMPGET) ─────────────────────────────────────
LINKAGE SECTION.
01 DFHCOMMAREA.
05 LK-EMP-KEY PIC X(6).
05 LK-EMP-NAME PIC X(30).
05 LK-EMP-SAL PIC S9(7)V99 COMP-3.
05 LK-RESP-CODE PIC X(1).
PROCEDURE DIVISION.
EXEC CICS READ FILE('EMPFILE')
RIDFLD(LK-EMP-KEY)
INTO(WS-EMP-REC)
RESP(WS-RESP)
END-EXEC
EVALUATE WS-RESP
WHEN DFHRESP(NORMAL)
MOVE WS-EMP-NAME TO LK-EMP-NAME
MOVE WS-EMP-SAL TO LK-EMP-SAL
MOVE 'N' TO LK-RESP-CODE
WHEN DFHRESP(NOTFND)
MOVE 'E' TO LK-RESP-CODE
WHEN OTHER
MOVE 'F' TO LK-RESP-CODE
END-EVALUATE
EXEC CICS RETURN END-EXEC.The COMMAREA is two-way: the calling program passes data IN, and the called program writes results back to the same COMMAREA before returning. After EXEC CICS LINK completes, the calling program reads the updated COMMAREA.
COMMAREA in EXEC CICS XCTL (Transfer Control)
EXEC CICS XCTL transfers control to another program without returning. The original program is terminated. The COMMAREA is passed one-way:
*── Transfer to EMPMENU without returning ────────────────────────
EXEC CICS XCTL PROGRAM('EMPMENU')
COMMAREA(WS-MENU-COMMAREA)
LENGTH(LENGTH OF WS-MENU-COMMAREA)
RESP(WS-RESP)
END-EXEC.
*> Code below here is never reached after XCTLUse XCTL when implementing a menu-driven application where pressing PF3 should switch to the main menu program and release the resources of the current program.
When the COMMAREA Is Not Enough: Temporary Storage Alternative
If your transaction state requires more than 32 KB, or if you need to share state between multiple different transactions (not just between invocations of the same transaction), use a Temporary Storage queue:
*── Build a unique queue name using tran-id + term-id ───────────
MOVE SPACES TO WS-TS-QUEUE
STRING EIBTRNID DELIMITED SIZE
EIBTRMID DELIMITED SIZE
INTO WS-TS-QUEUE
*── Save large state to TS queue ─────────────────────────────────
EXEC CICS WRITEQ TS
QUEUE(WS-TS-QUEUE)
FROM(WS-LARGE-STATE)
LENGTH(LENGTH OF WS-LARGE-STATE)
REWRITE *> overwrite item 1
ITEM(WS-TS-ITEM-NUM)
RESP(WS-RESP)
END-EXEC
*── Store only the queue name in the COMMAREA ────────────────────
MOVE WS-TS-QUEUE TO WS-CA-TS-QUEUE-NAME
EXEC CICS RETURN TRANSID(EIBTRNID)
COMMAREA(WS-COMMAREA)
LENGTH(LENGTH OF WS-COMMAREA)
END-EXEC.Key Takeaways
The COMMAREA is the cornerstone of CICS inter-program communication and pseudo-conversational state management. In pseudo-conversational design, passing a well-structured COMMAREA on every EXEC CICS RETURN is what makes stateless task invocations appear stateful to the user. For program-to-program calls, LINK uses the COMMAREA as a two-way parameter block while XCTL uses it one-way. Always test EIBCALEN before accessing DFHCOMMAREA, always copy DFHCOMMAREA to WORKING-STORAGE before using it, and always define shared COMMAREA structures in a COPYLIB to prevent layout drift.
To see how the COMMAREA fits into the full pseudo-conversational design pattern, continue with CICS Pseudo-Conversational Design. For the complete course, visit the CICS Mastery Course.
