← Back to Blog

SAP Job Monitoring: Diagnosing the Hung Jobs That Never Throw an Error

SAP long-running job monitoring for Basis teams: how to tell slow, blocked and abandoned jobs apart in SM37, SM50, SM12 and SM13 before choosing recovery.

SAP long-running job monitoring fails when it treats every long job as the same event. A failed job produces a cancelled status, a log entry, an alert and an owner. A hung job produces none of those: it sits in SM37 as Active while its duration counter climbs, and nothing in the standard toolset decides that it has stopped doing useful work. The diagnosis has to separate 3 states that a runtime alert collapses into one, namely a job that is genuinely slow, a job that is blocked on a resource, and a job that has been abandoned by its work process, because the correct recovery action differs in each.

Together they give SAP Basis and operations teams a repeatable sequence, from SM37 through SM50, SM66, SM12, SM13 and ST22, for reaching the right decision before the backlog does the deciding for them.

Why a Hung SAP Job Is Harder to Catch Than a Failed One

A hung background job survives because nothing in the ABAP stack is designed to terminate it. Dialog work processes have a runtime ceiling: historically rdisp/max_wprun_time applied only to dialog processes, and background work processes were exempt. In SAP S/4HANA 2020 and later, that parameter has been removed from the kernel in favour of priority-based dialog time-outs, and the exemption for background work remains. A batch step can wait on a lock, a remote partner or an update record for days without tripping a single system-side guard.

The second reason is that SM37 displays the job status exactly as it is stored in the database. If the work process that owned the job terminated without a controlled clean-up, the status row is never rewritten. The job is Active in table TBTCO and absent from every process overview at the same time. Any long-running job monitoring that reads SM37 or TBTCO sees a running job. There is no running job.

The third reason is organisational rather than technical. A cancelled job has a log line that names a cause, so the ticket routes itself. A hung job has a log that ends mid-step, so the ticket routes to whoever is awake. Most of the time lost on hung SAP jobs is spent deciding who should look and what they should look at first.

The 3 States Monitoring Collapses Into One

A runtime threshold treats slow, blocked and abandoned jobs as the same event, and that is the root of most wrong recovery decisions. The 3 states look identical in SM37. They separate cleanly in SM50 and SM66.

FIGURE 1 · DIAGNOSISSM37JobZFI_GL_DELTA_LOADStatusActiveDuration04:12:33 and risingJob loglast line 03:58 agoGenuinely slowRunningWhat SM50 / SM66 showsCPU time increases on refreshTable / Action column changesJob log advances between stepsCorrect actionLeave it running. Analyse with STAD and ST05after completion.BlockedHold · Reason: ENQ / RFC / UPDWhat SM50 / SM66 showsNo CPU consumedSame table, no progressJob log staticCorrect actionRelease the blocker at the resource. Cancelonly if it cannot be released.AbandonedNo work processWhat SM50 / SM66 showsNo BTC process for the PIDStatus row never rewrittenDuration counter still climbingCorrect actionSM37 Job → Check Status, then restart fromthe failed step.SM37 status is read from the database; SM50 and SM66 show the live work process.

Figure 1. One SM37 row, 3 different states, 3 different recovery actions.

State What SM37 shows What SM50 or SM66 shows Correct action
Genuinely slow Active, duration rising, job log updating between steps Work process in Running status, CPU time increasing, Table or Action column changing on refresh Leave it running. Investigate volume and SQL with STAD and ST05 after completion.
Blocked Active, duration rising, job log static Work process in Hold or Stopped status with a Reason value (ENQ, RFC, CPIC, UPD, PRIV) Identify and release the blocker. Cancel only if the blocker cannot be released.
Abandoned Active, duration rising, no log update for the full period No work process on the instance named in the job details, or a work process in Ended status Run SM37 Job → Check Status, then restart from the failed step.

The blocked state is the one that costs the most, because it is the one most often misdiagnosed as slow. A blocked job consumes no CPU and touches no table. Its duration counter is the only thing moving.

