본문으로 건너뛰기
cccskills
무료GitHub에 공개

flame-graph-analyzer

Reads CPU flame-graph output from py-spy (Python), async-profiler (JVM), Go pprof, or Node.js `perf_hooks` / clinic.js: identifies the hot path (top sample-time frames), classifies the bottleneck (CPU-bound vs lock contention vs allocator pressure), and proposes the next investigation step. Use when a perf regression is bisected to a commit but the hot path inside it is unclear; for tail-latency percentiles use the latency-percentiles reference in k6-load-testing, and for a slow SQL hot path use db-query-plan-analyzer.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

testland/qa스타 13(GitHub 13 + cccskills 0)

실행 점수 미검증

설치 방법 보기

포함된 파일(3)

  • SKILL.md7.8 KB
  • .tessl-plugin/plugin.json660 B
  • references/capturing-and-interpreting-flame-graphs.md4.2 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

flame-graph-analyzer

Overview

Canonical flame-graph reference: brendan-gregg-flame. The widest leaf (bottom of the stack) is the hot path.

Each runtime produces flame graphs from its own profiler - py-spy (Python), async-profiler (JVM), Go's built-in pprof, clinic.js flame (Node.js), and perf / eBPF (native C/C++/Rust). This skill is language-agnostic: it consumes the profiler output (SVG, JSON, or folded-stacks .txt) and surfaces a hypothesis the engineer can act on. Per-runtime capture commands live in references/capturing-and-interpreting-flame-graphs.md.

When to use

  • A perf regression has been bisected but the introducing commit touches multiple functions; the team needs to know which function is the actual hot path.
  • A load test under k6-load-testing or a sibling shows latency growth, but the API code hasn't visibly changed - the flame graph reveals the runtime cause.
  • A production incident showed CPU saturation; the team has captured a profile and needs to triage before reducing fleet size.
  • An EXPLAIN ANALYZE trace suggests CPU is the bottleneck rather than I/O - the flame graph confirms.

How to use

  1. Capture a profile under realistic load with the runtime's profiler and export folded stacks - per-runtime capture commands in references/capturing-and-interpreting-flame-graphs.md.
  2. Sort the folded stacks by sample count and read the top 5 leaves (the actual working code, not framework wrappers).
  3. Classify each hot leaf's sample-time signature (CPU-bound vs allocator pressure vs lock contention vs I/O-misclassified) using the table below.
  4. Propose the next step for the dominant leaf; the category-to-fix remediation catalog is in references/capturing-and-interpreting-flame-graphs.md.
  5. Re-profile after the change to confirm the delta, then hand off to perf-budget-gate to confirm the regression delta closes.

Reading the hot path

Read the folded stacks (or extract them from the SVG / JSON), sort by sample count, and identify the top leaves - the bottom-of-stack frames that are the actual working code, not framework wrappers:

# top 5 leaves by sample count
sort -k2 -n -r folded.txt | head -5

Each hot leaf's sample-time signature points to one category:

CategorySignature in the flame graph
CPU-bound (hot algo)A wide leaf in user code (a regex, a JSON serializer, a hash function).
Allocator pressureWide GC frames (gc::scavenge, Java GC, gc.collect).
Lock contentionWide synchronization frames (pthread_mutex_lock, Object.wait, parking).
I/O wait misclassifiedOn-CPU profilers don't show I/O blocks; switch to wall-clock profiling.
Reflection / dynamic dispatchWide reflection.invoke, method_missing, getattr chains.
Logging overheadWide log.format, Logger.debug, serialization for log lines.

Worked example

A Node.js endpoint regressed after a bisected commit. Capture under load, then read the hot path end to end.

Capture (Node.js clinic.js flame; other runtimes in the reference):

npx clinic flame -- node app.js
# drive load against the process, then stop it; clinic writes flame.html + folded stacks

Sort the folded stacks and read the top leaves:

sort -k2 -n -r folded.txt | head -5
main;handleRequest;serializeJson;JSON.stringify   4521
main;handleRequest;dbQuery;Array.from              2103
main;handleRequest;dbQuery;parseRows               1832
main;authCheck;jwt.verify;crypto.createHash        904
main;handleRequest;serializeJson;Buffer.from       312

Emit the analysis:

## Flame graph analysis - `flame.html`

**Runtime:** node
**Profile duration:** 30s under load

| Rank | Sample share | Stack (leaf)                          | Category |
|-----:|-------------:|---------------------------------------|----------|
| 1    | 38%          | `JSON.stringify` (in `serializeJson`) | CPU-bound hot algo |
| 2    | 17%          | `Array.from` (in `dbQuery`)           | Allocator pressure |
| 3    | 15%          | `parseRows` (in `dbQuery`)            | CPU-bound hot algo |
| 4    | 8%           | `jwt.verify` (in `authCheck`)         | CPU-bound hot algo (crypto) |
| 5    | 3%           | `Buffer.from` (in `serializeJson`)    | Allocator pressure |

### Hypothesis
The serialization path is load-bearing: rank 1 (`JSON.stringify`, 38%) plus
rank 5 (`Buffer.from`, 3%) account for ~41% of sampled time combined.

