Skip to content
7 Best SQL Linters in 2026 (Free and Paid)

Click to use (opens in a new tab)

7 Best SQL Linters in 2026 (Free and Paid)

September 3, 2026 by Chat2DBChat2DB Team

A SQL linter is not a formatter. A formatter changes how a query looks; a linter tells you what is wrong with it — the UPDATE that lost its WHERE clause in a rebase, the NOT IN subquery that returns zero rows the day a NULL appears, the function wrapped around an indexed column that quietly turned an index scan into a sequential scan.

The tools below all do some of that, but they sit at very different points on the spectrum. Here is what each one is actually good for.

1. Chat2DB

Chat2DB (opens in a new tab) is an AI-powered SQL client, and the linting it does is connected linting — it checks your SQL against the schema you are actually connected to, not just against a grammar. That is a different category of feedback from a static parser: it can tell you the column does not exist, that the join key types do not match, or that the predicate you wrote will not use the index that exists on the table.

What it does:

  • AI review of a statement in context, with the schema loaded, across PostgreSQL, MySQL, Oracle, SQL Server, ClickHouse, MongoDB and 20+ other engines.
  • Formatting and query rewriting suggestions, including turning a correlated subquery into a join.
  • Execution plan inspection next to the query, so a flagged predicate can be verified with EXPLAIN immediately rather than argued about.
  • Natural-language to SQL, which matters here because generated SQL is exactly the code that most needs a review pass before it runs.

Where it fits: interactive work — writing, checking and running a query, then reading the plan. It runs on Windows, macOS and Linux, and there is a browser version at app.chat2db.ai (opens in a new tab) if you would rather not install anything.

Trade-off: it is a client, not a CI binary. For a pull-request gate you still want a headless linter such as SQLFluff alongside it.

2. SQLFluff

The reference open-source SQL linter, and the one most teams end up putting in CI. SQLFluff parses SQL into a real syntax tree per dialect, which is why it can auto-fix rather than only complain.

pip install sqlfluff
sqlfluff lint models/orders.sql --dialect postgres
sqlfluff fix models/orders.sql --dialect postgres

Configuration lives in a .sqlfluff file:

[sqlfluff]
dialect = postgres
max_line_length = 120
 
[sqlfluff:rules:capitalisation.keywords]
capitalisation_policy = upper

Strengths: 60+ rules across layout, capitalisation, aliasing, references and structure; a genuine fix mode; first-class dbt and Jinja templating support; native GitHub annotation output.

Weaknesses: slow on large repositories, especially with the dbt templater. Rule codes changed in 3.x, so old blog posts reference codes that no longer exist. It also has no idea what your schema looks like.

See our SQLFluff tutorial for a full CI setup.

3. sqlfmt

sqlfmt takes the Black approach: it is opinionated, has essentially no configuration, and its only job is to make every file look the same.

pip install shandy-sqlfmt
sqlfmt models/           # rewrite in place
sqlfmt models/ --diff    # CI mode: fail if anything would change

Strengths: zero config arguments, very fast, produces a consistent layout that ends style debates immediately. Popular in dbt projects.

Weaknesses: it is a formatter, not a linter — it will never tell you that your DELETE has no WHERE clause. Its layout is deliberately non-negotiable, so if your team hates the output there is no knob to turn. Use it with a linter, not instead of one.

4. sql-lint

A Node-based linter that focuses on mistakes rather than style, and can optionally connect to a MySQL or PostgreSQL instance to validate identifiers.

npm install -g sql-lint
sql-lint --driver postgres queries/report.sql
echo "SELECT * FROM users WHERE id = 1" | sql-lint

Strengths: lightweight, fits naturally in a JavaScript toolchain, catches the classics — missing WHERE on destructive statements, invalid column references when connected, mistyped keywords.

Weaknesses: far smaller rule set than SQLFluff, limited dialect coverage, and development is less active. Good as a fast pre-commit tripwire, not as your only gate.

5. SonarQube / SonarLint (PL/SQL and T-SQL)

