Container

Monitoring

Use the up, diagnostics, and targethealth endpoints to monitor pdfRest API Toolkit Container health and available processing capacity.

Choose a monitoring endpoint

The Container provides three monitoring endpoints for API availability and Command-Line Utility (CLU) processing capacity. Use them to check availability, inspect capacity, and decide whether the container should receive more work.

EndpointPurposeResponse
GET /upCheck API liveness and identify the deployed release.200 with product and release information and status: "OK".
GET /diagnosticsInspect available CLU slots and running processes.200 with a JSON snapshot of processing capacity and processes.
GET /targethealthCheck processing capacity against health thresholds.200 with an empty body when within thresholds; 252 with an empty body when either threshold is reached.

All three endpoints accept requests without authentication or an Api-Key header. Call them on your deployed Container's address. The examples below use http://localhost, matching the host port 80 in the Docker Compose deployment example. The API listens on port 3000 inside the container; adjust the URL for your deployment.

See the Container API Reference Guide for the endpoint schemas and response details.

Check API availability with /up

curl --silent --show-error --max-time 5 http://localhost/up

A running API returns JSON containing status: "OK", product, releaseDate, and version. Use this endpoint for uptime monitoring and liveness checks, and record the release fields when investigating a deployment issue.

/up does not run a document-processing operation or assess available CLU capacity. It can return 200 while all processing slots are occupied. Use /targethealth to decide whether capacity is available, and a representative document-processing request to verify your complete workflow, including licensing and storage.

Understand CLU concurrency

pdfRest uses Command-Line Utilities (CLUs) to process documents. A CLU execution acquires a processing slot and releases it when the execution finishes. PDFREST_MAX_CLU_CONCURRENCY controls how many CLU executions can run at once in a container. This is a limit on utility executions; a single API request can involve multiple processing steps.

By default, the limit is the CPU parallelism available to the server minus one, with a minimum of one slot. For example, when the server detects four available CPUs, the default is three slots. Set an explicit positive integer if you need a predictable limit for your deployment, and tune it using representative documents and CPU and memory measurements.

When all slots are occupied, additional CLU executions wait in the local queue. PDFREST_CLU_SEMAPHORE_WAIT_TIME controls how long an execution can wait for a slot before timing out, in seconds, and defaults to 180. This wait is separate from MAX_PROCESS_TIME, which limits processing time. See environment variables for configuration details.

Concurrency and waiting work are local to each container. Adding replicas adds separate processing capacity; it does not create one shared queue or concurrency limit.

Inspect capacity with /diagnostics

curl --silent --show-error --max-time 5 http://localhost/diagnostics

For a container configured with three slots and one running CLU, a response could look like this:

{
  "availableCluProcesses": 2,
  "cluProcessCount": 1,
  "cluProcesses": [
    {
      "cmd": "/opt/datalogics/.example-clu",
      "cpu_pct": 0.1,
      "mem_pct": 0.2
    }
  ]
}
FieldHow to use it
availableCluProcessesNumber of processing slots currently available for new CLU work. A value of 0 means all slots are occupied.
cluProcessCountNumber of running main CLU processes. This is the process count used by /targethealth.
cluProcessesDetails of running CLU processes, including related child processes. Each entry contains the command (cmd), CPU usage percentage (cpu_pct), and memory usage percentage (mem_pct). The array is empty when no CLU processes are running.

The process list and slot availability measure different things. cluProcesses.length can exceed cluProcessCount because the list includes child processes. Slot acquisition and process startup or shutdown also occur at different times, so do not assume that availableCluProcesses + cluProcessCount always equals the configured limit.

Poll each container directly and label measurements by instance or Pod. Polling only a load-balanced address can sample a different container each time and hide a busy instance. Track available slots alongside request latency, errors, and host CPU and memory usage. The response does not include queue length or request wait time; zero available slots alone does not tell you how many requests are waiting.

/diagnostics returns 500 if process diagnostics cannot be retrieved. Treat this as a monitoring failure and inspect the container logs. The process commands can contain arguments and file paths, so keep access to this unauthenticated endpoint within your operational network and handle collected responses accordingly.

Check capacity health with /targethealth

curl --silent --show-error --max-time 5 \
  --output /dev/null --write-out '%{http_code}\n' \
  http://localhost/targethealth

The endpoint compares a diagnostics snapshot against two thresholds:

