FREE TOOL

Format a SQL query, safely.

By Chris Davidson, founder of yForest · Updated September 26, 2026

Uppercase keywords, consistent indentation, CTEs and window functions handled correctly. Nothing leaves your browser.

Paste SQL. Get it formatted.

Runs in your browser. If a segment can't be parsed with confidence, it's left exactly as you wrote it.

What "never corrupt input" means here

This formatter tokenizes your query character by character before it reformats anything: strings, comments, quoted identifiers, numbers, operators, and words are each classified first, then only whitespace and line breaks around known clause keywords are changed. A string literal that happens to contain the word SELECT stays exactly as written, quotes and casing intact, because it was tokenized as a string, not as a keyword. If a query has an unbalanced paren or an unterminated string, the tool doesn't try to guess your intent; it passes the malformed part through rather than mangling it further.

A before and after

select u.id, o.total from users u inner join orders o on u.id = o.user_id where o.total > 100 and u.active = 1 order by o.total desc

becomes:

SELECT u.id,
  o.total
FROM users u
INNER JOIN orders o
ON u.id = o.user_id
WHERE o.total > 100
  AND u.active = 1
ORDER BY o.total DESC

CTEs, subqueries, and window functions

A CTE's inner query gets its own indent level relative to the parenthesis it lives inside, so a chain of two or three CTEs stays readable instead of collapsing into one wall of text:

WITH recent AS (
  SELECT *
  FROM events
  WHERE ts > '2026-01-01')
SELECT count(*)
FROM recent

Window functions and their PARTITION BY / ORDER BY clauses stay inside the function's parentheses rather than breaking onto new top-level lines, since a comma inside a function call or argument list is deliberately left inline instead of triggering a new line: ROW_NUMBER() OVER (PARTITION BY dept ORDER BY salary DESC) formats as one readable unit, not a list broken apart by every comma it contains.

Comments and CASE expressions

Line comments (--) and block comments (/* ... */) are recognized as their own token type and never touched beyond being kept on the line they started on. A CASE ... WHEN ... THEN ... ELSE ... END block is tracked as its own nesting level so its internal keywords don't trigger the same line breaks a top-level WHEN would outside a CASE expression, which is a common way naive regex-based formatters break a query that looks fine until you run it.

What this is, and isn't

This is the free, no-key layer of formatting: consistent casing, consistent indentation, one clause per line. It does not rewrite your query's logic, rename anything, or suggest a better join. QueryFlow's Ask panel, using your own API key against a model like Claude Sonnet 5 or GPT-6, can go further: explain what a query does, suggest an index, or rewrite a subquery as a CTE. This tool is the mechanical half of that; Ask is the half that requires actually understanding what the query is for.

Sources

Free tools
QueryFlow Studio $9.99/mo · $99/yr
QueryFlow Pipelines $29.99/mo · $199.99/yr

Frequently asked

Is my SQL sent to a server to be formatted?

No. Tokenizing and formatting both happen in JavaScript in your browser. Nothing you paste is transmitted anywhere.

Will it ever change what my query does?

It's designed not to. Only whitespace and line breaks around recognized clause keywords change; strings, comments, identifiers, and operators are passed through as tokenized, unchanged.

Does it handle CTEs and subqueries?

Yes. A parenthesized SELECT or WITH gets its own indent level relative to where it's nested, so multi-CTE queries stay readable.

Why don't function arguments break onto separate lines?

Commas inside parentheses (function calls, value lists) are kept inline on purpose. Only top-level commas, like a SELECT list or column list, start a new line.

How is this different from the paid Ask panel?

This is rule-based formatting only: casing and layout. Ask panel uses your own model key to actually reason about a query, like explaining it or suggesting a rewrite.

Formatting is the free layer. Ask is the rest.

QueryFlow's Ask panel explains and rewrites SQL with your own model key.

Start 14-day free trial

No credit card. 14 days. Cancel in one click.