apache/seatunnel · warning

GET /overview slow: costMs=

Error message

GET /overview slow: costMs={} thread={} heapUsedMB={} heapTotalMB={} heapMaxMB={}

What it means

OverviewServlet.doGet logs this when handling GET /overview took more than 500ms (costMs > 500). The log includes heap statistics (used/total/max MB) to help diagnose whether memory pressure caused the slowness.

Solutions

  1. Read the heapUsedMB/heapMaxMB values in the log — if usage is near max, increase JVM -Xmx for the node
  2. Reduce the number of jobs or scale out the cluster
  3. Enable/inspect GC logs to confirm GC pauses as the cause
  4. Lower monitoring poll rate and avoid concurrent heavy REST queries
Defensive patterns

Strategy: retry

Validate before calling

// check handler cost via the response header
const cost = Number(resp.headers.get('X-Handler-Cost-Ms') || 0);
if (cost > 500) console.warn('overview slow, reduce poll rate');

Try / catch

try {
  const resp = await fetch(baseUrl + '/overview');
  if (!resp.ok || Number(resp.headers.get('X-Handler-Cost-Ms')) > 500) {
    await sleep(backoffMs);
  }
} catch (e) { /* exponential backoff retry */ }

Prevention

When it happens

Trigger: GET /overview handler execution exceeding 500ms — typically due to JVM GC pauses, heap pressure, or expensive job-status collection on the coordinator.

Common situations: Clusters with many running jobs making overview aggregation expensive; nodes near heap exhaustion (full GCs); slow disk/CPU contention on the master node.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/62b6dab50b8d9c82. Report an issue: GitHub.

Appendix: source

Thrown at seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/rest/servlet/OverviewServlet.java:87

                                JsonUtils.toJsonString(overviewService.getOverviewInfo(tags))));

        long costMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
        long dispatchDelayMs = receivedMs <= 0 ? -1 : Math.max(0, nowMs - receivedMs);

        resp.setHeader("X-Dispatch-Delay-Ms", String.valueOf(dispatchDelayMs));
        resp.setHeader("X-Handler-Cost-Ms", String.valueOf(costMs));

        writeJson(resp, body);
        if (dispatchDelayMs > 500) {
            log.warn(
                    "GET /overview dispatch delayed: dispatchDelayMs={} thread={}",
                    dispatchDelayMs,
                    Thread.currentThread().getName());
        }
        if (costMs > 500) {
            Runtime rt = Runtime.getRuntime();
            long usedBytes = rt.totalMemory() - rt.freeMemory();
            log.warn(
                    "GET /overview slow: costMs={} thread={} heapUsedMB={} heapTotalMB={} "
                            + "heapMaxMB={}",
                    costMs,
                    Thread.currentThread().getName(),
                    usedBytes / 1024 / 1024,
                    rt.totalMemory() / 1024 / 1024,
                    rt.maxMemory() / 1024 / 1024);
        }
    }
}

View on GitHub (pinned to cf67b549a7)