Agent skill

Samply

by vortex-data in vortex-data/vortex

Analyze Samply Firefox-profiler output, record focused profiles, summarize hot threads/stacks, inspect symbolication, and compare profile evidence before and after a performance change.

Apache-2.0Auto-check passedDevelopment

Install Samply

skills CLI
$ npx skills add vortex-data/vortex --skill samply -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install vortex-data/vortex samply --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/vortex-data/vortex.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/samply .claude/skills/samply && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
samply
GitHub stars
3.2k
Token cost
~2.7k tokens
SKILL.md length
1,211 words
Files
5 (incl. scripts)
Skills in repo
3
Repo updated
First seen
Licence
Apache-2.0

At a glance

Analyze Samply Firefox-profiler output, record focused profiles, summarize hot threads/stacks, inspect symbolication, and compare profile evidence before and after a performance change.

  • Works in 4 steps: timing command starts: say what target,… → timing command finishes: immediately… → profile command finishes: immediately… → …
  • Tasks that involve Performance optimization
  • SKILL.md covers Overview, Share Evidence Early, Standard Loop and Samply JSON Schema, plus 3 more sections
  • Runs Python scripts from its folder; calls python3, git and jq

What it does

Samply is an agent skill from vortex-data/vortex. Analyze Samply Firefox-profiler output, record focused profiles, summarize hot threads/stacks, inspect symbolication, and compare profile evidence before and after a performance change.

Its SKILL.md is about 2.7k tokens, which your agent loads only when the skill is triggered. The skill folder holds 6 other files, including scripts (for example `agents/openai.yaml`, `scripts/profile_activity.py` and `scripts/profile_inverted_tree.py`).

It sits in Development, covering Performance optimization. It works with Python and Rust. The repository describes itself as: An extensible, state-of-the-art framework for columnar compression, and the fastest FOSS columnar file format. Formerly at @spiraldb, now an Incubation Stage project at… The licence is Apache-2.0.

When your agent uses it

  • Tasks that involve Performance optimization

Example prompts

  • “/samply”

Requirements

  • Python 3

Workflow steps

4 steps, taken from the first numbered list in SKILL.md.

  1. timing command starts: say what target, input, mode, and runtime toggles are being measured;
  2. timing command finishes: immediately show timing results and output path;
  3. profile command finishes: immediately show profile path, a samply load command the user can
  4. deeper analysis begins: state the concrete hotspot or hypothesis being checked.

What it can do on your machine

Read from SKILL.md and the folder at commit d9ad4cf. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Ships 3 files in scripts/ (Python), which the agent can run.

    Shell commands in SKILL.md call:

    • python3
    • git
    • jq

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use git, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Samply loads about 2.7k tokens when it runs. Until then it costs about 48 tokens; SKILL.md has 1,211 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~48
When it runs · the whole SKILL.md, loaded when a task matches
~2.7k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.

SKILL.md

The full file from vortex-data/vortex at commit d9ad4cf, republished under its Apache-2.0 licence (© vortex-data). 1,211 words, ~2,676 tokens.

