# Measure application performance

Measure a real route or query before changing it. Include authentication, database access and rendering when they are part of the application path.

## Ask your agent

```text
Read https://cicadel.fauzaanu.com/en/dev/howto/performance/index.md.
Investigate [slow route or operation] in this application.
Create a representative benchmark, record latency and allocations, and profile it.
Fix the measured bottleneck while preserving behavior and permissions.
Compare repeated runs and report the workload and any remaining uncertainty.
```

## Benchmark a handler

Add a benchmark next to the handler you want to measure. This template uses a generated notes app; replace it with the real handler and its dependencies.

<!-- example: quickstart/apps/notes/benchmark_test.go -->
```go
package notes

import (
    "net/http/httptest"
    "testing"
)

func BenchmarkIndex(b *testing.B) {
    request := httptest.NewRequest("GET", "/notes/", nil)
    b.ReportAllocs()
    for b.Loop() {
        recorder := httptest.NewRecorder()
        Index(recorder, request)
        if recorder.Code != 200 {
            b.Fatalf("status = %d", recorder.Code)
        }
    }
}
```

```sh
go test ./apps/notes -run '^$' -bench BenchmarkIndex -benchmem -count=5
```

This measures the handler directly. It excludes network, middleware and database costs unless you include them in the setup.

## Profile the operation

```sh
go test ./apps/notes -run '^$' -bench BenchmarkIndex -benchtime=5s \
  -cpuprofile=cpu.out -memprofile=mem.out
go tool pprof -top cpu.out
go tool pprof -top -alloc_space mem.out
```

For database work, use representative rows in a disposable PostgreSQL database. Check query counts with [the application testing helpers](https://cicadel.fauzaanu.com/en/dev/topics/testing/index.md#postgresql-isolation-and-query-budgets) and inspect slow SQL with PostgreSQL's query planner.

## Compare a change

Keep the same inputs, dataset and concurrency before and after a change. Record errors as well as latency. Repeat runs; a single short run is not enough to claim a speedup. Do not use a development server's latency as your production capacity estimate.
