Backend/.NET performance optimization — EF Core queries, API response times, caching, database tuning, memory profiling
From claude-toolkitnpx claudepluginhub johwer/marketplace --plugin claude-toolkitThis skill uses the workspace's default tool permissions.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Compares coding agents like Claude Code and Aider on custom YAML-defined codebase tasks using git worktrees, measuring pass rate, cost, time, and consistency.
| Metric | Target | Action threshold |
|---|---|---|
| API response (p95) | < 200ms | > 500ms investigate |
| Database query | < 50ms | > 200ms optimize |
| TTFB | < 600ms | > 1.3s critical |
| Memory per request | < 5MB | > 20MB profile |
Query Optimization
.Include() for related entities, check EF Core logsSELECT * — use .Select() projections for read queries.AsNoTracking() for read-only queries (30-50% faster)WHERE, ORDER BY, and JOIN columnsEF Core Patterns
EF.CompileQuery().AsSplitQuery().Include() onlyExecuteUpdate() / ExecuteDelete() for bulkDatabase Maintenance
Payload
IAsyncEnumerable<T>)Caching
IMemoryCache) for hot data with TTLBackground Processing
Async/Await
.Result or .Wait() — causes thread pool starvationConfigureAwait(false) in library codeValueTask<T> for hot paths that often complete synchronouslyMemory
Span<T> / Memory<T> for buffer operationsArrayPool<T>.Shared for temporary arraysStringBuilder for string concatenation in loopsSerialization
[JsonSerializable][JsonIgnore] unused propertiesIHttpClientFactory — never new HttpClient() per request// BAD: N+1 — fetches each order separately
var users = await db.Users.ToListAsync();
foreach (var user in users)
user.Orders = await db.Orders.Where(o => o.UserId == user.Id).ToListAsync();
// GOOD: Single query with Include
var users = await db.Users
.Include(u => u.Orders)
.AsNoTracking()
.ToListAsync();
// BAD: Loads entire table into memory
var allUsers = await db.Users.ToListAsync();
return allUsers.Where(u => u.IsActive).Take(10);
// GOOD: Filter and page in database
var users = await db.Users
.Where(u => u.IsActive)
.OrderBy(u => u.Name)
.Skip(offset).Take(limit)
.AsNoTracking()
.ToListAsync();
// BAD: Thread pool starvation
var result = httpClient.GetAsync(url).Result;
// GOOD: Async all the way
var result = await httpClient.GetAsync(url);
// BAD: New HttpClient per request (socket exhaustion)
using var client = new HttpClient();
var response = await client.GetAsync(url);
// GOOD: IHttpClientFactory (pooled, managed)
public MyService(IHttpClientFactory factory)
{
_client = factory.CreateClient("ServiceName");
}
| Tool | Purpose | Usage |
|---|---|---|
| EF Core logging | Query analysis | .LogTo(Console.WriteLine, LogLevel.Information) |
| MiniProfiler | Per-request profiling | NuGet: MiniProfiler.AspNetCore |
| BenchmarkDotNet | Micro-benchmarks | [Benchmark] attribute on methods |
| dotnet-counters | Runtime metrics | dotnet-counters monitor |
| dotnet-trace | CPU profiling | dotnet-trace collect |
| dotnet-dump | Memory analysis | dotnet-dump analyze |
# Official Microsoft .NET skills — performance investigations, debugging
# From: github.com/dotnet/skills
# Aaronontheweb dotnet-skills — 30 skills + 5 agents (EF Core, concurrency, perf)
/plugin marketplace add Aaronontheweb/dotnet-skills
# wshaddix dotnet-skills — 167 skills (N+1 detection, query optimization, database-performance)
# From: github.com/wshaddix/dotnet-skills