startup-profile
Captures a sampling flamegraph of application startup to isolate performance bottlenecks.
Install
mkdir -p .claude/skills/startup-profile && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/18173" && unzip -o skill.zip -d .claude/skills/startup-profile && rm skill.zipInstalls to .claude/skills/startup-profile
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Use when a uv-based Python app is slow to start — the first worker/log line takes several seconds, you want to see where launch time goes, or whether startup is blocked on imports, DNS/socket/TLS, an SMB share, or a credential subprocess (e.g. google-auth shelling out to gcloud). Captures a py-spy startup flamegraph and ranks the cost by bucket. Advisory: never edits source.Key capabilities
- →Capture a sampling profile of Python app startup
- →Rank startup cost by bucket
- →Identify blocking stalls like DNS/socket/TLS
- →Profile a specific application configuration
- →Compare startup costs across multiple worker configurations
- →Re-analyze existing profile data
How it works
The skill captures a py-spy startup flamegraph of a uv-based Python application and ranks the cost by bucket, focusing on active time by excluding idle event-loop and parked-thread waiting.
Inputs & outputs
When to use startup-profile
- →Debugging slow app startup
- →Identifying blocking network calls
- →Measuring import time overhead
About this skill
Startup Profile
Capture a sampling profile of python -m vspeech startup and rank where the
time goes, so blocking stalls (DNS/socket/TLS, SMB shares, credential
subprocesses) stand out from import and model-load cost. Advisory only — this
never edits source.
The headline is active time (total - idle): event-loop and parked-thread
waiting is bucketed as idle and excluded so the slack at the tail of a fixed
sampling window doesn't dilute the real stalls.
Procedure
Default to baseline. For any "startup is slow / where does launch time go?"
request — or to profile a single real config — run startup-profile (baseline)
and stop there. It is fast, environment-independent, and measures the
import/infra floor every config pays. Only run startup-sweep when the user
explicitly asks to break the cost down per worker ("which worker is
heaviest?", "compare the workers", "profile each worker") — it costs ~7× the
window and is environment-specific. When unsure, do baseline and offer the sweep.
- Confirm the working directory is a uv project (
pyproject.tomlexists). If not, say so and stop. - Capture + analyze (the orchestrator lives at
scripts/startup_capture.py, wired as[tool.poe.tasks].startup-profile). Capture now auto-analyzes inline — one command both records and ranks the buckets:uv run poe startup-profile- Default = baseline. With no
--configthis profiles the bundled baseline (scripts/fixtures/baseline_startup.toml): every optional worker disabled, only the always-on gRPCsender/receiverrun. That is the pure import/infra floor every configuration pays. - Profile a real config:
uv run poe startup-profile --config <path>. - Tune the window:
... --duration 20(default 30s).--nativeadds native frames;--ratechanges sample Hz;--topsets frames listed. - Writes
<stamp>-<label>.speedscope.json+.logto./.startup-profiles/(gitignored).
- Default = baseline. With no
- Sweep (opt-in — run only when asked to break startup cost down per
worker; wired as
[tool.poe.tasks].startup-sweep):uv run poe startup-sweep- Profiles the baseline plus one single-worker config per optional worker
(
scripts/fixtures/sweep/: recording, transcription, subtitle, translation, tts, playback), auto-analyzing each, then prints a comparison table of active time by config (sorted heaviest first). Subtract the baseline row to isolate each worker's own startup cost. vcis excluded: its torch + CUDA model load dwarfs the window and needs real RVC model assets (model_file/hubert_model_file/rmvpe_model_file) to start at all. Measure it ad hoc with--config.- The window applies per config, so a sweep takes ~7 ×
--duration. Use a short window (e.g.... --duration 12) for a quick comparison. - Sweep fixtures are environment-specific by nature: recording/playback need
audio devices, transcription(GCP)/translation need google credentials (and
show the
gcloudcredential-subprocess stall), tts(VR2) needs VOICEROID2. A config whose assets are absent exits early — still a valid data point (its capture window is short and the analysis shows how far it got).
- Profiles the baseline plus one single-worker config per optional worker
(
- Re-analyze an existing profile if needed (
scripts/startup_analyze.py, wired asstartup-analyze):uv run poe startup-analyze --input .startup-profiles/<stamp>-<label>.speedscope.json--jsonfor machine-readable output;--top 30for more rows.
- Interpret the buckets (percentages are of active time):
- blocking-io → the actionable stalls: DNS/socket/TLS,
\\host\share(SMB/UNC) paths, or waiting on a credential subprocess. Remove these first. - import → module-load cost (cold disk cache / AV scanning / heavy deps like grpc, torch, faster_whisper).
- compute → model loading.
- idle → event-loop / parked-thread waiting; reported separately and excluded from the active headline.
- blocking-io → the actionable stalls: DNS/socket/TLS,
- Present the top frames with
file:line, bucket, and self-time, plus the bucket split (and the sweep comparison table, if run). This is input for the user's fix decision — do not edit code.
Notes
- py-spy runs via
uvx(no project dependency); the analyzer is pure stdlib. - Windows / uv gotcha: a uv
.venvships a trampolinepython.exe, not a CPython copy. py-spy can't identify it and fails withFailed to find python version from target process. The capture script passes--subprocessesso py-spy follows the trampoline into the real base interpreter it launches (and into credential helpers likegcloud). This is already baked in — don't drop it. --idleis on: Python releases the GIL during blocking I/O, so default on-CPU sampling would miss the very stalls this skill hunts. The analyzer'sidlebucket then removes the resulting event-loop-wait noise.- The baseline config disables every optional worker and the telemetry/log
network shares, so it isolates the import/infra floor with no devices,
credentials, or models. The
startup-sweepfixtures each turn on exactly one worker; thetranslation(and GCPtranscription) fixtures are what exercise the google-authgcloudcredential subprocess. Use--configfor a real one. - The speedscope JSON also opens at https://speedscope.app for a visual
flamegraph. See
references/speedscope-schema.mdfor the format and the bucket signature catalog.
Rules
- Advisory only. Never gates a launch and never edits source or config — it reports where startup time goes.
- A missing
uvx/py-spy is a SKIP with a message, not a failure. - py-spy reads only the
sampledspeedscope format. pyinstrument emitseventedspeedscope, which this analyzer does not parse.
When not to use it
- →When the user explicitly asks to break down cost per worker and startup-sweep is preferred
- →When the goal is to edit source code or configuration
- →For non-uv based Python applications
Limitations
- →The skill never edits source code or configuration files
- →It requires a uv project with a pyproject.toml file
- →vc (torch + CUDA model load) is excluded from sweep due to its large resource requirements
How it compares
This skill automatically analyzes and ranks startup costs into predefined buckets, providing actionable insights into blocking stalls, unlike manual profiling which requires interpreting raw flamegraph data.
Compared to similar skills
startup-profile side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| startup-profile (this skill) | 0 | 1mo | Review | Intermediate |
| python-performance-optimization | 27 | 2mo | No flags | Intermediate |
| optimizing-performance | 1 | 1mo | Review | Intermediate |
| codex-code-review | 1 | 7mo | Review | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
python-performance-optimization
wshobson
Profile and optimize Python code using cProfile, memory profilers, and performance best practices. Use when debugging slow Python code, optimizing bottlenecks, or improving application performance.
optimizing-performance
CloudAI-X
Analyzes and optimizes application performance across frontend, backend, and database layers. Use when diagnosing slowness, improving load times, optimizing queries, reducing bundle size, or when asked about performance issues.
codex-code-review
tyrchen
Perform comprehensive code reviews using OpenAI Codex CLI. This skill should be used when users request code reviews, want to analyze diffs/PRs, need security audits, performance analysis, or want automated code quality feedback. Supports reviewing staged changes, specific files, entire directories, or git diffs.
memory-optimization
benchflow-ai
Optimize Python code for reduced memory usage and improved memory efficiency. Use when asked to reduce memory footprint, fix memory leaks, optimize data structures for memory, handle large datasets efficiently, or diagnose memory issues. Covers object sizing, generator patterns, efficient data structures, and memory profiling strategies.
benchmark-kernel
flashinfer-ai
Guide for benchmarking FlashInfer kernels with CUPTI timing
python-performance-optimization
netbarros
Profile and optimize Python code using cProfile, memory profilers, and performance best practices. Use when debugging slow Python code, optimizing bottlenecks, or improving application performance.