### Recommended next step
1. Switch to a streaming JSON serializer (`fast-json-stringify` in Node,
   `orjson` in Python, Jackson's `JsonGenerator` in the JVM) to eliminate the
   intermediate string allocation.
2. Re-profile; expect rank 1 to drop below 10%.
3. Hand off to `perf-budget-gate` to confirm the regression delta closes.

More interpreted cases (GC pressure, lock contention, reflection overhead) and the category-to-fix remediation catalog are in references/capturing-and-interpreting-flame-graphs.md.

Anti-patterns

Anti-patternWhy it failsFix
Reading the SVG visually only, no quantitative dataEasy to mis-judge widths; biases toward dramatic-looking deep stacks.Always work from folded stacks; sort by sample count.
Profiling under load that is too lowOne request per second can't expose contention or allocator pressure.Profile under realistic load - pair with k6-load-testing.
Optimizing rank 5 first because rank 1 looks "structural"Premature optimization; misses the dominant cost.Always start with rank 1; only descend if rank 1 is genuinely framework-bound (e.g. event_loop).
On-CPU profiler for an I/O-bound workloadI/O wait doesn't appear; the flame graph shows what's running, not what's waiting.Use wall-clock / off-CPU profiling for I/O-bound workloads.
Single 30-second capture under highly variable loadThe sample is unrepresentative.Capture multiple samples across the load-test duration; merge.

Limitations

  • Symbolication. Without debug symbols, the flame graph shows hex addresses. Profile with debug info enabled in CI builds intended for analysis.
  • Inlining. Aggressive inlining (especially in the JVM hot-path optimizer) can hide functions; the flame graph shows the post-inlining shape, which may not match the source.
  • Sampling vs. tracing. Sample-based flame graphs give relative weights; for absolute timings of specific operations, use a tracer instead.

References

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Builds a CI gate that fails the build on **new** WCAG / a11y violations introduced by a PR while grandfathering pre-existing violations on a per-rule / per-page baseline. Aggregates verdicts from axe-core / pa11y / Lighthouse a11y / WAVE / IBM Equal Access scans. Use when a project has accumulated a11y debt and a strict "zero violations" gate would block every PR - the ratchet pattern lets the team ship while preventing regressions.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

testland/qa132026년 10월 20일 업데이트

Workflow skill that builds an A/B-test validity checklist from an experiment proposal, walking the canonical design-correctness gates - pre-registered OEC/power/guardrails, randomization unit + SRM check, assignment integrity, telemetry, peeking discipline, novelty/primacy, post-experiment SRM re-check - into a per-experiment checklist + sign-off form. Use when launching, auditing, or governing an experiment. For pitfall mechanics (guardrails, peeking) see experiment-results-interpreter's references; to read an already-valid result use experiment-results-interpreter; for per-SDK harness tests use experiment-sdk-testing - this gates DESIGN, not SDK code.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

testland/qa132026년 10월 20일 업데이트

The single install-flow skill: the reference contract for the PWA install flow (installability gate fields, `beforeinstallprompt` handshake, per-platform paths - Android WebAPK / iOS Share menu / Firefox no-op - and the `display-mode` post-install signal, in references/install-flow-reference.md) plus the build-an-X workflow that emits the Add-to-Home-Screen suite. Walks the four-stage timeline, emitting one test per gate cell per [web.dev/articles/install-criteria][install-criteria], the deferred-prompt → `prompt()` → `userChoice` chain per [web.dev/articles/customize-install][customize-install], the iOS Safari manual-metadata branch (`apple-touch-icon`) per [web.dev/learn/pwa/installation][learn-pwa], and the post-install `(display-mode: standalone)` MQ assertion. Output: a Playwright spec with per-stage cells plus a coverage matrix. Use when a PWA's manifest, icons, or install handler change, when install conversion drops at an unknown stage, or when triaging a flaky install assertion.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

testland/qa132026년 10월 20일 업데이트

Build-an-X workflow that uses an LLM to map existing tests to spec sections - given a spec doc + the test suite, the LLM identifies which tests cover which sections, surfaces uncovered sections (gap), and recommends specific tests to add. Output is a coverage matrix per spec ID. Scope is mapping tests that already exist and naming the gaps, not authoring tests for new acceptance criteria. Use when a spec doc and a test suite both exist but nobody can say which requirements are actually covered - before a release sign-off, an audit, or a decision about where to spend the next round of test effort.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

testland/qa132026년 10월 20일 업데이트

Generates tests from natural-language specs (acceptance criteria, user stories, requirements) using an LLM, with confidence scoring per test case (LLM self-assessment plus heuristics: assertion quality, naming, completeness), batching uncertain cases for human review, and integration with the team's existing test framework. Use when the user asks to generate unit tests from acceptance criteria, convert user stories to test cases, automate test creation from requirements, or augment a spec-driven test suite with AI-generated stubs that are then curated before merge.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

testland/qa132026년 10월 20일 업데이트

Configures Allure Report (test-runner adapter install, `allure-results` directory wiring, `categories.json` for failure classification, `history-trend.json` retention via the copy-history-between-runs pattern), runs the Allure CLI to convert `allure-results` to a static HTML site, and uploads the report as a CI artifact. Use when the team needs richer test reporting than JUnit XML - step-level attachments, per-test history, retry tracking, and severity / epic / feature labeling across framework-agnostic adapters (pytest, Jest, JUnit, TestNG, NUnit, Mocha). As a rich static HTML report generator, it is the open-source alternative to the sunset ExtentReports (JVM/.NET per-test HTML narrative); for hosted cross-run flakiness analytics rather than a static per-run report use currents-integration.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

testland/qa132026년 10월 20일 업데이트

testland의 스킬 모두 보기

이 스킬의 문제 신고