The getAgentBreakdown procedure fetches every single agentJob row for all accessible projects (potentially tens of thousands of rows) and then loops through them in JavaScript to build the aggregation map. This is a classic N-load-then-aggregate anti-pattern that should be a single GROUP BY SQL query, exactly as getSummary already does correctly using sql<number> aggregate filters.
Category: api File: src/lib/routers/observability.ts Recommendation: Replace the full-table JS aggregation with a single SQL query: SELECT agentType, COUNT() as totalJobs, COUNT() FILTER (WHERE status='completed') as completed, COUNT(*) FILTER (WHERE status='failed') as failed, COALESCE(SUM((tokenUsage->>'inputTokens')::int),0) as inputTokens, COALESCE(SUM((tokenUsage->>'outputTokens')::int),0) as outputTokens, AVG(EXTRACT(EPOCH FROM (completedAt - startedAt))) as avgDurationSec FROM agentJobs JOIN pipelineRuns ... GROUP BY agentType. Estimated Improvement: Reduces response time from O(n) memory + transfer to O(1) DB aggregation; prevents OOM risk as agent job count grows; expected 10-100x speedup on large datasets