Environment variableDefaultCondition that returns 252
HEALTH_MINIMUM_CLU_CONCURRENCY_LIMIT0availableCluProcesses is less than or equal to this value.
HEALTH_MAXIMUM_EXECUTING_CLUSThe effective maximum CLU concurrency.cluProcessCount is greater than or equal to this value.

Either condition is enough to return 252. The endpoint returns 200 only when available slots are above the minimum and running main CLUs are below the maximum. Both responses have an empty body. If the diagnostics lookup fails, the endpoint returns 500.

Configure capacity health checks to accept only HTTP 200. 252 is in the 2xx range but indicates that a capacity threshold has been reached. A check that accepts all 2xx responses, or relies only on curl --fail, will treat it as successful.

Configure headroom

The health thresholds affect the health response; they do not change the execution limit or stop the API from accepting requests. Set them through the environment variables described in Configure Container.

For example, add these values to the environment section of your Docker Compose service:

environment:
  LICENSE_KEY: YOUR-LICENSE-KEY-VALUE-HERE
  PDFREST_MAX_CLU_CONCURRENCY: "4"
  HEALTH_MINIMUM_CLU_CONCURRENCY_LIMIT: "1"
  HEALTH_MAXIMUM_EXECUTING_CLUS: "3"

With these settings, /targethealth returns 252 when one or fewer slots remain, or when three or more main CLUs are running. It returns 200 when more than one slot remains and fewer than three main CLUs are running. This lets a health-aware router stop assigning new work before all four slots are occupied.

Choose thresholds that allow an idle container to be healthy. For example, setting the minimum available-slot threshold equal to the concurrency limit makes even an idle container return 252. Raising the maximum executing-CLU threshold above the concurrency limit does not override the available-slot check.

Use an exact-status check

For a script or monitoring agent, compare the returned status explicitly and fail on connection errors or timeouts:

#!/bin/sh
status=$(curl --silent --show-error --max-time 5 \
  --output /dev/null --write-out '%{http_code}' \
  http://localhost/targethealth) || exit 1
[ "$status" = "200" ]

This check exits successfully only for 200. Set the address to the individual container being monitored. For a load balancer, use /targethealth as the target health path and set its success-code matcher to 200.

Integrate health checks with your deployment

Use /up for liveness and /targethealth for capacity-based readiness or routing. A 252 response generally means the container is busy; let its active work finish and use the signal to defer or redirect new work. Restarting a busy container can interrupt document processing.

Kubernetes probes

Kubernetes HTTP probes accept status codes from 200 through 399, including 252. Use an exec readiness probe to require exactly 200. Add the following settings to the pdfRest container entry under spec.template.spec.containers in the Kubernetes deployment:

startupProbe:
  httpGet:
    path: /up
    port: 3000
  periodSeconds: 5
  timeoutSeconds: 5
  failureThreshold: 30
livenessProbe:
  httpGet:
    path: /up
    port: 3000
  periodSeconds: 10
  timeoutSeconds: 5
  failureThreshold: 3
readinessProbe:
  exec:
    command:
      - node
      - -e
      - |
        const http = require('node:http');
        const request = http.get('http://127.0.0.1:3000/targethealth', (response) => {
          response.resume();
          process.exit(response.statusCode === 200 ? 0 : 1);
        });
        request.setTimeout(3000, () => request.destroy(new Error('Health check timed out')));
        request.on('error', () => process.exit(1));
  periodSeconds: 10
  timeoutSeconds: 5
  failureThreshold: 3
  successThreshold: 2

The startup probe allows time for initialization. Readiness failures remove the Pod from Service traffic while liveness failures can trigger a restart. Tune the example timings for your workload. See the Kubernetes probe documentation for probe behavior and settings.

Multiple containers and alerting

Monitor every replica and use several consecutive checks before changing routing or sending an alert. Brief saturation can be normal during a batch. Sustained 252 responses, increasing request latency, or concurrency-wait timeouts can indicate that you need to reduce incoming work, tune concurrency, or add capacity. These endpoints report health; your monitoring and deployment systems must implement alerts, routing, and scaling actions.

Before routing document-processing requests across replicas, configure shared storage so every container can access the same input and output files. These health endpoints do not verify shared-storage access, free disk space, or successful completion of a document workflow. Monitor those separately and use the Storage Guide to plan file retention and volume configuration.