The First 5 Minutes: Confirming the Job Is Still Attached to a Work Process

The first diagnostic question is not why the job is slow but whether the job still exists as a process. Everything downstream depends on that answer, and it takes 4 steps to get it.

FIGURE 2 · THE FIRST 5 MINUTES1SM37Job detailsTarget server, work processnumber, PID, timestamp of the lastjob log line.2SM37Job → Check StatusCompares the stored status withthe real process state.3SM50On the named instanceStatus, Reason, CPU, Time, Report,Table columns.4SM66Global overview, BTC filterIsolated wait, or shared acrossinstances?What the result decidesStep 2 flips status to CancelledThe job was abandoned. Stop diagnosing, correct the status, restart from the failed step.Step 3 shows Running, CPU advancingThe job is slow, not hung. This is a performance question, not a recovery.Step 3 shows Hold or Stopped with a ReasonThe job is blocked. The Reason value chooses the next transaction.Confirm the job still exists as a process before asking why it is slow.

Figure 2. The first 5 minutes: SM37 to SM50 to SM66, and what each result decides.

Step Transaction What to read What it tells you
1 SM37 Job details: target server, work process number, PID, and the timestamp of the last job log line Which instance to open and how long the log has been silent
2 SM37, Job → Check Status Status after the check runs If the status flips to Cancelled, the job was abandoned. The check corrects a stale Active or Ready status against the real process state (SAP Learning).
3 SM50 on the named instance The BTC work process matching the PID: Status, Reason, CPU, Time, Report, Table columns Whether the process is Running, on Hold, Stopped or Ended, and what it is waiting on
4 SM66 Global process overview filtered to BTC type Whether the wait is isolated to this job or shared across instances, which points to a system-wide blocker

If Step 2 changes the status, stop diagnosing and move to recovery. If Step 3 shows a Running process with CPU time advancing, the job is slow, not hung, and the investigation becomes a performance question. If Step 3 shows Hold or Stopped with a populated Reason column, the job is blocked, and the Reason value chooses the next transaction. The Check Status function is documented in SAP Learning’s background processing lesson.

Reading the Reason Column: What the Job Is Waiting On

The Reason column in SM50 is the single most useful field in the diagnosis of a hung SAP job, because it names the resource the job is waiting for. SAP documents the typical hold reasons as debugging, CPIC activity, locks, updates, GUI response and PRIV memory mode. Each maps to a different diagnostic branch.

FIGURE 3 · READING THE REASON COLUMNREASONWHAT THE JOB IS WAITING ONWHERE TO LOOK NEXTRECOVERY DECISIONENQAn SAP lock held by another process or sessionSM12 lock owner and age · SM04 / AL08 sessionalive?Release only if the owner is dead. Never delete alock held by a running process.RFC / CPICSynchronous call to a partner that has notrepliedSM59 test · SMGW gateway · SM58, SMQ1, SMQ2queuesRestore the partner or gateway. Cancel andrestart only if the outage outlasts the window.UPDUpdate task completion after COMMIT WORKAND WAITSM13 records in Init / Error · SM14 update serveractive?Reactivate updates or clear the record. The jobresumes on its own.PRIVPrivate memory mode after exhaustingextended memoryST02 extended memory and heap limitLet it finish if progress is visible. Otherwise canceland reduce volume per step.Blank · RunningNothing external. The job is executing.Table and Action columns across 3 to 4refreshes · STAD, ST05No recovery. Performance analysis.The Reason column in SM50 names the resource the job is waiting for. Each value opens a different branch.

Figure 3. The SM50 Reason column mapped to the next transaction and the recovery decision.

