performance skill
CLI performance optimization - startup time, memory usage, token savings benchmarking
Is the performance skill safe?
Clean: nothing in its files matched our rules. We read 1 file in the folder on 2026-11-10.
- low
SKILL.md:1The name should be 1 to 64 lowercase letters, digits or hyphens.
(missing)
Install the performance skill
A skill is a folder. Copy it into your agent's skills folder and the agent loads it when the task matches its description.
git clone --depth 1 https://github.com/rtk-ai/rtk.git /tmp/rtk mkdir -p ~/.claude/skills cp -r /tmp/rtk/.claude/skills/performance ~/.claude/skills/performance
In the Claude apps, zip the folder and upload it from the Skills settings. The folder on GitHub
The instructions your agent would load
SKILL.md as published, without the frontmatter. Read it on GitHub
Performance Optimization Skill
Systematic performance analysis and optimization for RTK CLI tool, focusing on startup time (<10ms), memory usage (<5MB), and token savings (≥20% floor).
When to Use
- Automatically triggered: After filter changes, regex modifications, or dependency additions
- Manual invocation: When performance degradation suspected or before release
- Proactive: After any code change that could impact startup time or memory
RTK Performance Targets
Performance Analysis Workflow
1. Establish Baseline
Before making any changes, capture current performance:
# Startup time baseline
hyperfine 'rtk git status' --warmup 3 --export-json /tmp/baseline_startup.json
# Memory usage baseline (macOS)
/usr/bin/time -l rtk git status 2>&1 | grep "maximum resident set size" > /tmp/baseline_memory.txt
# Memory usage baseline (Linux)
/usr/bin/time -v rtk git status 2>&1 | grep "Maximum resident set size" > /tmp/baseline_memory.txt
# Binary size baseline
ls -lh target/release/rtk | tee /tmp/baseline_binary_size.txt2. Make Changes
Implement optimization or feature changes.
3. Rebuild and Measure
# Rebuild with optimizations
cargo build --release
# Measure startup time
hyperfine 'target/release/rtk git status' --warmup 3 --export-json /tmp/after_startup.json
# Measure memory usage
/usr/bin/time -l target/release/rtk git status 2>&1 | grep "maximum resident set size" > /tmp/after_memory.txt
# Check binary size
ls -lh target/release/rtk | tee /tmp/after_binary_size.txt4. Compare Results
# Startup time comparison
hyperfine 'rtk git status' 'target/release/rtk git status' --warmup 3
# Example output:
# Benchmark 1: rtk git status
# Time (mean ± σ): 6.2 ms ± 0.3 ms [User: 4.1 ms, System: 1.8 ms]
# Benchmark 2: target/release/rtk git status
# Time (mean ± σ): 7.8 ms ± 0.4 ms [User: 5.2 ms, System: 2.1 ms]
#
# Summary
# 'rtk git status' ran 1.26 times faster than 'target/release/rtk git status'
# Memory comparison
diff /tmp/baseline_memory.txt /tmp/after_memory.txt
# Binary size comparison
diff /tmp/baseline_binary_size.txt /tmp/after_binary_size.txt5. Identify Regressions
Startup time regression (>15% increase or >2ms absolute):
# Profile with flamegraph
cargo install flamegraph
cargo flamegraph -- target/release/rtk git status
# Open flamegraph.svg
open flamegraph.svg
# Look for:
# - Repeated fixed-regex compilation (should be in LazyLock init)
# - Excessive allocations
# - File I/O on startup (should be zero)Memory regression (>20% increase or >1MB absolute):
# Profile allocations (requires nightly)
cargo +nightly build --release -Z build-std
RUSTFLAGS="-C link-arg=-fuse-ld=lld" cargo +nightly build --release
# Use DHAT for heap profiling
cargo install dhat
# Add to main.rs:
# #[global_allocator]
# static ALLOC: dhat::Alloc = dhat::Alloc;Token savings regression (<20% savings):
# Run token accuracy tests
cargo test test_token_savings
# Example failure output:
# Git log filter: expected ≥20% savings, got 52.3%
# Fix: Improve filter condensation logicCommon Performance Issues
Issue 1: Regex Recompilation
Symptom: Startup time >20ms, flamegraph shows regex compilation in hot path
Detection:
# Flamegraph shows Regex::new() calls during execution
cargo flamegraph -- target/release/rtk git log -10
# Check whether fixed patterns are compiled outside LazyLock staticsFix:
// ❌ WRONG: Recompiled on every call
fn filter_line(line: &str) -> Option<&str> {
let re = Regex::new(r"pattern").unwrap(); // RECOMPILED!
re.find(line).map(|m| m.as_str())
}
// ✅ RIGHT: Compiled once with LazyLock
use std::sync::LazyLock;
static LINE_PATTERN: LazyLock<Regex> =
LazyLock::new(|| Regex::new(r"pattern").unwrap());
fn filter_line(line: &str) -> Option<&str> {
LINE_PATTERN.find(line).map(|m| m.as_str())
}Issue 2: Excessive Allocations
Symptom: Memory usage >5MB, many small allocations in flamegraph
Detection:
# DHAT heap profiling
cargo +nightly build --release
valgrind --tool=dhat target/release/rtk git statusFix:
// ❌ WRONG: Allocates Vec for every line
fn filter_lines(input: &str) -> String {
input.lines()
.map(|line| line.to_string()) // Allocates String
.collect::<Vec<_>>()
.join("\n")
}
// ✅ RIGHT: Borrow slices, single allocation
fn filter_lines(input: &str) -> String {
input.lines()
.collect::<Vec<_>>() // Vec of &str (no String allocation)
.join("\n")
}Issue 3: Startup I/O
Symptom: Startup time varies wildly (5ms to 50ms), flamegraph shows file reads
Detection:
# strace on Linux
strace -c target/release/rtk git status 2>&1 | grep -E "open|read"
# dtrace on macOS (requires SIP disabled)
sudo dtrace -n 'syscall::open*:entry { @[execname] = count(); }' &
target/release/rtk git status
sudo pkill dtraceFix:
// ❌ WRONG: File I/O on startup
fn main() {
let config = load_config().unwrap(); // Reads ~/.config/rtk/config.toml
// ...
}
// ✅ RIGHT: Lazy config loading (only if needed)
fn main() {
// No I/O on startup
// Config loaded on-demand when first accessed
}Issue 4: Dependency Bloat
Symptom: Binary size >5MB, many unused dependencies in Cargo.toml
Detection:
# Analyze dependency tree
cargo tree
# Find heavy dependencies
cargo install cargo-bloat
cargo bloat --release --crates
# Example output:
# File .text Size Crate
# 0.5% 2.1% 42.3KB regex
# 0.4% 1.8% 36.1KB clap
# ...Fix:
# ❌ WRONG: Full feature set (bloat)
[dependencies]
clap = { version = "4", features = ["derive", "color", "suggestions"] }
# ✅ RIGHT: Minimal features
[dependencies]
clap = { version = "4", features = ["derive"], default-features = false }Optimization Techniques
Technique 1: LazyLock Initialization
Use case: Regex patterns, static configuration, one-time allocations
Implementation:
use regex::Regex;
use std::sync::LazyLock;
static COMMIT_HASH: LazyLock<Regex> =
LazyLock::new(|| Regex::new(r"[0-9a-f]{7,40}").unwrap());
static AUTHOR_LINE: LazyLock<Regex> =
LazyLock::new(|| Regex::new(r"^Author: (.+)$").unwrap());
static DATE_LINE: LazyLock<Regex> =
LazyLock::new(|| Regex::new(r"^Date: (.+)$").unwrap());
// Fixed regexes compile on first use and are then reusedImpact: ~5-10ms saved per regex pattern (if compiled at runtime)
Technique 2: Zero-Copy String Processing
Use case: Filter output without allocating intermediate Strings
Implementation:
// ❌ WRONG: Allocates String for every line
fn filter(input: &str) -> String {
input.lines()
.filter(|line| !line.is_empty())
.map(|line| line.to_string()) // Allocates!
.collect::<Vec<_>>()
.join("\n")
}
// ✅ RIGHT: Borrow slices, single final allocation
fn filter(input: &str) -> String {
input.lines()
.filter(|line| !line.is_empty())
.collect::<Vec<_>>() // Vec<&str> (no String alloc)
.join("\n") // Single allocation for joined result
}Impact: ~1-2MB memory saved, ~1-2ms startup saved
Technique 3: Minimal Dependencies
Use case: Reduce binary size and compile time
More skills from rtk-ai/rtk
- Acode-simplifierReview RTK Rust code for idiomatic simplification. Detects over-engineering, unnecessary allocations, verbose patterns. Applies Rust idioms without changing behavior.
- Adesign-patternsRust design patterns for RTK. Newtype, Builder, RAII, Trait Objects, State Machine. Applied to CLI filter modules. Use when designing new modules or refactoring existing ones.
- Aissue-triageIssue triage: audit open issues, categorize, detect duplicates, cross-ref PRs, risk assessment, post comments. Args: "all" for deep analysis of all, issue numbers to focus (e.g. "42 57"), "en"/"fr" for language, no arg = audit only in French.
- Apr-reviewBatch review des PRs RTK par ordre de complexité croissante (XS → S → M → L). Pour chaque PR : vérifie l'état (conflits, CLA, reviews), lit le diff complet, analyse le code en contexte, présente un résumé avec lien + taille + recommandation. Attend validation explicite avant tout merge. Poste des commentaires boldguy-adapt sur les PRs bloquées (conflit, CLA, CHANGES_REQUESTED). Args: "triage" pour lancer un triage complet avant la review. "from:<num>" pour reprendre à partir d'un numéro de PR spécifique.
- Apr-triagePR triage: audit open PRs, deep review selected ones, draft and post review comments. Args: "all" to review all, PR numbers to focus (e.g. "42 57"), "en"/"fr" for language, no arg = audit only in French.
- Arepo-recapGenerate a comprehensive repo recap (PRs, issues, releases) for sharing with team. Pass "en" or "fr" as argument for language (default fr).
- Drtk-tddEnforces TDD (Red-Green-Refactor) for Rust development. Auto-triggers on implementation, testing, refactoring, and bug fixing tasks. Provides Rust-idiomatic testing patterns with anyhow/thiserror, cfg(test), and Arrange-Act-Assert workflow.
- Artk-triageTriage complet RTK : exécute issue-triage + pr-triage en parallèle, puis croise les données pour détecter doubles couvertures, trous sécurité, P0 sans PR, et conflits internes. Sauvegarde dans claudedocs/RTK-YYYY-MM-DD.md. Args: "en"/"fr" pour la langue (défaut: fr), "save" pour forcer la sauvegarde.
- Fsecurity-guardianCLI security expert for RTK - command injection, shell escaping, hook security
- AshipBuild, commit, push & version bump workflow - automates the complete release cycle
- Atdd-rustTDD workflow for RTK filter development. Red-Green-Refactor with Rust idioms. Real fixtures, token savings assertions, snapshot tests with insta. Auto-triggers on new filter implementation.