# sql-tap: Real-Time SQL Traffic Inspection for PostgreSQL, MySQL, and TiDB

> sql-tap is a Go proxy daemon with TUI, Web, and CI clients for observing database traffic in real time. It fits development and test environments where query inspection must happen without modifying application code.

**mickamy/sql-tap** — Watch SQL traffic in real-time with a TUI

- Repository: https://github.com/mickamy/sql-tap
- Stars: 1,593 · Forks: 50
- Language: Go
- License: MIT
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/mickamy-sql-tap

## Why sql-tap Sits Between the Application and Database

sql-tap addresses a specific observability gap: an application can send SQL normally while a separate process watches the traffic and reports query activity. It is intended for developers who need to inspect individual statements, transaction grouping, query duration, slow operations, and repeated N+1 patterns. The supported upstream databases are PostgreSQL, MySQL, and TiDB. Its terminal and browser clients also give teams a way to collect query events during automated tests rather than adding database logging calls throughout application code.

The architecture has three distinct parts. `sql-tapd` is the database-facing proxy and event server. `sql-tap` is the terminal client connected to that server over gRPC. The optional Web UI is served by the same daemon and receives a real-time query stream through SSE. This separation matters because the application only needs a different database address, while inspection happens outside its code path.

That approach avoids SQL-client libraries as an application dependency, but it is not transparent infrastructure. The database connection must be redirected through the proxy, and traffic gains another network hop. The README does not discuss a passive capture mode, production deployment guidance, authentication for the gRPC service, or a mechanism for automatically restoring the upstream address. Those omissions make local and test environments the clearer use cases. This is a developer diagnostic tool, not a general-purpose database access gateway.

## sql-tapd Proxy Flow and Query Event Pipeline

The proxy listens on a client-facing address and forwards traffic to an upstream database address. The README states that it speaks the native wire protocol, so an application connects to `sql-tapd` instead of connecting directly to PostgreSQL, MySQL, or TiDB. As queries pass through the proxy, the daemon captures them and makes the associated events available to connected clients.

The terminal client connects to the daemon's gRPC address, which defaults to `:9091`. The client then presents a list containing queries and transactions, with controls for inspection, filtering, sorting, and transaction expansion. This design keeps database protocol handling in the daemon while presenting operator controls in a separate terminal process. Repository directories such as `proxy/`, `broker/`, `query/`, `server/`, and `tui/` reflect that separation.

Event analysis is configurable in two ways. The slow-query threshold defaults to `100ms` and can be disabled with `0`. N+1 detection uses a threshold of `5`, a `1s` window, and a `10s` cooldown per query template. The TUI can flag detected problems, while the Web UI adds highlighting and toast notifications. The daemon also recognizes transaction boundaries, allowing the interface to expand or collapse related activity.

EXPLAIN has a separate data path. The proxy must read a DSN from `DATABASE_URL`, or from the environment variable named by `-dsn-env`. If that variable is absent, traffic is still captured but EXPLAIN is disabled. This distinction matters during setup: successful query viewing does not prove that database plans can be requested. Enabling `X` for `EXPLAIN ANALYZE` can also execute an edited plan against the configured database, so it belongs in a controlled development or test environment.

## Installing sql-tap and Viewing the First PostgreSQL Queries

The Go installation path installs both the daemon and terminal client. A Go toolchain capable of building the module is required for this documented method. The commands install the current tagged module rather than requiring a separate checkout.

```bash
go install github.com/mickamy/sql-tap@latest
go install github.com/mickamy/sql-tap/cmd/sql-tapd@latest
```

Start `sql-tapd` with the PostgreSQL driver, a local client port, and the real database address. The example also supplies `DATABASE_URL` for EXPLAIN support.

```bash
DATABASE_URL="postgres://user:pass@localhost:5432/db?sslmode=disable" \
  sql-tapd --driver=postgres --listen=:5433 --upstream=localhost:5432
```

The daemon should listen for clients on `:5433` and forward them to PostgreSQL on `localhost:5432`. Change the application's database host and port to `localhost:5433`. The README explicitly says no application code changes are required, although connection configuration outside the application, such as an environment variable, may still need to change.

In another terminal, connect the TUI to the daemon's default gRPC endpoint:

```bash
sql-tap localhost:9091
```

Queries sent through the proxy port should appear in real time. Press `j` or `k` to move through the list, `/` to search, `Enter` to inspect a query or transaction, and `x` to request `EXPLAIN`. If queries do not appear, first confirm that the application is using the proxy port rather than `5432`, then confirm that the daemon and client both target `:9091`. The repository does not document automatic failure recovery if the daemon stops or the upstream database becomes unavailable.

## MySQL, TiDB, Configuration, and the Web Client

MySQL and TiDB use the same routing model with different drivers and example ports. The documentation provides a MySQL DSN shaped for `database/sql`, plus a `:3307` client listener forwarding to `localhost:3306`. For TiDB, the daemon listens on `:4001` and forwards to `localhost:4000`.

```bash
DATABASE_URL="user:pass@tcp(localhost:3306)/db" \
  sql-tapd --driver=mysql --listen=:3307 --upstream=localhost:3306
```

```bash
DATABASE_URL="user:pass@tcp(localhost:4000)/db" \
  sql-tapd --driver=tidb --listen=:4001 --upstream=localhost:4000
```

