Security & devFree

SQL Formatter

Free SQL formatter. Beautify SQL keywords and clauses with basic indentation for readability. Runs in your browser.

Last updated 14 October 2026

This is a keyword uppercaser, not a SQL parser, and the difference can corrupt your query

The tool works by finding a list of keywords surrounded by whitespace and putting a line break before each one. It does not parse SQL, so it has no idea which parts of your text are code and which are data. That has one consequence serious enough to lead the page with.

Keywords inside a string literal are rewritten. Measured:

input   select a from t where note = 'select from where'
output  SELECT a
          FROM t
          WHERE note = 'select
          FROM where'

The text inside the quotes was uppercased and had a line break pushed into the middle of it. Pasting that output back into a database would compare note against a different string from the one you started with. The same applies to a column or table name that happens to match a keyword.

A multi-line string literal is flattened. Measured: select 'line one⏎line two' from t comes back as SELECT 'line one line two'. The newline inside your data is replaced with a space, silently, because the first thing the formatter does is collapse all whitespace in the whole query.

So: use this to read a query someone sent you as one long line. Do not use its output as the query you run, unless you have checked that every string literal came through untouched.

Subqueries are not formatted, because the opening bracket hides the keyword

A keyword is only recognised when whitespace sits on both sides of it. A subquery starts immediately after a bracket, so its keyword is invisible to the formatter. Measured:

input   select a from t where id in (select id from u)
output  SELECT a
          FROM t
          WHERE id
          IN (select id
          FROM u)

Note the lower-case select inside the brackets, next to the upper-case ones outside. The from inside the subquery is matched, because it does have spaces around it, so it gets a line break at the same indent as the outer query. The result reads as though the subquery’s FROM belongs to the outer SELECT, which is the opposite of helpful.

For the same reason, a query written without spaces is left completely alone. Measured: select*from t comes back exactly as typed, unchanged and unformatted.

Every line gets the same two-space indent, so nesting is invisible

There is one indent level. The first line is flush left and every subsequent line gets two spaces, whatever its depth. A five-table join with two subqueries and a CASE expression comes out as a flat list of clauses.

That is still a large improvement on one 400-character line, which is the state most queries arrive in, and it is worth knowing that is all it is. If you need structure, the output is a starting point for hand-formatting rather than a finished product.

Identifiers keep their own case, and keywords are always made upper case

Measured: SELECT MyColumn FROM MyTable comes back as SELECT MyColumn and FROM MyTable, with the camel case on the identifiers intact. Only the recognised keywords are touched, and they are always upper-cased, never lower.

So the house style this tool enforces is upper-case keywords and untouched identifiers. If your team writes lower-case keywords, this tool will fight you and there is no option to turn it round.

What this tool deliberately does not do

Nothing is uploaded. The formatting is a few lines of JavaScript running in your browser, and the query never leaves your device, which matters because a real query usually contains table names, column names and sometimes literal values from production.

Sources

Every behaviour and every example on this page was measured against this tool as it is published, in a browser, on 14 October 2026. Where the page says what the tool does not do, that is a statement about this tool, not about SQL formatting in general.

Frequently asked questions

Is it safe to run the formatted query?

Only after checking your string literals. The formatter does not know which text is code and which is data, so a keyword inside quotes gets uppercased and gets a line break pushed into it. Measured: where note = 'select from where' comes back with the quoted text rewritten. Use the output to read a query, and check before you run it.

Why did the text inside my quotes change?

Because the tool is a text substitution over the whole query, not a parser. It collapses all whitespace first, which flattens multi-line strings, then uppercases and line-breaks every keyword it can see, including ones inside quotes. There is no way to tell it to leave literals alone.

Why is the SELECT in my subquery still lower case?

Because a keyword is only matched when there is whitespace on both sides of it, and a subquery’s keyword follows an opening bracket. Measured: in (select id from u) keeps select lower case while uppercasing the from after it, which also gets the same indent as the outer query.

Nothing happened to my query at all. Why?

It has no spaces around its keywords. Measured: select*from t comes back exactly as typed. Add spaces, or accept that this tool cannot help with compressed SQL.

Can I get lower-case keywords instead?

No. Recognised keywords are always upper-cased and there is no setting. If your team’s style is lower case, this tool is the wrong one.

Why is everything indented the same amount?

There is one indent level: the first line flush left, every other line two spaces in. Depth is not tracked, so joins, subqueries and CASE expressions all sit at the same level. It is still much easier to read than one long line, which is the problem it is actually solving.

Does it know my database’s dialect?

No. The keyword list is a fixed set of common ANSI-style keywords. Window functions, common table expressions, RETURNING, vendor functions and optimiser hints are not in it, so they are left alone.

Is my query sent anywhere?

No. The formatting runs in your browser and nothing leaves the page. That matters here because real queries carry table and column names, and often literal values copied out of production.

Related tools