
Multi Agent Performance Profiling
- 117 installs
- 62 repo stars
- Updated August 3, 2026
- terrylica/cc-skills
Use multi-agent-performance-profiling for development tasks
About
multi-agent-performance-profiling: A skill for development. This provides functionality for development workflows.
- multi-agent-performance-profiling
Multi Agent Performance Profiling by the numbers
- 117 all-time installs (skills.sh)
- Ranked #2,871 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/terrylica/cc-skills --skill multi-agent-performance-profilingAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 117 |
|---|---|
| repo stars | ★ 62 |
| Last updated | August 3, 2026 |
| Repository | terrylica/cc-skills ↗ |
What it does
Use multi-agent-performance-profiling for development tasks
Files
Multi-Agent Performance Profiling
Self-Evolving Skill: This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues.
Overview
Prescriptive workflow for spawning parallel profiling agents to comprehensively identify performance bottlenecks across multiple system layers. Successfully discovered that QuestDB ingests at 1.1M rows/sec (11x faster than target), proving database was NOT the bottleneck - CloudFront download was 90% of pipeline time.
When to Use This Skill
Use this skill when:
- Performance below SLO (e.g., 47K vs 100K rows/sec target)
- Multi-stage pipeline optimization (download → extract → parse → ingest)
- Database performance investigation
- Bottleneck identification in complex workflows
- Pre-optimization analysis (before making changes)
Key outcomes:
- Identify true bottleneck (vs assumed bottleneck)
- Quantify each stage's contribution to total time
- Prioritize optimizations by impact (P0/P1/P2)
- Avoid premature optimization of non-bottlenecks
Core Methodology
1. Multi-Layer Profiling Model (5-Agent Pattern)
Agent 1: Profiling (Instrumentation)
- Empirical timing of each pipeline stage
- Phase-boundary instrumentation with time.perf_counter()
- Memory profiling (peak usage, allocations)
- Bottleneck identification (% of total time)
Agent 2: Database Configuration Analysis
- Server settings review (WAL, heap, commit intervals)
- Production vs development config comparison
- Expected impact quantification (<5%, 10%, 50%)
Agent 3: Client Library Analysis
- API usage patterns (dataframe vs row-by-row)
- Buffer size tuning opportunities
- Auto-flush behavior analysis
Agent 4: Batch Size Analysis
- Current batch size validation
- Optimal batch range determination
- Memory overhead vs throughput tradeoff
Agent 5: Integration & Synthesis
- Consensus-building across agents
- Prioritization (P0/P1/P2) with impact quantification
- Implementation roadmap creation
2. Agent Orchestration Pattern
Parallel Execution (all 5 agents run simultaneously):
Agent 1 (Profiling) → [PARALLEL]
Agent 2 (DB Config) → [PARALLEL]
Agent 3 (Client Library) → [PARALLEL]
Agent 4 (Batch Size) → [PARALLEL]
Agent 5 (Integration) → [PARALLEL - reads tmp/ outputs from others]Key Principle: No dependencies between investigation agents (1-4). Integration agent synthesizes findings.
Dynamic Todo Management:
- Start with investigation plan (5 agents)
- Spawn agents in parallel using single message with multiple Task tool calls
- Update todos as each agent completes
- Integration agent waits for all findings before synthesizing
3. Profiling Script Structure
Each agent produces:
1. Investigation Script (e.g., profile_pipeline.py)
- time.perf_counter() instrumentation at phase boundaries
- Memory profiling with tracemalloc
- Structured output (phase, duration, % of total)
2. Report (markdown with findings, recommendations, impact quantification) 3. Evidence (benchmark results, config dumps, API traces)
Example Profiling Code:
import time
# Profile multi-stage pipeline
def profile_pipeline():
results = {}
# Phase 1: Download
start = time.perf_counter()
data = download_from_cdn(url)
results["download"] = time.perf_counter() - start
# Phase 2: Extract
start = time.perf_counter()
csv_data = extract_zip(data)
results["extract"] = time.perf_counter() - start
# Phase 3: Parse
start = time.perf_counter()
df = parse_csv(csv_data)
results["parse"] = time.perf_counter() - start
# Phase 4: Ingest
start = time.perf_counter()
ingest_to_db(df)
results["ingest"] = time.perf_counter() - start
# Analysis
total = sum(results.values())
for phase, duration in results.items():
pct = (duration / total) * 100
print(f"{phase}: {duration:.3f}s ({pct:.1f}%)")
return results4. Impact Quantification Framework
Priority Levels:
- P0 (Critical): >5x improvement, addresses primary bottleneck
- P1 (High): 2-5x improvement, secondary optimizations
- P2 (Medium): 1.2-2x improvement, quick wins
- P3 (Low): <1.2x improvement, minor tuning
Impact Reporting Format:
### Recommendation: [Optimization Name] (P0/P1/P2) - [IMPACT LEVEL]
**Impact**: 🔴/🟠/🟡 **Nx improvement**
**Effort**: High/Medium/Low (N days)
**Expected Improvement**: CurrentK → TargetK rows/sec
**Rationale**:
- [Why this matters]
- [Supporting evidence from profiling]
- [Comparison to alternatives]
**Implementation**:
[Code snippet or architecture description]5. Consensus-Building Pattern
Integration Agent Responsibilities:
1. Read all investigation reports (Agents 1-4) 2. Identify consensus recommendations (all agents agree) 3. Flag contradictions (agents disagree) 4. Synthesize master integration report 5. Create implementation roadmap (P0 → P1 → P2)
Consensus Criteria:
- ≥3/4 agents recommend same optimization → Consensus
- 2/4 agents recommend, 2/4 neutral → Investigate further
- Agents contradict (one says "optimize X", another says "X is not bottleneck") → Run tie-breaker experiment
Workflow: Step-by-Step
Step 1: Define Performance Problem
Input: Performance metric below SLO Output: Problem statement with baseline metrics
Example Problem Statement:
Performance Issue: BTCUSDT 1m ingestion at 47K rows/sec
Target SLO: >100K rows/sec
Gap: 53% below target
Pipeline: CloudFront download → ZIP extract → CSV parse → QuestDB ILP ingestStep 2: Create Investigation Plan
Directory Structure:
tmp/perf-optimization/
profiling/ # Agent 1
profile_pipeline.py
PROFILING_REPORT.md
questdb-config/ # Agent 2
CONFIG_ANALYSIS.md
python-client/ # Agent 3
CLIENT_ANALYSIS.md
batch-size/ # Agent 4
BATCH_ANALYSIS.md
MASTER_INTEGRATION_REPORT.md # Agent 5Agent Assignment:
- Agent 1: Empirical profiling (instrumentation)
- Agent 2: Database configuration analysis
- Agent 3: Client library usage analysis
- Agent 4: Batch size optimization analysis
- Agent 5: Synthesis and integration
Step 3: Spawn Agents in Parallel
IMPORTANT: Use single message with multiple Task tool calls for true parallelism
Example:
I'm going to spawn 5 parallel investigation agents:
[Uses Task tool 5 times in a single message]
- Agent 1: Profiling
- Agent 2: QuestDB Config
- Agent 3: Python Client
- Agent 4: Batch Size
- Agent 5: Integration (depends on others completing)Execution:
# All agents run simultaneously (user observes 5 parallel tool calls)
# Each agent writes to its own tmp/ subdirectory
# Integration agent polls for completed reportsStep 4: Wait for All Agents to Complete
Progress Tracking:
- Update todo list as each agent completes
- Integration agent polls tmp/ directory for report files
- Once 4/4 investigation reports exist → Integration agent synthesizes
Completion Criteria:
- All 4 investigation reports written
- Integration report synthesizes findings
- Master recommendations list created
Step 5: Review Master Integration Report
Report Structure:
# Master Performance Optimization Integration Report
## Executive Summary
- Critical discovery (what is/isn't the bottleneck)
- Key findings from each agent (1-sentence summary)
## Top 3 Recommendations (Consensus)
1. [P0 Optimization] - HIGHEST IMPACT
2. [P1 Optimization] - HIGH IMPACT
3. [P2 Optimization] - QUICK WIN
## Agent Investigation Summary
### Agent 1: Profiling
### Agent 2: Database Config
### Agent 3: Client Library
### Agent 4: Batch Size
## Implementation Roadmap
### Phase 1: P0 Optimizations (Week 1)
### Phase 2: P1 Optimizations (Week 2)
### Phase 3: P2 Quick Wins (As time permits)Step 6: Implement Optimizations (P0 First)
For each recommendation:
1. Implement highest-priority optimization (P0) 2. Re-run profiling script 3. Verify expected improvement achieved 4. Update report with actual results 5. Move to next priority (P1, P2, P3)
Example Implementation:
# Before optimization
uv run python tmp/perf-optimization/profiling/profile_pipeline.py
# Output: 47K rows/sec, download=857ms (90%)
# Implement P0 recommendation (concurrent downloads)
# [Make code changes]
# After optimization
uv run python tmp/perf-optimization/profiling/profile_pipeline.py
# Output: 450K rows/sec, download=90ms per symbol * 10 concurrent (90%)Real-World Example: QuestDB Refactor Performance Investigation
Context: Pipeline achieving 47K rows/sec, target 100K rows/sec (53% below SLO)
Assumptions Before Investigation:
- QuestDB ILP ingestion is the bottleneck (4% of time)
- Need to tune database configuration
- Need to optimize Sender API usage
Findings After 5-Agent Investigation:
1. Profiling Agent: CloudFront download is 90% of time (857ms), ILP ingest only 4% (40ms) 2. QuestDB Config Agent: Database already optimal, tuning provides <5% improvement 3. Python Client Agent: Sender API already optimal (using dataframe() bulk ingestion) 4. Batch Size Agent: 44K batch size is within optimal range 5. Integration Agent: Consensus recommendation - optimize download, NOT database
Top 3 Recommendations:
1. 🔴 P0: Concurrent multi-symbol downloads (10-20x improvement) 2. 🟠 P1: Multi-month pipeline parallelism (2x improvement) 3. 🟡 P2: Streaming ZIP extraction (1.3x improvement)
Impact: Discovered database ingests at 1.1M rows/sec (11x faster than target) - proving database was never the bottleneck
Outcome: Avoided wasting 2-3 weeks optimizing database when download was the real bottleneck
Common Pitfalls
1. Profiling Only One Layer
❌ Bad: Profile database only, assume it's the bottleneck ✅ Good: Profile entire pipeline (download → extract → parse → ingest)
2. Serial Agent Execution
❌ Bad: Run Agent 1, wait, then run Agent 2, wait, etc. ✅ Good: Spawn all 5 agents in parallel using single message with multiple Task calls
3. Optimizing Without Profiling
❌ Bad: "Let's optimize the database config first" (assumption-driven) ✅ Good: Profile first, discover database is only 4% of time, optimize download instead
4. Ignoring Low-Hanging Fruit
❌ Bad: Only implement P0 (highest impact, highest effort) ✅ Good: Implement P2 quick wins (1.3x for 4-8 hours effort) while planning P0
5. Not Re-Profiling After Changes
❌ Bad: Implement optimization, assume it worked ✅ Good: Re-run profiling script, verify expected improvement achieved
Resources
scripts/
Not applicable - profiling scripts are project-specific (stored in tmp/perf-optimization/)
references/
profiling_template.py- Template for phase-boundary instrumentationintegration_report_template.md- Template for master integration reportimpact_quantification_guide.md- How to assess P0/P1/P2 priorities
assets/
Not applicable - profiling artifacts are project-specific
---
Troubleshooting
| Issue | Cause | Solution |
|---|---|---|
| Agents running sequentially | Using separate messages | Spawn all agents in single message with multi-Task |
| Integration report empty | Agent reports not written | Wait for all 4 investigation agents to complete |
| Wrong bottleneck identified | Single-layer profiling | Profile entire pipeline, not just assumed layer |
| Profiling results vary | No warmup runs | Run 3-5 warmup iterations before measuring |
| Memory not profiled | Missing tracemalloc | Add tracemalloc instrumentation to profiling script |
| P0/P1 priority unclear | No impact quantification | Include expected Nx improvement for each finding |
| Consensus missing | Agents not compared | Integration agent must synthesize all 4 reports |
| Re-profile shows no change | Caching effects | Clear caches, restart services before re-profiling |
Post-Execution Reflection
After this skill completes, reflect before closing the task:
0. Locate yourself. — Find this SKILL.md's canonical path before editing. 1. What failed? — Fix the instruction that caused it. 2. What worked better than expected? — Promote to recommended practice. 3. What drifted? — Fix any script, reference, or dependency that no longer matches reality. 4. Log it. — Evolution-log entry with trigger, fix, and evidence.
Do NOT defer. The next invocation inherits whatever you leave behind.
Evolution Log
Convention: Reverse chronological order (newest on top, oldest at bottom). Prepend new entries.
---
2026-02-26: Initial Evolution Log
Status: Skill is in use and maintained. Track improvements here.
Purpose
This evolution log tracks updates to the skill. Each entry should note:
- What changed (content, structure, tooling)
- Why it changed (bug fix, feature request, best practice)
- Files affected
How to Use
1. When updating SKILL.md or references, add an entry here with the date 2. Keep entries reverse-chronological (newest first) 3. Link to ADRs or GitHub issues when relevant 4. Reference specific line changes when helpful
---
Skill: Multi-Agent Performance Profiling
Impact Quantification Guide
How to Assess P0/P1/P2/P3 Priorities
---
Priority Framework
P0 (Critical Priority) - HIGHEST IMPACT
Criteria:
- Improvement: >5x performance gain
- Bottleneck: Addresses primary bottleneck (>50% of total time)
- ROI: High impact despite high effort
- Risk: Acceptable risk/reward ratio
Examples:
- Concurrent downloads (10-20x improvement, 90% bottleneck)
- Algorithm replacement (O(n²) → O(n log n) for large n)
- Caching layer for frequently accessed data (10x+ improvement)
Decision Matrix:
| Improvement | Effort | Priority | Implement? |
|---|---|---|---|
| 10x | 2 weeks | P0 | ✅ YES |
| 5x | 1 week | P0 | ✅ YES |
| 3x | 3 weeks | P1 | ⚠️ MAYBE (effort too high) |
---
P1 (High Priority) - HIGH IMPACT
Criteria:
- Improvement: 2-5x performance gain
- Bottleneck: Addresses secondary bottleneck (20-50% of time)
- ROI: Medium-high impact, medium effort
- Risk: Low to medium risk
Examples:
- Pipeline parallelism (2x improvement by overlapping download + ingest)
- Index optimization in database (2-3x query improvement)
- Memory allocation tuning (2x improvement in GC overhead)
Decision Matrix:
| Improvement | Effort | Priority | Implement? |
|---|---|---|---|
| 5x | 1 week | P0 | ✅ YES (upgrade to P0) |
| 3x | 1 week | P1 | ✅ YES |
| 2x | 2 weeks | P1 | ⚠️ MAYBE |
| 2x | 1 day | P0/P1 | ✅ YES (quick win, high impact) |
---
P2 (Medium Priority) - QUICK WINS
Criteria:
- Improvement: 1.2-2x performance gain
- Bottleneck: May not address primary bottleneck
- ROI: Low effort, measurable impact
- Risk: Very low risk
Examples:
- Streaming ZIP extraction (1.3x improvement, 4-8 hours effort)
- Connection pooling (1.5x improvement for high-frequency requests)
- Buffer size tuning (1.2-1.5x improvement)
Decision Matrix:
| Improvement | Effort | Priority | Implement? |
|---|---|---|---|
| 1.5x | 4 hours | P2 | ✅ YES (quick win) |
| 1.3x | 8 hours | P2 | ✅ YES (if time permits) |
| 1.2x | 2 days | P3 | ⚠️ MAYBE (effort too high for low impact) |
---
P3 (Low Priority) - MINOR TUNING
Criteria:
- Improvement: <1.2x performance gain
- Bottleneck: Does not address primary bottleneck
- ROI: Low impact, any effort level
- Risk: Low risk but also low value
Examples:
- Logging verbosity reduction (1.05x improvement)
- String concatenation optimization (1.1x improvement)
- Minor config parameter tuning (<5% improvement)
Decision Matrix:
| Improvement | Effort | Priority | Implement? |
|---|---|---|---|
| 1.1x | 1 hour | P3 | ⚠️ MAYBE (if trivial) |
| 1.05x | 1 day | P3 | ❌ NO (not worth effort) |
---
Calculating Impact
1. Measure Baseline
# Run profiling 3+ times, average results
baseline_time = 952 # ms (average of 3 runs)
baseline_throughput = 47_000 # rows/sec2. Estimate Optimized Performance
Method A: Phase Elimination (if removing bottleneck entirely)
# If download is 857ms (90% of 952ms total):
optimized_time = 952 - 857 + estimated_new_download_time
# e.g., if concurrent downloads reduce to 90ms:
optimized_time = 952 - 857 + 90 = 185ms
improvement = baseline_time / optimized_time
# 952 / 185 = 5.1x improvementMethod B: Phase Acceleration (if speeding up bottleneck)
# If download is 857ms and we can do 10 concurrent:
new_download_time = 857 / 10 = 86ms # (assuming perfect parallelism)
optimized_time = 952 - 857 + 86 = 181ms
improvement = 952 / 181 = 5.3x improvementMethod C: Amdahl's Law (for partial parallelization)
# If 90% of time is parallelizable with 10 workers:
speedup = 1 / ((1 - 0.9) + (0.9 / 10))
# speedup = 1 / (0.1 + 0.09) = 5.26x improvement3. Assign Priority
if improvement >= 5.0:
priority = "P0"
elif improvement >= 2.0:
priority = "P1"
elif improvement >= 1.2:
priority = "P2"
else:
priority = "P3"
# Adjust based on effort:
if effort_days > 10 and improvement < 10:
priority = downgrade(priority) # P0 → P1, P1 → P2, etc.---
Real-World Examples
Example 1: Concurrent Downloads (P0)
Baseline: 857ms download, 952ms total Optimization: 10 concurrent downloads Estimated: 857ms / 10 = 86ms per download (parallelized) New Total: 952 - 857 + 86 = 181ms Improvement: 952 / 181 = 5.3x ← P0 (>5x) Effort: 1-2 weeks (medium) Decision: ✅ P0 - Implement immediately
---
Example 2: Pipeline Parallelism (P1)
Baseline: 952ms total (download → extract → parse → ingest) Optimization: Overlap download(month N+1) with ingest(month N) Estimated: Save 850ms per month (out of ~1900ms for 2 months serial) New Total: 1900ms → 1050ms (for 2 months) Improvement: 1900 / 1050 = 1.8x per month ← P1 (approaching 2x) Effort: 1 week (medium) Decision: ✅ P1 - Implement after P0
---
Example 3: Streaming ZIP Extraction (P2)
Baseline: 11ms extraction (disk I/O), 952ms total Optimization: In-memory extraction (eliminate 3 disk I/O operations) Estimated: 11ms → 2ms (5x faster extraction) New Total: 952 - 11 + 2 = 943ms Improvement: 952 / 943 = 1.01x ← Wait, this is P3!
Re-analysis: Actually, eliminates disk I/O overhead across entire pipeline, not just extraction phase. Real savings: ~50ms (extraction + CSV write/read overhead) New Total: 952 - 50 = 902ms Improvement: 952 / 902 = 1.06x ← Still P3
BUT: Effort is only 4-8 hours (very low) Adjusted Priority: ✅ P2 - Quick win (despite low impact, trivial effort)
---
Decision Tree
START
|
Is improvement ≥5x?
/ \
YES NO
| |
P0 Is improvement ≥2x?
/ \
YES NO
| |
P1 Is improvement ≥1.2x?
/ \
YES NO
| |
Is effort P3
<1 day?
/ \
YES NO
| |
P2 P3
THEN: Adjust based on effort
- If effort >10 days AND improvement <10x → downgrade
- If effort <1 day AND improvement >1.1x → upgrade to P2---
Common Mistakes
Mistake 1: Optimizing Non-Bottleneck
❌ Bad: "Let's optimize the database (4% of time) to get 2x improvement"
- Real improvement: 952ms → 932ms (952 - 20ms savings) = 1.02x (not 2x!)
- Lesson: 2x improvement on 4% of time = 0.02x overall improvement
✅ Good: Optimize the 90% bottleneck first
Mistake 2: Ignoring Effort
❌ Bad: "This 10x improvement is P0, even though it takes 6 months"
- Real cost: 6 months of engineering time
- Lesson: Consider ROI (return on investment)
✅ Good: Prioritize high-impact, reasonable-effort optimizations first
Mistake 3: Overestimating Parallelism
❌ Bad: "10 workers = 10x improvement"
- Real improvement: Amdahl's Law limits parallelism
- Serial overhead (10%) + parallel portion (90% / 10 workers) = 5.3x (not 10x)
✅ Good: Use Amdahl's Law to estimate realistic parallelism gains
---
Validation Checklist
Before assigning priority, verify:
- [ ] Profiling data is accurate (3+ runs, consistent results)
- [ ] Improvement calculation accounts for Amdahl's Law (if parallelizing)
- [ ] Effort estimate includes testing, documentation, code review
- [ ] Risk assessment considers backward compatibility, data integrity
- [ ] Priority assignment uses decision tree consistently
- [ ] Consensus across multiple investigation agents (for multi-agent workflows)
Skill: Multi-Agent Performance Profiling
Master Performance Optimization Integration Report
[Project Name] - [Feature/Refactor Name]
Date: YYYY-MM-DD Integration Agent: Complete Synthesis Status: ✅ Ready for Implementation
---
Executive Summary
Critical Discovery
[One-sentence statement of what IS or ISN'T the bottleneck - surprise finding]
Example: QuestDB ILP ingestion is NOT the bottleneck. The system achieves 1.1M rows/sec for pure database ingestion, which is 11x faster than the 100K rows/sec target.
The reported "[Current throughput]" pipeline throughput includes:
- X% [Phase Name] (Xms)
- Y% [Phase Name] (Yms)
- Z% [Phase Name] (Zms)
Key Findings from All Investigation Agents
1. Profiling Agent
- [Primary finding - what takes most time]
- [Quantified performance: Xms for Y rows = Z rows/sec]
- [CPU/memory observations]
2. [Database/Server] Config Agent
- [Current configuration assessment]
- [Production tuning available vs development]
- [Expected improvement percentage]
3. [Client/Library] Agent
- [API usage pattern assessment]
- [Optimization opportunities]
- [Configuration recommendations]
4. [Batch/Size/Algorithm] Agent
- [Current approach assessment]
- [Optimal parameters determination]
- [Tradeoff analysis]
5. Integration Agent (This Report)
- Primary bottleneck: [Phase Name] (Xms, Y% of time)
- Primary solution: [Recommendation] (Nx improvement)
- Secondary solution: [Recommendation] (Nx improvement)
- Quick win: [Recommendation] (Nx improvement)
---
Top 3 Recommendations (Consensus)
All investigation agents agree on these priorities:
1. [Optimization Name] (P0) - HIGHEST IMPACT
Impact: 🔴 Nx improvement Effort: High/Medium/Low (N days) Expected Improvement: [Current] → [Target] [metric]
Rationale:
- [Why this is the primary bottleneck]
- [Supporting evidence from profiling]
- [Why this is feasible/safe to implement]
- [Memory/complexity tradeoffs]
Implementation:
# Pseudocode or architecture description
from concurrent.futures import ThreadPoolExecutor
def optimized_approach():
# Implementation details
passRisks/Considerations:
- [Risk 1 and mitigation]
- [Risk 2 and mitigation]
---
2. [Optimization Name] (P1) - HIGH IMPACT
Impact: 🟠 Nx improvement Effort: High/Medium/Low (N days) Expected Improvement: [Current] → [Target] [metric]
Rationale:
- [Why this is secondary priority]
- [Supporting evidence]
- [Comparison to P0]
Implementation: [Description or pseudocode]
---
3. [Optimization Name] (P2) - QUICK WIN
Impact: 🟡 Nx improvement Effort: High/Medium/Low (N hours) Expected Improvement: [Current] → [Target] [metric]
Rationale:
- [Why this is a quick win]
- [Low effort, medium impact]
- [Can be done in parallel with P0/P1]
Implementation: [Description or pseudocode]
---
Agent Investigation Summary
Profiling Agent Findings
Location: tmp/perf-optimization/profiling/
Key Results:
- [Phase 1]: Xms (Y% of total)
- [Phase 2]: Xms (Y% of total)
- [Phase 3]: Xms (Y% of total)
- [Phase 4]: Xms (Y% of total)
Recommendation: [One-sentence summary of profiling agent's primary recommendation]
Evidence:
- Benchmark runs: [Number of iterations, consistency of results]
- Throughput: [Current rows/sec, target rows/sec]
- Memory usage: [Peak, average]
---
[Database/Server] Config Agent Findings
Location: tmp/perf-optimization/[config-type]/
Key Results:
- Current config: [Description of current settings]
- Production config: [Description of optimal settings]
- Expected improvement: <X% (worth it? yes/no)
Recommendation: [One-sentence summary]
Supporting Evidence:
- [Config parameter 1]: [Current value] → [Recommended value] = [Impact]
- [Config parameter 2]: [Current value] → [Recommended value] = [Impact]
---
[Client/Library] Agent Findings
Location: tmp/perf-optimization/[client-type]/
Key Results:
- Current API usage: [Description - e.g., "using dataframe() bulk ingestion"]
- Alternative approaches: [List of alternatives considered]
- Expected improvement: <X% (worth it? yes/no)
Recommendation: [One-sentence summary]
---
[Batch/Size/Algorithm] Agent Findings
Location: tmp/perf-optimization/[analysis-type]/
Key Results:
- Current batch size: [X rows/items]
- Optimal range: [Y-Z rows/items]
- Memory overhead: [MB per batch]
- Expected improvement: <X% (current is already optimal? yes/no)
Recommendation: [One-sentence summary]
---
Consensus Analysis
Areas of Agreement (All Agents)
1. Primary Bottleneck: [X/4 agents] agree that [Phase Name] is the bottleneck 2. Recommended Optimization: [X/4 agents] recommend [Optimization Name] 3. Expected Impact: Consensus on [Nx] improvement potential
Areas of Disagreement
[If any agents contradict each other, document here. Otherwise state "None - all agents in consensus"]
Example disagreement:
- Agent 2 recommends database config tuning (+50% improvement)
- Agent 1 profiling shows database is only 4% of time
- Resolution: Profiling agent's empirical evidence takes priority
---
Implementation Roadmap
Phase 1: P0 Optimizations (Week 1-2)
- [ ] Implement [P0 Optimization Name]
- [ ] Re-run profiling to verify [Nx] improvement achieved
- [ ] Update benchmarks and documentation
Success Criteria: Achieve [Target metric] or better
---
Phase 2: P1 Optimizations (Week 3-4)
- [ ] Implement [P1 Optimization Name]
- [ ] Re-run profiling to verify [Nx] improvement achieved
- [ ] Update benchmarks
Success Criteria: Achieve [Target metric] or better
---
Phase 3: P2 Quick Wins (As time permits)
- [ ] Implement [P2 Optimization Name]
- [ ] Re-run profiling to verify [Nx] improvement achieved
Success Criteria: Any measurable improvement (>1.2x)
---
Risk Assessment
| Risk | Likelihood | Impact | Mitigation |
|---|---|---|---|
| [Risk 1] | High/Med/Low | High/Med/Low | [Mitigation strategy] |
| [Risk 2] | High/Med/Low | High/Med/Low | [Mitigation strategy] |
---
Validation Plan
Before Optimization:
# Baseline profiling
uv run python tmp/perf-optimization/profiling/profile_pipeline.py
# Expected output: [Current metric]After Each Optimization:
# Re-run profiling
uv run python tmp/perf-optimization/profiling/profile_pipeline.py
# Verify: [Expected metric after P0/P1/P2]Acceptance Criteria:
- P0 implemented → Achieve [X metric] (Nx improvement)
- P1 implemented → Achieve [Y metric] (Nx improvement)
- P2 implemented → Achieve [Z metric] (Nx improvement)
---
Appendices
Appendix A: Full Profiling Results
[Link to or inline profiling data]
Appendix B: Configuration Recommendations
[Link to or inline config recommendations]
Appendix C: Alternative Approaches Considered
[List of approaches considered but rejected, with rationale]
#!/usr/bin/env python3
"""
Performance Profiling Template - Phase-Boundary Instrumentation
Use this template for profiling multi-stage pipelines with time.perf_counter()
at phase boundaries to identify bottlenecks.
"""
import time
import tracemalloc
from typing import Dict
def profile_pipeline_example():
"""
Example profiling function for multi-stage data pipeline.
Adapt this template to your pipeline by:
1. Replace phase names (download, extract, parse, ingest)
2. Replace function calls with your actual operations
3. Add/remove phases as needed
4. Run 3+ times and average results for accuracy
"""
results: dict[str, float] = {}
# Optional: Track memory usage
tracemalloc.start()
mem_start = tracemalloc.get_traced_memory()[0] / 1024 / 1024 # MB
print("=" * 80)
print("PERFORMANCE PROFILING")
print("=" * 80)
# Phase 1: Download
print("\n[Phase 1: Download]")
start = time.perf_counter()
# ↓ Replace with your download operation
data = download_data_from_source()
# ↑
duration = time.perf_counter() - start
results["download"] = duration
print(f" Duration: {duration:.3f}s")
# Phase 2: Extract/Decompress
print("\n[Phase 2: Extract]")
start = time.perf_counter()
# ↓ Replace with your extraction operation
extracted_data = extract_or_decompress(data)
# ↑
duration = time.perf_counter() - start
results["extract"] = duration
print(f" Duration: {duration:.3f}s")
# Phase 3: Parse/Transform
print("\n[Phase 3: Parse]")
start = time.perf_counter()
# ↓ Replace with your parsing operation
parsed_data = parse_and_transform(extracted_data)
# ↑
duration = time.perf_counter() - start
results["parse"] = duration
print(f" Duration: {duration:.3f}s")
# Phase 4: Write/Ingest
print("\n[Phase 4: Ingest]")
start = time.perf_counter()
# ↓ Replace with your ingestion operation
row_count = ingest_to_database(parsed_data)
# ↑
duration = time.perf_counter() - start
results["ingest"] = duration
print(f" Duration: {duration:.3f}s")
print(f" Rows processed: {row_count:,}")
# Memory tracking (optional)
mem_end = tracemalloc.get_traced_memory()[0] / 1024 / 1024 # MB
mem_peak = tracemalloc.get_traced_memory()[1] / 1024 / 1024 # MB
tracemalloc.stop()
# Analysis
print("\n" + "=" * 80)
print("ANALYSIS")
print("=" * 80)
total_time = sum(results.values())
print(f"\nTotal Duration: {total_time:.3f}s")
print(f"Throughput: {row_count / total_time:,.0f} rows/sec")
print("\nPhase Breakdown:")
print(f"{'Phase':<20} {'Duration (s)':<15} {'% of Total':<15} {'Bottleneck?'}")
print("-" * 70)
# Sort by duration (descending) to identify bottleneck
sorted_phases = sorted(results.items(), key=lambda x: x[1], reverse=True)
for phase, duration in sorted_phases:
pct = (duration / total_time) * 100
is_bottleneck = "🔴 YES" if pct > 50 else ("🟡 MAYBE" if pct > 20 else "")
print(f"{phase:<20} {duration:<15.3f} {pct:<15.1f} {is_bottleneck}")
print("\nMemory Usage:")
print(f" Start: {mem_start:.1f} MB")
print(f" End: {mem_end:.1f} MB")
print(f" Peak: {mem_peak:.1f} MB")
print(f" Delta: {mem_end - mem_start:.1f} MB")
# Recommendations
print("\n" + "=" * 80)
print("RECOMMENDATIONS")
print("=" * 80)
primary_bottleneck = sorted_phases[0]
if primary_bottleneck[1] / total_time > 0.5:
print(f"\n🔴 PRIMARY BOTTLENECK: {primary_bottleneck[0]}")
print(f" Accounts for {(primary_bottleneck[1] / total_time * 100):.1f}% of total time")
print(" Recommendation: Focus optimization efforts here first")
else:
print(f"\n🟡 NO SINGLE BOTTLENECK (largest phase: {primary_bottleneck[0]} at {(primary_bottleneck[1] / total_time * 100):.1f}%)")
print(" Recommendation: Optimize multiple phases or parallelize pipeline")
return results
# Placeholder functions - replace with your actual operations
def download_data_from_source():
"""Replace with your download logic."""
time.sleep(0.1) # Simulate download
return b"sample_data"
def extract_or_decompress(data):
"""Replace with your extraction logic."""
time.sleep(0.05) # Simulate extraction
return "extracted_data"
def parse_and_transform(data):
"""Replace with your parsing logic."""
time.sleep(0.05) # Simulate parsing
return [{"id": i, "value": i * 2} for i in range(1000)]
def ingest_to_database(data):
"""Replace with your ingestion logic."""
time.sleep(0.05) # Simulate ingestion
return len(data)
if __name__ == "__main__":
# Run profiling 3 times and average results
print("Running 3 profiling iterations...")
all_results = []
for iteration in range(3):
print(f"\n\nITERATION {iteration + 1}/3")
results = profile_pipeline_example()
all_results.append(results)
# Average results
print("\n\n" + "=" * 80)
print("AVERAGED RESULTS (3 iterations)")
print("=" * 80)
avg_results = {}
for phase in all_results[0].keys():
avg_results[phase] = sum(r[phase] for r in all_results) / len(all_results)
total_avg = sum(avg_results.values())
print(f"\n{'Phase':<20} {'Avg Duration (s)':<15} {'% of Total'}")
print("-" * 50)
for phase, duration in sorted(avg_results.items(), key=lambda x: x[1], reverse=True):
pct = (duration / total_avg) * 100
print(f"{phase:<20} {duration:<15.3f} {pct:.1f}%")