Repeated flags can be replaced with `.sql-tap.yaml`. The daemon loads that filename from the current directory when it exists, and `-config` selects another path. CLI flags take precedence. Configuration keys use underscores, including `dsn_env`, `slow_threshold`, and `nplus1`.

```yaml
driver: postgres
listen: ":5433"
upstream: "localhost:5432"
grpc: ":9091"
http: ":8080"
dsn_env: DATABASE_URL
slow_threshold: 100ms
nplus1:
  threshold: 5
  window: 1s
  cooldown: 10s
```

With `http: ":8080"`, the daemon also serves the browser interface documented as `http://localhost:8080`. It provides a real-time SSE stream, query details, filtering, query copying, EXPLAIN controls, N+1 highlighting, and a timeline. The repository does not state whether the Web UI, gRPC listener, or EXPLAIN DSN requires authentication. Binding these services beyond localhost would therefore require verification outside what the README establishes.

## CI Reporting for Slow Queries and N+1 Detection

The `-ci` mode turns the terminal client into a report collector. It connects to an existing `sql-tapd`, gathers events until the process receives `SIGTERM` or `SIGINT`, prints its report, and exits. The documented exit status is `0` when no configured problem is found and `1` when problems are detected.

The test connection must target the proxy, not the direct database. In the PostgreSQL example, `localhost:5433` is the proxy port established by `sql-tapd`.

```bash
sql-tap -ci localhost:9091 &
CI_PID=$!

DATABASE_URL="postgres://user:pass@localhost:5433/db?sslmode=disable" go test ./...

kill "$CI_PID" 2>/dev/null || true
wait "$CI_PID" 2>/dev/null || true
```

This makes sql-tap usable as a test-environment side process, but it also makes CI orchestration responsible for three details: start the daemon, ensure tests use its client port, and signal the collector only after tests complete. A CI runner that cannot accept a proxy in the database connection path will not gain value from the reporter.

The thresholds also determine what the report means. A query below `100ms` does not appear slow under the default configuration, while a repeated pattern must meet the N+1 threshold within its configured window. These are detection rules, not database performance classifications. The README does not describe query sampling, event retention limits, or behavior under very high traffic, so CI use is best evaluated with workloads whose event volume is known.

## Operational Limits, License, and Release Maintenance

The central limitation is network placement. Applications must accept the proxy as their database endpoint, and the proxy must preserve the selected database's native protocol connection. Failure to redirect the correct port produces no captured traffic even when the daemon itself is running. SQL clients or features outside the documented protocol path may also need verification, because the README names the databases but does not enumerate every extension or compatibility mode.

sql-tap is also not the right tool for retaining application logs across a fleet. It provides a live event interface, detection rules, EXPLAIN access, and a process-bound CI report, but the documentation does not specify durable event storage, historical retention, multi-user access control, or a database of recorded traffic. A conventional database query log or APM system with longer retention serves a different requirement.

The repository is not archived. Its last push was on 2026-07-07, and release `v0.3.2` was published on 2026-07-07. That is recent project activity, but the version remains pre-1.0, which usually warrants attention to release notes and compatibility changes before relying on it in a shared workflow. The documented `go install...@latest` form installs the latest release, while it does not pin or provide a rollback procedure. Users who need reproducible builds should record the chosen version externally.

The project uses the MIT license. That permits use, modification, distribution, and sublicensing subject to the license terms and preservation of its copyright and permission notice. It does not by itself establish compatibility with an organization's policies, and the MIT license does not remove the operator's responsibility for database credentials, network exposure, or the effects of executing EXPLAIN ANALYZE.

## Conclusion

sql-tap is appropriate for developers who can route a development or test application through a local database proxy and need live query inspection or CI reporting. It is a poor fit for a deployment where traffic routing is prohibited, where adding another network hop is unacceptable, or where the supported database set excludes the production system. Verify first that the selected native protocol works with the exact application connection settings, then confirm that EXPLAIN credentials, thresholds, and exposed gRPC or HTTP addresses meet local security requirements. For the documented PostgreSQL workflow, adoption can proceed only after an application successfully reaches the upstream database through `sql-tapd` on `:5433`.

## FAQ

### How do I install sql-tap on Go?

Install both binaries with `go install github.com/mickamy/sql-tap@latest` and `go install github.com/mickamy/sql-tap/cmd/sql-tapd@latest`. The README also documents Homebrew, Nix, source builds, and Docker.

### Does sql-tap require changes to application code?

No application code changes are required according to the README. The application database configuration must point to the proxy port, while `sql-tapd` forwards traffic to the upstream database address.

### Why is EXPLAIN unavailable even though sql-tap is capturing queries?

Query capture works without `DATABASE_URL`, but EXPLAIN requires that variable or another DSN environment variable selected through `-dsn-env`. Configure a reachable DSN before using the EXPLAIN controls.

## Sources

- [Issues](https://github.com/mickamy/sql-tap/issues)
- [License: MIT](https://github.com/mickamy/sql-tap/blob/main/LICENSE)
- [mickamy/sql-tap on GitHub](https://github.com/mickamy/sql-tap)
- [README](https://github.com/mickamy/sql-tap/blob/main/README.md)
- [Releases](https://github.com/mickamy/sql-tap/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/mickamy-sql-tap
