{"record":{"id":"62b6dab50b8d9c82","repo":"apache/seatunnel","slug":"get-overview-slow-costms-thread-heapusedmb","errorCode":null,"errorMessage":"GET /overview slow: costMs={} thread={} heapUsedMB={} heapTotalMB={} heapMaxMB={}","messagePattern":"GET /overview slow: costMs=(.+?) thread=(.+?) heapUsedMB=(.+?) heapTotalMB=(.+?) heapMaxMB=(.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/rest/servlet/OverviewServlet.java","lineNumber":87,"sourceCode":"                                JsonUtils.toJsonString(overviewService.getOverviewInfo(tags))));\n\n        long costMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);\n        long dispatchDelayMs = receivedMs <= 0 ? -1 : Math.max(0, nowMs - receivedMs);\n\n        resp.setHeader(\"X-Dispatch-Delay-Ms\", String.valueOf(dispatchDelayMs));\n        resp.setHeader(\"X-Handler-Cost-Ms\", String.valueOf(costMs));\n\n        writeJson(resp, body);\n        if (dispatchDelayMs > 500) {\n            log.warn(\n                    \"GET /overview dispatch delayed: dispatchDelayMs={} thread={}\",\n                    dispatchDelayMs,\n                    Thread.currentThread().getName());\n        }\n        if (costMs > 500) {\n            Runtime rt = Runtime.getRuntime();\n            long usedBytes = rt.totalMemory() - rt.freeMemory();\n            log.warn(\n                    \"GET /overview slow: costMs={} thread={} heapUsedMB={} heapTotalMB={} \"\n                            + \"heapMaxMB={}\",\n                    costMs,\n                    Thread.currentThread().getName(),\n                    usedBytes / 1024 / 1024,\n                    rt.totalMemory() / 1024 / 1024,\n                    rt.maxMemory() / 1024 / 1024);\n        }\n    }\n}\n","sourceCodeStart":69,"sourceCodeEnd":98,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/rest/servlet/OverviewServlet.java#L69-L98","documentation":"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.","triggerScenarios":"GET /overview handler execution exceeding 500ms — typically due to JVM GC pauses, heap pressure, or expensive job-status collection on the coordinator.","commonSituations":"Clusters with many running jobs making overview aggregation expensive; nodes near heap exhaustion (full GCs); slow disk/CPU contention on the master node.","solutions":["Read the heapUsedMB/heapMaxMB values in the log — if usage is near max, increase JVM -Xmx for the node","Reduce the number of jobs or scale out the cluster","Enable/inspect GC logs to confirm GC pauses as the cause","Lower monitoring poll rate and avoid concurrent heavy REST queries"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// check handler cost via the response header\nconst cost = Number(resp.headers.get('X-Handler-Cost-Ms') || 0);\nif (cost > 500) console.warn('overview slow, reduce poll rate');","typeGuard":null,"tryCatchPattern":"try {\n  const resp = await fetch(baseUrl + '/overview');\n  if (!resp.ok || Number(resp.headers.get('X-Handler-Cost-Ms')) > 500) {\n    await sleep(backoffMs);\n  }\n} catch (e) { /* exponential backoff retry */ }","preventionTips":["Size JVM heap generously (-Xmx) on coordinator nodes","Enable GC logging to correlate slow handlers with GC pauses","Avoid stacking many concurrent REST queries during heavy scheduling","Scale out if job count grows beyond node capacity"],"tags":["performance","jvm","memory","latency"],"backgroundTag":"request-timeout","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}