Reason in SM50 What the job is waiting on Where to look next Recovery decision
ENQ An SAP lock held by another process or session SM12: find the lock owner, user, and lock age. SM04 or AL08 to confirm whether the owning session is still alive. Release the lock only if the owner is a dead session. Never delete a lock held by a running process.
RFC (SM50) or CPIC (SM66) A synchronous call to a partner system that has not replied SM59 connection test to the destination. SMGW for the gateway connection. SM58 for tRFC errors, SMQ1 and SMQ2 for qRFC queues. Restore the partner or the gateway. If the partner is permanently down, cancel and restart after connectivity returns.
UPD Update task completion after COMMIT WORK AND WAIT SM13 for update records in Init or Error status. SM14 to confirm the update server is active. Reactivate updates or clear the erroring record. The job resumes on its own once V1 completes.
PRIV Private memory mode after exhausting extended memory ST02 for extended memory usage and the heap limit. The job is holding the process exclusively. Let it finish if progress is visible. Otherwise cancel and reduce the data volume per step before restart.
Blank, status Running Nothing external. The job is executing. Watch the Table and Action columns across 3 or 4 refreshes. STAD after completion, ST05 during. No recovery. Performance analysis.

Work process exhaustion

Work process exhaustion presents in 2 different places depending on which pool ran out. If every BTC work process on the instance is occupied, a released job never becomes Active at all. It sits in Ready, and the job scheduler has nowhere to place it. The tell is RZ04 or SM50 showing all BTC processes busy while SM37 shows a queue of Ready jobs whose start time has long passed.

The subtler case is a job that is Active but whose parallel child tasks have nowhere to run. A step that fans out work through asynchronous RFC calls needs free dialog work processes in the target RFC server group, and if that group is saturated the parent step waits on children that never start. SM50 shows the parent on Hold with reason RFC even though the partner is the same system. RZ12 shows the server group resource limits that are starving it.

Table locks and enqueue waits

Two different lock layers produce an identical symptom from the job’s point of view, and confusing them wastes the first hour. An SAP enqueue lock lives in the enqueue server and appears in SM12 with an owner and a timestamp. A database lock lives in the database and appears in DBACOCKPIT or the database’s own monitoring, with no entry in SM12 at all. A job on Hold with reason ENQ is waiting on the first kind. A job in Running status that makes no progress and shows the same table name across every refresh is usually waiting on the second.

The recovery rule is the same for both: identify the holder before touching the lock. A lock whose owner is a dead GUI session or a cancelled job can be released. A lock whose owner is another active batch step must be left alone, and the recovery decision becomes a sequencing question about which job should have run first.

RFC connections waiting on a partner that will never answer

A synchronous RFC has no notion of a dead partner until the underlying CPIC layer gives up. SAP’s own guidance on work processes stuck in On Hold with reason RFC, or Stopped with reason CPIC, treats the condition as a hang requiring gateway and destination analysis rather than a normal wait. The diagnostic sequence is SM59 to test the destination, SMGW to confirm the gateway still holds the connection, and SM21 on both systems for the timestamp at which the partner went quiet.

The delta here is not only the job’s own lost time. Any tRFC or qRFC traffic behind the same destination is queuing in SM58, SMQ1 and SMQ2 while the partner is unreachable, and it will all release at once when connectivity returns.

Update task backlogs

An update backlog freezes every job that waits on its own updates, not only the one under investigation. When the update server is deactivated, whether by an administrator after a database fill-up or by a V1 error that triggered automatic deactivation, records accumulate in SM13 in Init status. Any batch step that issued COMMIT WORK AND WAIT holds until its record is processed. SM14 shows whether updates are active, and SM13 shows how deep the queue has grown and which records are in Error. Reactivating the update server, or repairing the erroring record, releases the whole set without any job-level intervention.

The Cost of Every Hour: The Delta That Grows While the Job Does Not Finish

A hung job is not a static problem, because the environment around it keeps moving while it does not. Each hour of hang adds to a delta that the recovery has to absorb, and the size of that delta often matters more to the recovery decision than the cause of the hang.

FIGURE 4 · THE COST OF EVERY HOURIllustrative growth curves, not measured data.Hang starts+1 h+2 h+4 h+8 hDownstream chainReleased / Ready jobs with after-job or after-event starts · SM37Unconsumed deltaChange pointers, delta queues, IDoc status 64in WE02Locks the hung job holdsSM12 entries owned by the job user and PIDDumps elsewhereChild aRFC or partner system, same user andwindow · ST22

