# Backlogged Processes

LLMS index: [llms.txt](/llms.txt)

---

<div id="pslens-context-panel" class="card border-info mb-4 d-none">
  <div class="card-header bg-light text-info py-2 fw-bold d-flex align-items-center border-bottom border-info-subtle">
    <i class="bi bi-info-circle-fill me-2"></i>
    <span>Tailored Operational Context</span>
  </div>
  <div class="card-body p-0">
    <ul class="list-group list-group-flush">
      <li id="row-db" class="list-group-item d-flex align-items-center justify-content-between py-2 d-none">
        <strong>Target Database:</strong>
        <span id="ctx-db" class="badge bg-secondary font-monospace">&mdash;</span>
      </li>
      <li id="row-type" class="list-group-item d-flex align-items-center justify-content-between py-2 d-none">
        <strong>Context Type:</strong>
        <span id="ctx-type" class="badge bg-light text-dark border font-monospace text-uppercase">&mdash;</span>
      </li>
      <li id="row-severity" class="list-group-item d-flex align-items-center justify-content-between py-2 d-none">
        <strong>Alert Severity:</strong>
        <span id="ctx-severity" class="badge">&mdash;</span>
      </li>
      <li id="row-time" class="list-group-item d-flex align-items-center justify-content-between py-2 d-none">
        <strong>Triggered Time:</strong>
        <span id="ctx-time" class="text-muted small">&mdash;</span>
      </li>
      <li id="row-details" class="list-group-item py-2 d-none">
        <strong id="label-details" class="d-block mb-1">Firing Context:</strong>
        <code id="ctx-details" class="d-block p-2 bg-light border rounded small" style="white-space: pre-wrap; word-break: break-all;">&mdash;</code>
      </li>
    </ul>
  </div>
</div>

<script>
  (function() {
    const params = new URLSearchParams(window.location.search);
    const metadata = params.get('metadata');
    if (!metadata) return;

    try {
      
      const base64 = metadata.replace(/-/g, '+').replace(/_/g, '/');
      const jsonStr = decodeURIComponent(escape(window.atob(base64)));
      const data = JSON.parse(jsonStr);

      if (data) {
        let hasData = false;

        if (data.db) {
          document.getElementById('ctx-db').textContent = data.db;
          document.getElementById('row-db').classList.remove('d-none');
          hasData = true;
        }

        if (data.type) {
          document.getElementById('ctx-type').textContent = data.type;
          document.getElementById('row-type').classList.remove('d-none');
          hasData = true;
        }

        if (data.severity) {
          const severityBadge = document.getElementById('ctx-severity');
          const severity = data.severity.toLowerCase();
          severityBadge.textContent = severity.toUpperCase();
          if (severity === 'critical') {
            severityBadge.className = 'badge bg-danger';
          } else if (severity === 'warning') {
            severityBadge.className = 'badge bg-warning text-dark';
          } else {
            severityBadge.className = 'badge bg-info';
          }
          document.getElementById('row-severity').classList.remove('d-none');
          hasData = true;
        }

        if (data.t) {
          const date = new Date(data.t * 1000);
          document.getElementById('ctx-time').textContent = date.toLocaleString();
          document.getElementById('row-time').classList.remove('d-none');
          hasData = true;
        }

        if (data.details) {
          document.getElementById('ctx-details').textContent = data.details;

          
          const labelDetails = document.getElementById('label-details');
          if (data.type === 'object') {
            labelDetails.textContent = 'Object Metadata Details:';
          } else if (data.type === 'report') {
            labelDetails.textContent = 'Report Description:';
          } else {
            labelDetails.textContent = 'Firing Context:';
          }

          document.getElementById('row-details').classList.remove('d-none');
          hasData = true;
        }

        if (hasData) {
          document.getElementById('pslens-context-panel').classList.remove('d-none');
        }
      }
    } catch (e) {
      console.error('Failed to parse operational context metadata:', e);
    }
  })();
</script>


## Backlogged Processes Alert

**Alert ID:** `backlogged_processes`
**Category:** Process Scheduler
**Default threshold:** 30 minutes

### What This Alert Detects

This alert finds Process Scheduler requests that are in **Queued** or **Blocked** status and whose scheduled run time (`RUNDTTM`) has already passed by more than the configured threshold.

### Severity Logic

|                  Condition                  | Severity |
| ------------------------------------------- | -------- |
| Overdue by more than `thresholdMinutes`     | Warning  |
| Overdue by more than `thresholdMinutes × 2` | Critical |

For example, with the default threshold of 30 minutes:

- A process scheduled 40 minutes ago that is still queued → **Warning**
- A process scheduled 65 minutes ago that is still queued → **Critical**

### What Gets Checked

The alert queries the Process Scheduler request table for processes in run status **5 (Queued)** or **18 (Blocked)** whose `RUNDTTM` (scheduled run datetime) is in the past. For each result, it calculates how far past the scheduled time the process is based on `RUNDTTM` and the current server time.

Processes with no `RUNDTTM` value are skipped.

### Alert Details

Each alert item includes:

- Process name (`PRCSNAME`)
- Process instance number
- How long the process is overdue (in minutes)
- Current run status (Queued or Blocked)
- The operator who submitted the request
- A link to the Process Monitor detail page for that instance

### Configuration

```yaml
alerts:
  checks:
    backlogged_processes:
      enabled: true
      thresholdMinutes: 30         # Minutes overdue before flagging as Warning
      excludeProcesses:            # Process names to skip
        - SOME_LOW_PRIORITY_JOB
```

|      Setting       | Default |                                                            Description                                                             |
| ------------------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `thresholdMinutes` | `30`    | Minutes past the scheduled run time before a queued/blocked process triggers a Warning alert. Critical fires at 2× this value.     |
| `excludeProcesses` | `[]`    | List of process names to exclude from this check. Use for processes that are known to queue for a long time and are not a concern. |

### How to Respond

1. Click the alert link to go directly to the Process Monitor entry for the flagged process
2. Check whether the Process Scheduler server is running and accepting work
3. Look at how many processes are currently running on the server. It may have hit its concurrency limit
4. Check if the process type or class has reached its maximum allowed concurrent instances
5. For blocked processes, investigate what is blocking them (dependencies, server restrictions, etc.)
6. If the Process Scheduler server is down, restart it from PeopleSoft's Process Scheduler administration

### Tuning the Threshold

The right threshold depends on how busy your Process Scheduler is. In environments where many jobs are submitted at once, some queuing is normal. Set `thresholdMinutes` high enough to avoid false positives during peak batch windows but low enough to catch genuine problems. You can also use `excludeProcesses` to exclude specific low-priority processes that are known to queue for long periods.