If your organisation already runs SonarQube, it has SQL analysers — strongest for Oracle PL/SQL and T-SQL rather than plain analytical SQL.

Strengths: results land in the same quality gate as the rest of your code, with tracked debt, ownership and history. Genuinely good rules for stored procedure logic: unreachable code, unhandled exceptions, cursors never closed, SQL injection paths in dynamic SQL.

Weaknesses: the deep SQL rules are in the commercial editions; Community coverage is thin. It is heavyweight to introduce purely for SQL, and weak on modern warehouse dialects such as Snowflake or BigQuery.

6. JetBrains DataGrip inspections

DataGrip's inspection engine is schema-aware in the way an IDE can be — it knows your tables because it is connected to them.

Strengths: unresolved references highlighted as you type, redundant joins, implicit type conversions, SELECT * warnings, and a large set of migration-safety checks. Quick-fixes are available inline.

Weaknesses: commercial licence, IDE-only — there is no headless mode to put in CI. And like any inspection engine it needs tuning, or the default severity levels will drown a legacy schema in yellow.

7. pgFormatter (and pg_format)

Perl-based, PostgreSQL-focused, and the tool most likely to already be on a DBA's machine.

pg_format -s 4 -f 1 report.sql > report.formatted.sql

Strengths: excellent PostgreSQL and PL/pgSQL handling including dollar-quoted function bodies, which several other tools mangle. Available as a CLI, a CGI web page you can self-host, and an editor plugin.

Weaknesses: formatting only, and single-dialect. If your stack is Postgres-only and you just want consistent files, it is hard to beat; if you want rules, pair it with something else.

Quick comparison

ToolTypeAuto-fixSchema-awareCI-friendlyLicence
Chat2DBClient + AI reviewSuggestionsYesVia clientFree tier + paid
SQLFluffLinter + formatterYesNoYesMIT
sqlfmtFormatterYesNoYesApache 2.0
sql-lintLinterNoOptionalYesMIT
SonarQubeStatic analysisNoNoYesCommunity + paid
DataGripIDE inspectionsInlineYesNoPaid
pgFormatterFormatterYesNoYesPostgreSQL licence

How to choose

Most teams need two tools, not one, because the categories genuinely do not overlap:

A headless linter in CI. SQLFluff for almost everyone. Add sqlfmt if you want formatting settled by fiat rather than by configuration. Pin the version so a linter release cannot fail a build for code nobody changed.

A schema-aware client for the interactive loop. This is where the expensive mistakes get caught, because it is the only place where the tool can see both the query and the data. Chat2DB covers this across a wide range of engines; DataGrip does it well if you are already in JetBrains and only need relational databases.

If you want a starting point that costs nothing, our SQL Linter & Style Checker (opens in a new tab) runs a rule set covering the correctness and sargability traps above entirely in your browser — nothing is uploaded — and our SQL Formatter (opens in a new tab) handles the layout half.

The rules that matter most

Whichever tool you pick, make sure these are enabled, because they catch bugs rather than style:

-- 1. UPDATE/DELETE with no WHERE clause
UPDATE orders SET status = 'cancelled';           -- rewrites every row
 
-- 2. NOT IN against a nullable subquery
SELECT * FROM orders
WHERE coupon_id NOT IN (SELECT id FROM coupons);  -- empty if any id IS NULL
 
-- 3. Comparison to NULL with = or <>
SELECT * FROM orders WHERE shipped_at = NULL;     -- never matches
 
-- 4. Function applied to an indexed column
SELECT * FROM orders WHERE date(created_at) = '2026-09-01';
-- rewrite as a range so the index is usable:
SELECT * FROM orders
WHERE created_at >= '2026-09-01' AND created_at < '2026-09-02';
 
-- 5. JOIN with no ON clause
SELECT * FROM orders o JOIN customers c;          -- cartesian product
 
-- 6. LIMIT with no ORDER BY
SELECT * FROM orders LIMIT 10;                    -- arbitrary, non-repeatable

Style rules make diffs readable. These six are the ones that keep you out of an incident review.