Figure 4. What accumulates behind a hung job, hour by hour (illustrative).

What accumulates Where it shows Recovery consequence
Downstream jobs in the chain waiting on this job’s event or completion SM37 Released or Ready jobs with start conditions after job or after event Every dependent job runs late and compressed into the same window once released, competing for the same work processes.
Delta records the job was meant to consume Change pointers, delta queues, IDoc status 64 in WE02, extraction queues The restart processes hours or days of volume in a single run, which is itself a performance risk.
Locks the hung job is holding SM12 entries owned by the job’s user and PID Other jobs and dialog users block behind the hung job, producing a second wave of hangs with a different visible cause.
Dumps in child tasks or partner systems ST22 for the same user and time window, on both systems A child aRFC that dumped with a memory error does not cancel its parent. The parent waits for a reply that will never come, and ST22 is the only place the real cause is written down.

ST22 deserves a specific check in every hung-job diagnosis even when the job itself has no dump. The runtime error that explains the hang is frequently in a different process, on a different instance, or in the partner system.

Choosing the Recovery Action: Wait, Release the Blocker, or Cancel and Restart

The recovery decision follows from the state, not from the duration, and there are only 3 decisions available. A slow job is left alone. A blocked job is unblocked at the resource, not at the job. An abandoned job is status-corrected and restarted from the step that did not complete.

FIGURE 5 · CHOOSING THE RECOVERY ACTIONWaitGenuinely slowBefore acting, confirmCPU time and table access still advancingacross successive SM50 refreshes.After acting, verifyJob log reaches the next step within theprojected interval.Extend the downstream window if the chainallows it.Release the blockerBlocked on ENQ · RFC · UPDBefore acting, confirmLock owner liveness in SM12 and SM04. SM59test and partner SM21. The SM13 Error recordcause.After acting, verifySM50 reason clears, queues drain in SM58 /SMQ1 / SMQ2 or SM13, job log resumes.Cancelling a blocked job removes the symptomand preserves the cause.Cancel and restartAbandonedBefore acting, confirmWhether the failed step is restartable withoutduplicating what it already posted.After acting, verifyThe restarted step completes anddownstream events fire.SM37 Check Status first, then restart from thefailed step only.The recovery decision follows from the state, not from the duration. There are only 3 decisions.

Figure 5. The 3 recovery decisions and the checks before and after each.

Diagnosed state Action Before acting, confirm After acting, verify
Genuinely slow Wait. Extend the downstream window if the chain allows it. CPU time and table access are still advancing across successive SM50 refreshes. Job log reaches the next step within the projected interval.
Blocked on ENQ or database lock Release the lock if the owner is dead, or wait for the owning step to finish. Lock owner identity and liveness in SM12 and SM04. SM50 reason clears and the job log resumes.
Blocked on RFC or CPIC Restore the partner or gateway. Cancel the job only if the partner outage will outlast the window. SM59 test result and SM21 on the partner system. SM58, SMQ1 and SMQ2 drain, then the job log resumes.
Blocked on UPD Reactivate updates in SM14 or repair the erroring record in SM13. The Error record’s cause, so the same failure does not recur immediately. SM13 queue drains and the job completes without restart.
Abandoned SM37 Check Status, then restart from the failed step. Whether the failed step is restartable without duplicating what it already posted. Check what was committed before the process died. The restarted step completes and downstream events fire.

Cancelling a blocked job is the most common wrong action, because it removes the symptom and preserves the cause. The lock holder, the dead partner or the deactivated update server is still there, and the restarted job blocks again on the same resource within minutes.

Why Runtime Thresholds Fail at SAP Long-Running Job Monitoring

A runtime threshold detects duration and nothing else, which is why it generates the alert and then leaves the recovery decision exactly as hard as it was. The alert tells the operator that the job has exceeded a limit. It does not say whether the work process is running, on hold or gone, what the Reason column reads, who holds the lock, or how much delta has accumulated behind the job. The operator still has to run the sequence above from the start, and the threshold is usually tuned so loosely to avoid month-end false positives that the hang has been under way for hours before it fires.