Download SKILL.mdSave it as .claude/skills/samply/SKILL.md (or your agent's skills folder). This skill also uses 4 other files; get the full folder from GitHub.
name
samply
description
Analyze Samply Firefox-profiler output, record focused profiles, summarize hot threads/stacks, inspect symbolication, and compare profile evidence before and after a performance change.

Samply

Overview

Use this skill when a task involves Samply recordings or Firefox-profiler JSON, especially profile.json.gz files, samply record, samply load, symbolication, thread timeline skew, or hot stack interpretation. Keep the loop evidence-driven: establish a focused baseline, record the exact target, summarize the profile before deep code reading, make one scoped change, and rerun the same target.

This skill is intentionally project-agnostic. Any project-specific benchmark harness, environment variables, metrics, or logging commands should live in a separate benchmark skill or in the current task context.

Share Evidence Early

Do not disappear into profile spelunking while useful output is already available. As soon as a timing run finishes, report the timing lines or comparison table before starting deeper analysis. As soon as a profile summary is available, report the top threads/functions/stacks before reading more code. Then continue investigating with those facts visible.

For long performance sessions, use this cadence:

  1. timing command starts: say what target, input, mode, and runtime toggles are being measured;
  2. timing command finishes: immediately show timing results and output path;
  3. profile command finishes: immediately show profile path, a samply load command the user can run to inspect it in Firefox Profiler, and the first stack/function summary;
  4. deeper analysis begins: state the concrete hotspot or hypothesis being checked.

Standard Loop

  1. Check branch state and changed surface when working in a repository:

    bash
    git status --short
    git branch --show-current
    git diff --stat
  2. Run a focused timing command before profiling. Prefer one executable, one workload/input, one mode, and enough iterations to smooth obvious noise. If the experiment has a runtime environment toggle, prefix every timing and profile command with the same env setting; this is often faster than recompiling and makes A/B comparisons clearer.

    Generic shape:

    bash
    FEATURE_TOGGLE=1 <timing-command> --iterations 5 --output /tmp/<label>.jsonl

    If a project has an existing benchmark harness, use that harness for the timing baseline and copy its exact target arguments into the profiled command.

  3. Record a focused Samply profile. Prefer recording without --unstable-presymbolicate first, then symbolicate offline with the scripts below. This avoids chasing misleading pre-symbolicated stacks when unwinding or symbol lookup gets confused.

    bash
    FEATURE_TOGGLE=1 samply record --save-only --rate 1000 \
      --output /tmp/<label>.profile.json.gz \
      -- /absolute/path/to/<binary> <args>

    Put environment assignments before samply record, as shown above. Do not put them after the -- separator; everything after -- is the command Samply launches and profiles.

    On macOS, profiling through a system helper such as env, sleep, /bin/true, or system Python can be a bad sanity check because signed system executables may block Samply's task-port handoff. Prefer a locally built binary or a user-owned executable.

    In a sandboxed agent environment on macOS, Encountered an error during profiling: Unknown(1100) usually means Samply was blocked before the profiled command started. Rerun the same samply record command with the required execution permissions instead of changing the workload.

    Use a profile with debug information when stack quality matters. If the symbols or unwinding look suspect, rebuild with the project's highest-quality profiling/debug-symbol profile and record again.

    If a profile shows impossible-looking ancestry, such as hot execution frames nested under unrelated Drop::drop frames or otherwise nonsensical async stacks, do not trust the stack summary. First verify the binary UUID matches the profile, remove presymbolication from the recording command, and rebuild with better debug symbols if needed.

    After the profile is recorded, immediately show the user the command to open it themselves:

    bash
    samply load /tmp/<label>.profile.json.gz

    samply load starts a local Firefox Profiler server and opens the browser UI. If the user only wants the URL or the environment cannot open a browser, use:

    bash
    samply load --no-open /tmp/<label>.profile.json.gz

    Then report the printed local URL.

  4. Summarize the profile without opening Firefox Profiler. Run a small summary first and report it immediately, then run a wider summary only if needed:

    bash
    python3 .agents/skills/samply/scripts/profile_summary.py \
      /tmp/<label>.profile.json.gz \
      --binary /absolute/path/to/<binary> \
      --symbolicate \
      --weight-mode cpu \
      --top 12 \
      --threads 2 \
      --stacks 4 \
      --stack-depth 10

    Wider follow-up:

    bash
    python3 .agents/skills/samply/scripts/profile_summary.py \
      /tmp/<label>.profile.json.gz \
      --binary /absolute/path/to/<binary> \
      --symbolicate \
      --weight-mode cpu \
      --top 30 \
      --threads 6 \
      --stacks 12

    For timeline skew, quantify worker occupancy instead of relying only on the visual timeline:

    bash
    python3 .agents/skills/samply/scripts/profile_activity.py \
      /tmp/<label>.profile.json.gz \
      --thread-regex '<worker-thread-regex>' \
      --bin-ms 10

    For a focused inverted call tree over a thread class or time range, use:

    bash
    python3 .agents/skills/samply/scripts/profile_inverted_tree.py \
      /tmp/<label>.profile.json.gz \
      --binary /absolute/path/to/<binary> \
      --symbolicate \
      --thread-regex '<worker-thread-regex>' \
      --start-ms <start> \
      --end-ms <end> \
      --contains '<frame-regex>'
  5. Inspect code near the actual hot path. Load the workload definition when it matters; do not rely on memory for the workload shape.

  6. Make one narrow change, rerun the focused timing/profile command, and record the before/after command lines and results. Do not broaden the workload until the narrow target explains the change.

Show full SKILL.md (537 more words)Show less

Samply JSON Schema

Samply writes Firefox-profiler JSON, often compressed as profile.json.gz.

  • Top-level keys commonly include meta, libs, threads, pages, counters, and profilerOverhead.
  • meta.product names the process, meta.interval is the sampling interval in milliseconds, and meta.startTime is an epoch timestamp in milliseconds.
  • libs[] records loaded binaries with name, path, debugPath, codeId, breakpadId, and arch. Use this to verify symbol files still match the profile.
  • Each threads[] entry has name, tid, samples, stackTable, frameTable, funcTable, resourceTable, and stringArray.
  • samples.length is the number of stored sample rows. samples.stack[] points into stackTable. samples.weight[] is the number of collapsed samples represented by that row; use weight instead of row count when present. samples.threadCPUDelta[] is per-thread CPU delta in microseconds when present.
  • stackTable is a linked list: stackTable.frame[i] is the current frame and stackTable.prefix[i] points to the caller stack. Follow prefixes to null and reverse to get root-to-leaf order.
  • frameTable.func[frame] points into funcTable; funcTable.name[func] points into stringArray. funcTable.resource[func] points into resourceTable, whose name or lib fields point back into stringArray.

Symbolication

If function names are raw addresses such as 0x3db28a0, the profile is not symbolicated. Before using atos, verify the binary UUID/code ID matches the profile:

bash
gzip -cd /tmp/<label>.profile.json.gz | jq '.libs[] | {name, path, codeId, breakpadId}'
dwarfdump --uuid /absolute/path/to/<binary>

If the UUID/code ID does not match, do not trust symbol names from the current binary. Re-profile, or keep the exact binary plus any symbol sidecar emitted by the recorder.

On macOS, Samply stores app addresses as offsets. Add the Mach-O text load address when using atos manually:

bash
atos -o /absolute/path/to/<binary> -l 0x100000000 0x103db28a0

For a raw offset 0x3db28a0, the address passed to atos is 0x100000000 + 0x3db28a0.

When using the bundled scripts, pass --symbol-lib <library-name> if the binary name in profile.libs[] differs from the basename of --binary.

Reading Profiles

  • Treat the main thread as orchestration unless its CPU delta is high. Useful CPU time is often on worker threads, but thread naming is runtime-specific.
  • Sort threads by total sample weight and CPU delta. Many idle worker threads can have high wall time but near-zero CPU.
  • Use profile_activity.py when the Firefox Profiler timeline shows empty space. Good parallel traces keep worker occupancy high through the timed region; a low-occupancy tail points to scheduling skew, stragglers, dependency ordering, partition imbalance, blocking, or insufficient work admission.
  • Use profile_inverted_tree.py with --contains for allocation frames, blocking frames, or a hot leaf function to see the caller contexts that produce the samples.
  • A stack with many samples may mean the operation is slow, or it may mean it is called many times. Samply alone usually cannot distinguish those. Pair hot stacks with counters, metrics, or logs: operation count, byte count, rows/items processed, cache hits/misses, per-operation max/median duration, and lock wait/hold time.
  • Prefer inclusive stacks to understand which subsystem owns time, then self frames to find tight loops.
  • Look for repeated work: allocation, parsing, cloning, serialization/deserialization, expression evaluation, decompression, canonicalization, redundant I/O, and synchronization overhead.
  • If profile output only shows addresses and symbolication is blocked by a UUID mismatch, you can still use thread CPU, stack repetition, and library ownership, but re-profile before making a code-level claim.

Reporting

Summaries should include:

  • timing command and profile command;
  • command for the user to open the profile, usually samply load <profile.json.gz>;
  • branch, binary, and profile used;
  • before/after timings or run IDs;
  • top hot threads/functions/stacks;
  • confirmed facts versus inferences;
  • checks run and checks skipped.

© vortex-data, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 4 other files (scripts) in .agents/skills/samply of vortex-data/vortex.

  • SKILL.md
  • agents/openai.yaml
  • scripts/profile_activity.py
  • scripts/profile_inverted_tree.py
  • scripts/profile_summary.py

Open the folder on GitHubat commit d9ad4cf

Compare with similar skills

Samply next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Samply compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Samply this skillvortex-data/vortex3.2k—~2.7kAutomated safety check: PassApache-2.0
Pyroscopegrafana/skills278—~1.2kAutomated safety check: PassApache-2.0
Fory Performance Optimizationapache/fory4.6k—~2.2kAutomated safety check: PassApache-2.0
Code Review ChecklistshareAI-lab/learn-claude-code78k5 repos~1.1kAutomated safety check: PassMIT
Pycrazyguitar/pysheeet8.2k—~886Automated safety check: PassMIT
Release Skillsnexmoe/eve4213 repos~3.3kAutomated safety check: PassNone

Similar skills

  • Pyroscope

    grafana/skills

    Official

    Continuously profile applications with Grafana Pyroscope and read the result as flame graphs.

    278 GitHub stars~1.2k tokensUpdated yesterday
    DevOps & CloudAuto-check passed
  • Run profile-driven bottleneck optimization across Apache Fory implementations (Java, C++, Python/Cython, Go, Rust, Swift, C, JavaScript/TypeScript, Dart, Kotlin, Scala).

    4.6k GitHub stars~2.2k tokensUpdated today
    MobileAuto-check passed
  • Code Review Checklist

    shareAI-lab/learn-claude-code

    Reviews code against a five-part checklist covering security, correctness, performance, maintainability and testing, and reports findings in a fixed format.

    78k GitHub starsUsed in 5 repos~1.1k tokens
    DevelopmentAuto-check passed
  • Py

    crazyguitar/pysheeet

    Comprehensive Python programming reference covering syntax, concurrency, networking, databases, ML/LLM development, and HPC.

    8.2k GitHub stars~886 tokensUpdated yesterday
    DevelopmentAuto-check passed
  • Release Skills

    nexmoe/eve

    Universal release workflow. An agent skill from nexmoe/eve.

    421 GitHub starsUsed in 3 repos~3.3k tokens
    DevelopmentAuto-check passed
  • RustPython C-API Expansion

    RustPython/RustPython

    Implements missing CPython C-API functions in RustPython's crates/capi, mapping each header to its module with the pyo3-ffi header split.

    22k GitHub stars~831 tokensUpdated today
    DevelopmentAuto-check passed

More from vortex-data/vortex

  • Bench Performance

    vortex-data/vortex

    Iterate on Vortex vx-bench query performance with benchmark comparisons, engine-specific benchmark flags, RUSTLOG/tracing/metrics/explain output, and Samply profiles.

    3.2k GitHub stars~5.1k tokensUpdated today
    Auto-check passed
  • CI Failure Analysis

    vortex-data/vortex

    Analyze Vortex GitHub Actions CI failures. An agent skill from vortex-data/vortex.

    3.2k GitHub stars~810 tokensUpdated today
    Auto-check passed

Works with

Categories

Questions about Samply

What does Samply do?

Analyze Samply Firefox-profiler output, record focused profiles, summarize hot threads/stacks, inspect symbolication, and compare profile evidence before and after a performance change. Samply is an agent skill from vortex-data/vortex. Analyze Samply Firefox-profiler output, record focused profiles, summarize hot threads/stacks, inspect symbolication, and compare profile evidence before and after a performance change.

When should I use Samply?

Samply fits situations like: tasks that involve Performance optimization.

How do I install Samply in Claude Code?

Run `npx skills add vortex-data/vortex --skill samply -a claude-code`. Or copy the skill folder (.agents/skills/samply in vortex-data/vortex) into .claude/skills/samply in your project. Claude Code loads it when a task matches its description.

How do I install Samply in Codex?

Run `npx skills add vortex-data/vortex --skill samply -a codex`. Or copy the skill folder (.agents/skills/samply in vortex-data/vortex) into .agents/skills/samply in your project. Codex loads it when a task matches its description.

Can I use Samply in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add vortex-data/vortex --skill samply -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/samply, .gemini/skills/samply, .github/skills/samply and .opencode/skills/samply in your project.

What does Samply need to run?

Going by SKILL.md and its folder, Samply needs Python for the scripts in its folder and the command-line tools its instructions call (python3, git and jq). Our summary lists: Python 3.

Does Samply access the network?

SKILL.md contains no URLs. Its commands use git, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is Samply safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.

What licence does Samply use?

Samply is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Samply use?

About 2.7k tokens (SKILL.md is roughly 11k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Samply?

Skills that share tags, products or a category with Samply: Pyroscope (grafana/skills, 278 stars), Fory Performance Optimization (apache/fory, 4.6k stars), Code Review Checklist (shareAI-lab/learn-claude-code, 78k stars) and Py (crazyguitar/pysheeet, 8.2k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Samply?

vortex-data (a GitHub organization) maintains it in vortex-data/vortex, which has 3,248 GitHub stars. The repository holds 3 skills in this directory. The repository was last updated on October 7, 2026.

Source: vortex-data/vortex on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.