# Configuration (/docs/go/configuration)

`tracepanel.WrapHandler` and `tracepanel.Setup` take a `tracepanel.Config`.
The fields you leave empty come from environment variables, then from the
defaults:

```go
handler := tracepanel.WrapHandler(mux, tracepanel.Config{Service: "shop"})
```

The integrations' middleware takes no `Config`. Call `tracepanel.Setup`
with it before you add the middleware. The environment variables are named
as in the other SDKs.

## Turn it on and off [#turn-it-on-and-off]

Tracepanel records in development only: when the app runs under `go run`,
with `TRACEPANEL_ENABLED=1`, or with `Config.Enabled`. A binary built with
`go build` records nothing. `TRACEPANEL_ENABLED=0` turns it off, whatever
else says. `tracepanel run` and `tracepanel dev --` set
`TRACEPANEL_ENABLED=1` for the command they run. See
[Command line](/docs/go/cli).

With `Config.Enabled`, call `tracepanel.Setup` before `Driver`, so the
database is recorded too.

When it is off, `WrapHandler`, `Driver` and the rest return what you gave
them: your handler as it is, and the driver's own name. The integrations
record nothing, and no agent is downloaded or started. `Span`, `Go` and
`Command` run your function and nothing else. `Dump` still prints, and
records nothing.

## Settings [#settings]

| Field | Variable | Default | What it sets |
| --- | --- | --- | --- |
| `Enabled` | `TRACEPANEL_ENABLED` | on under `go run`, off in a built binary | `1` records in any build, `0` never |
| `Service` | `TRACEPANEL_SERVICE` | the executable's name | the app's name in the console |
| `StoreDir` | `TRACEPANEL_DIR` | `.tracepanel` | the store, where the agent keeps the traces |
| `ConsoleURL` | `TRACEPANEL_CONSOLE_URL` | where the project's agent serves it | the console the badge loads from and opens |
| `MaxTraces` | `TRACEPANEL_MAX_TRACES` | `2000` | how many traces the agent keeps |
| `Module` | | the main module | the module whose frames are your code |
| `Route` | | the `ServeMux` pattern | a request's route, for another router |
| `Profile` | `TRACEPANEL_PROFILE` | off | `1` profiles every trace, not only those the panel asks for |
| `ProfileMemory` | `TRACEPANEL_PROFILE_MEMORY` | off | `1` measures every profiled trace's memory, not only those asked for it |
| | `TRACEPANEL_PROFILE_ENABLED` | on | `0` profiles nothing |
| | `TRACEPANEL_CAPTURE_REQUEST` | on | `0` keeps no headers, query, cookies or body for the Request tab |
| | `TRACEPANEL_AGENT_BIN` | the agent the SDK downloads | the agent to start, such as a build of your own |
| | `TRACEPANEL_AGENT` | `auto` | an agent that runs elsewhere, as `tcp:host:port`, which Tracepanel never starts. `off` starts none |
| | `TRACEPANEL_CACHE_DIR` | `%LOCALAPPDATA%\tracepanel` on Windows, else `$XDG_CACHE_HOME/tracepanel` or `~/.cache/tracepanel` | where the downloaded agent is kept. See [The agent](/docs/go/installation#the-agent) |
| | `TRACEPANEL_NPM_REGISTRY` | npm's `npm_config_registry`, else `https://registry.npmjs.org/` | the npm registry the agent is downloaded from |
| | `HTTPS_PROXY`, `NO_PROXY` | none | the proxy for the agent's download, and the hosts it skips |
| | `TRACEPANEL_OTLP` | `127.0.0.1:4318` | where the agent takes OpenTelemetry spans, as `HOST:PORT`, or `off`. See [The OTLP port](/docs/how-it-works#the-otlp-port) |

## Thresholds [#thresholds]

The agent finds the [issues](/docs/issues) by these thresholds:

| Variable | Default | What it sets |
| --- | --- | --- |
| `TRACEPANEL_N_PLUS_ONE_THRESHOLD` | `3` | how many repeats make an N+1 |
| `TRACEPANEL_N_PLUS_ONE_MIN_MS` | `5` | for Redis and other fast stores, the time the repeats must take together |
| `TRACEPANEL_SLOW_SQL_MS` | `100` | a slow query |
| `TRACEPANEL_SLOW_HTTP_MS` | `500` | a slow outgoing HTTP call |
| `TRACEPANEL_LONG_TRANSACTION_MS` | `500` | a long transaction |
| `TRACEPANEL_QUEUE_WAIT_MS` | `1000` | a task that waited long for a worker |
| `TRACEPANEL_LARGE_RESULT_ROWS` | `1000` | a query without a `LIMIT` that read too many rows |

### A limit per database [#a-limit-per-database]

`TRACEPANEL_SLOW_SQL_MS` and `TRACEPANEL_LONG_TRANSACTION_MS` take a limit
per database too, by its kind:

```bash
export TRACEPANEL_SLOW_SQL_MS=100,snowflake=3000
```

This holds every database to 100 ms, and Snowflake to 3 s. Without a limit
of its own, the agent holds an analytical warehouse, such as Snowflake,
BigQuery, Databricks, Redshift or ClickHouse, to 2 s per query.

The kind comes from the driver. `pgx` and lib/pq are `postgresql`, and the
drivers of MySQL, MariaDB, SQLite, SQL Server, Oracle, ClickHouse, DuckDB,
Snowflake, BigQuery, Databricks, Redshift and Trino tell theirs too. For a
driver the SDK doesn't know, or one that reaches another database, such as
CockroachDB through pgx, name the kind yourself:

```go
db, err := sql.Open(tracepanel.Driver("pgx", tracepanel.DBSystem("cockroachdb")), dsn)
```

## Without an agent [#without-an-agent]

When the SDK can't get an agent, or the agent doesn't start, the log says
why, once. Responses keep their headers, pages get no badge, and no traces
are kept. The agent writes its own log to `.tracepanel/agent.log`.

## A trace's size [#a-traces-size]

A trace keeps at most 2,000 spans and 1,000 log records, as the agent stores
it, and counts the rest.
