Skip to main content
Version: 0.2

Introduction

sqlguard is a production-safe SQL query analyzer for Go. It finds the queries that hurt in production — SELECT *, a DELETE with no WHERE, an N+1 loop, a LIKE '%…' that can never use an index, a query that took 800 ms — and reports each one with a rule name, a redacted copy of the query, and a suggested fix. Think of it as golangci-lint for the SQL your application actually runs.

Three entry surfaces, one analyzer

Every surface runs the same rules through the same analyzer and reporter, so a finding looks the same whether it came from a test run, a CI job or a production log.

SurfaceHowWhen to use it
Runtime middlewareWraps the database/sql driver, returns a real *sql.DBCatch everything your ORM or query builder emits, plus latency and N+1
Static scannersqlguard scan ./... walks Go source and resolves string constantsGate pull requests in CI without a database
EXPLAIN analyzersqlguard explain --db … plans a query on a live serverCheck a specific query's plan for sequential scans and missing indexes

Six ORM and driver integrations — GORM, sqlx, native pgx, bun, xorm and ent — are additional runtime surfaces. They hook each library's own callback seam and route through the same exported middleware.Guard, so they inherit every runtime behaviour without a second option surface to learn.

What you get out of the box

  • 21 detection rules — 14 static SQL rules, slow-query and n-plus-one at runtime, and 5 plan-level rules from EXPLAIN. See Rules.
  • Redaction by default — string and numeric literals become ? before a finding leaves the process, and every finding carries a stable, PII-free fingerprint that is safe as a metric label.
  • Quiet in production — repeated findings are de-duplicated per window, and repeated queries hit an exact-string cache instead of being re-parsed.
  • One config file — a .sqlguard.yml drives the middleware, the scanner and the CLI. Inline suppressions work without any config.
  • A pluggable parser — a zero-dependency fallback by default, or an opt-in real grammar for PostgreSQL or MySQL.

Module layout

sqlguard is nine Go modules released in lockstep, so a heavy dependency never enters your build unless you import the module that needs it:

ModuleImport pathThird-party deps
Coregithub.com/KARTIKrocks/sqlguardnone in analyzer, middleware, reporter
Config…/sqlguard/configgopkg.in/yaml.v3 (only here)
CLI…/sqlguard/cmd/sqlguardcobra, go/packages, database drivers
Parsers…/sqlguard/parsers/pgparser, …/parsers/mysqlparserthe respective SQL grammar
Integrations…/sqlguard/integrations/{gormguard,sqlxguard,pgxguard,bunguard,xormguard,entguard}the respective ORM/driver

Importing analyzer or middleware pulls in nothing outside the standard library.

What sqlguard is not

  • Not a query rewriter. It observes and reports; it never alters the SQL or the arguments on their way to the driver.
  • Not a schema linter. Rules reason about the statement text and, via EXPLAIN, the plan — not your migrations.
  • Not a replacement for tracing. The pgx integration composes with otelpgx and friends rather than replacing them.

Next steps

Start with Getting Started — it takes about a minute to see the first finding.