Performance Profiling Agent
The Problem
N+1 queries hide in ORMs and only surface under load. Memory leaks creep in through unclosed connections. Goroutine leaks silently eat resources until the server crashes at 3 AM. Performance issues are invisible in development and catastrophic in production.
The Solution
Perf Profiler statically analyzes your code to detect N+1 query patterns, unclosed resources, and goroutine leaks. It finds the 2000ms endpoint hiding a 101-query loop and rewrites it to 2 queries in 50ms.
How It Works
Before Agent
Code looks fine in dev → deploys to production → load increases →
database CPU spikes to 95% → p99 latency hits 5s → PagerDuty fires →
engineer spends 4 hours profiling → finds N+1 query →
hotfix at 2 AM (8 hours total)
After Agent
Developer writes code → runs perf-profiler → detects N+1 pattern
in 10 seconds → shows exact line + optimized query → developer
applies batch query fix → deploys with confidence (10 minutes total)
What It Catches
- ✅ N+1 Queries — loops executing individual DB calls
- ✅ Memory Leaks — unclosed connections, readers, channels
- ✅ Goroutine Leaks — goroutines without cancellation context
- ✅ Unbounded Allocations — slices growing without capacity hints
- ✅ Missing Connection Pools — new connection per request
- ✅ Blocking I/O in Hot Paths — sync file reads in request handlers
- ✅ Missing Indexes — queries on unindexed columns
- ✅ Large Payload Serialization — full object graphs in API responses
- ✅ Excessive Logging — debug logging in tight loops
- ✅ Missing Timeouts — HTTP clients without deadline
Real Example
Input (Go handler with N+1 query):
func GetOrders(w http.ResponseWriter, r *http.Request) {
orders, _ := db.Query("SELECT * FROM orders WHERE user_id = $1", userID)
for orders.Next() {
var o Order
orders.Scan(&o.ID, &o.ProductID, &o.Qty)
// N+1: one query per order to fetch product
product, _ := db.QueryRow("SELECT name, price FROM products WHERE id = $1", o.ProductID)
o.Product = product
results = append(results, o)
}
json.NewEncoder(w).Encode(results) // 100 orders = 101 DB calls
}Agent Output:
🔴 CRITICAL: N+1 Query detected (line 6-8)
Loop executes 1 query per order — 100 orders = 101 DB calls
Fix: Batch query with IN clause
ids := collectIDs(orders)
products, _ := db.Query(
"SELECT id, name, price FROM products WHERE id = ANY($1)", ids)
productMap := indexBy(products, "id")
// Map products to orders — 2 DB calls total
Impact: 101 calls → 2 calls, ~2000ms → ~50ms
Impact Numbers
| Metric | Before | After | |--------|--------|-------| | Response time (p95) | 2000ms | 50ms | | DB calls per request | 101 | 2 | | DB CPU under load | 95% | 15% | | Production incidents/month | 3-5 | 0 | | Time to find perf issues | 4-8 hours | 10 seconds |
Getting Started
agentbox pull perf-profiler
agentbox perf-profiler "profile my API handlers"