FIGURE 6 · WHY RUNTIME THRESHOLDS FAILIllustrative values.Runtime threshold alertALERT ZFI_GL_DELTA_LOADRuntime 04:12:33 exceeds threshold 04:00:00What it does not say?Is the work process running, on hold, or gone??What does the Reason column read??Who holds the lock? Is the partner up??How much delta has built behind the job??Is the duration counter on a dead job?Tuned loosely to survive month-end. Fires hours late.Context carried into recoveryStateBlockedWait reasonENQBlocking resourceLock on BKPF, owner WP 14, dialog session ended 03:51DownstreamZFI_GL_POST_02 and 6 chained jobs waiting on eventDelta2 h 41 m of change pointers unconsumedDecisionRelease lock. Restart not required.

Figure 6. A duration alert versus the context the recovery step needs (illustrative).

The abandoned state defeats threshold alerting entirely. The duration counter in SM37 keeps advancing on a job that has no process, so the alert reports a long-running job when the truth is a dead one. Recovery for that state is a status correction and a restart, and a duration alert points in the wrong direction.

What the recovery step needs is the context the diagnosis produces: the state, the wait reason, the blocking resource and the downstream dependencies, carried into the decision rather than reconstructed by hand after the alert. Automating SM37 job monitoring only helps if that context travels with the alert. Symphony is one example of a layer built to carry it into the recovery step, so that the choice to wait, release or restart is taken with the job’s wait state and its downstream chain in view rather than its clock alone. Its SAP job orchestration capabilities and failed job recovery approach describe how that context reaches the operator, or the automated recovery path, before the delta grows.

From Silent Job to Decided Action

A hung SAP job never announces itself, so the diagnosis has to be a habit rather than a reaction. Confirm the process exists. Read the Reason column. Follow it to SM12, SM59, SM13 or ST22. Size the delta. Then choose between waiting, releasing the blocker, and restarting from the failed step, with the state deciding the action rather than the duration. Teams that run this sequence consistently recover hung jobs before the downstream chain notices, and teams that rely on runtime thresholds recover them after it does.

If you want to see how that context-carrying recovery step behaves against your own job chains, see how it works in your environment.

Frequently Asked Questions

What is SAP long-running job monitoring?

SAP long-running job monitoring is the practice of detecting background jobs that exceed their expected runtime and determining whether each one is slow, blocked or abandoned before acting. It combines SM37 job status with SM50 and SM66 work process state, because runtime alone cannot distinguish a job that is working from one that has stopped.

How do you diagnose a hung SAP background job?

Start in SM37 with the job details and Job → Check Status to confirm the job still has a process. Then open SM50 on the named instance and read the Reason column. ENQ points to SM12, RFC or CPIC to SM59 and SMGW, UPD to SM13 and SM14, and a Running status with advancing CPU means the job is slow rather than hung.

Why does a job show Active in SM37 but does not appear in SM50?

SM37 displays the status stored in the database, not the live process state. If the work process terminated without a controlled clean-up, the status row is never corrected. Running Job → Check Status in SM37 compares the stored status with the real process and sets it to Cancelled if the job was abandoned.

Does rdisp/max_wprun_time stop long-running SAP background jobs?

No. The parameter applied only to dialog work processes, and background work processes have never had a system-side runtime limit. In SAP S/4HANA 2020 and later the parameter has been removed in favour of priority-based dialog time-outs, and background jobs remain exempt. A hung batch job will run until something releases it or an operator cancels it.

Should I cancel a hung SAP job or wait for it?

The answer depends on the diagnosed state, not the duration. A slow job with advancing CPU should be left to finish. A blocked job should be unblocked at the resource, because cancelling it leaves the lock, the dead partner or the deactivated update server in place and the restart blocks again. An abandoned job should be status-corrected in SM37 and restarted from the failed step.

Ready to see Symphony in action?

Request a personalized demo to learn how Symphony's AI agents can transform your enterprise operations.