Sharon Ben-Moshe is the founder of sqlfmt, a browser-based SQL formatter and validator with misspelled-keyword suggestions across PostgreSQL, MySQL, SQLite, SQL Server, and BigQuery.
Should SQL keywords be uppercase or lowercase? We compare major style guides, tool defaults, and team conventions to give you a clear, defensible answer.
Quick answer
SQL keywords like SELECT, FROM, and WHERE are case-insensitive in every major database — the engine treats them identically regardless of capitalization. The convention endorsed by most style guides and the default for popular SQL formatters is uppercase keywords with lowercase identifiers, because the contrast makes it easy to separate SQL structure from your data. If your team has no existing convention, uppercase keywords is the broadly recognized, low-friction choice.
FAQs
Is SQL case-sensitive for keywords?
No. SQL keywords are case-insensitive in all major databases — PostgreSQL, MySQL, SQLite, SQL Server, and BigQuery all treat SELECT, select, and Select identically. Keyword casing is a style convention, not a syntax requirement. Quoted identifiers are different and can be case-sensitive depending on the database.
Does writing SQL keywords in uppercase make queries run faster?
No. The database parser normalizes keywords before processing, so uppercase and lowercase produce identical execution plans. Performance differences come from query structure, indexes, statistics, and join handling — not from how you capitalize SELECT or WHERE.
What does the most popular SQL style guide say about keyword casing?
Simon Holywell's SQL Style Guide (sqlstyle.guide) — the most widely-referenced public SQL style guide — recommends uppercase for all reserved words. GitLab, Microsoft T-SQL documentation, and Google BigQuery all follow the same convention in their official examples and style guidance.
Should table and column names be uppercase too?
No. The convention is uppercase keywords (SELECT, FROM, WHERE, JOIN) with lowercase identifiers (table names, column names). That contrast is the whole point: it creates an immediate visual boundary between SQL structure and your data, making queries easier to scan at a glance.
How do I automatically enforce SQL keyword casing across my team?
Add a SQL formatter to your workflow and run it in check mode on pull requests. Tools like sqlfmt, sqlfluff, and sql-formatter all enforce keyword casing automatically. Commit a shared config file to the repo so every team member uses identical settings, and add the check to CI so violations are caught before merge.
Try it now
Paste your SQL into sqlfmt — format, validate, and catch typos free in your browser.
SQL keywords like SELECT, FROM, and WHERE are case-insensitive — every major database accepts both uppercase and lowercase. The real question isn't whether your queries will run; it's whether your team's SQL will be consistent, readable, and easy to review.
Most style guides and SQL formatters converge on the same answer: uppercase keywords, lowercase identifiers. The contrast helps readers instantly separate SQL structure from data. It's not enforced by any engine, but it has become the de-facto standard across documentation, tools, and teams.
This guide explains the technical reality, surveys what major style guides actually say, and gives you a concrete checklist to lock in a consistent casing convention on your team.
Is SQL Case-Sensitive for Keywords?
SQL keywords are case-insensitive in all five major databases: PostgreSQL, MySQL, SQLite, SQL Server (T-SQL), and BigQuery. The PostgreSQL documentation states this explicitly: "Key words and unquoted identifiers are case-insensitive." The same holds true across every other major dialect.
All three queries return identical results
-- These three produce the same outputSELECT id, name FROM users WHERE active = 1;select id, name from users where active = 1;Select Id, Name From Users Where Active = 1;
Identifiers — table names, column names, schema names — are a different matter. PostgreSQL folds unquoted identifiers to lowercase, so Users and users refer to the same table — but "Users" (quoted) is treated as case-sensitive. MySQL's identifier case sensitivity depends on the OS and the lower_case_table_names setting. The bottom line: keyword casing is a pure style choice, while identifier casing can affect runtime behavior.
What Do Major Style Guides Recommend?
Most widely-referenced SQL style guides land on uppercase keywords. Simon Holywell's SQL Style Guide — the most-linked public SQL style guide — recommends uppercase for all reserved words. Here's a quick survey:
Simon Holywell's SQL Style Guide: uppercase all reserved words
Google BigQuery documentation: all examples use uppercase keywords
A minority of style guides favor lowercase — typically ones making a broader argument that SQL should look consistent with Python or JavaScript. That argument has some merit if SQL is peripheral in your stack. But when SQL is a first-class language in your workflow, its own conventions apply.
The Case for Uppercase Keywords
Visual separation between structure and data
In SELECT id, name FROM users WHERE active = 1, the keywords stand out immediately. In the all-lowercase version, every word competes for the same visual weight and the eye has to work harder to parse structure from data. The contrast matters most in long queries with multiple joins, subqueries, or CASE expressions.
Formatter and tool defaults
sql-formatter (the most-installed SQL formatting library), sqlfmt, DataGrip, pgAdmin, and most SQL IDE formatters default to uppercase keywords. Lowercase enthusiasts have to actively override the default — which means any new team member or automated tool will push back toward uppercase unless you configure it otherwise.
Documentation and example consistency
Every major database reference manual — PostgreSQL, MySQL, SQL Server, BigQuery — uses uppercase keywords in its examples. Stack Overflow answers and database textbooks do the same. Going against this means every copy-pasted snippet from documentation needs a case change, adding constant friction for your whole team.
The Case for Lowercase Keywords
The lowercase camp has a legitimate argument: uppercase is slower to type (you need Shift or Caps Lock) and some typographic research suggests that all-caps text takes longer to read than lowercase. That second point is debated when applied to short SQL keyword tokens rather than running prose — but it's not without basis.
Lowercase also fits a preference for visual uniformity across languages. If you write Python, JavaScript, and SQL in the same editor session, an all-lowercase style removes one context switch. Some modern toolchains (dbt's lowercase-by-convention in Jinja models, for example) lean this direction.
The practical takeaway: if your team already has a lowercase convention and enforces it with a formatter, don't switch just because the majority opinion is uppercase. Consistent lowercase beats inconsistent uppercase every time.
What SQL Formatters Default To
Formatters are a pragmatic signal: they encode the considered opinion of many engineers. The most widely used ones all default to uppercase keywords. Here's a before-and-after showing what mixed-case SQL looks like after formatting:
Keyword casing is one piece of a broader SQL style puzzle. For the full breakdown — comma placement, indentation, explicit JOIN syntax, and CTE style — see our guide to SQL formatting best practices.
Choosing and Enforcing a Casing Standard
Agreeing on uppercase or lowercase is a five-minute conversation. Getting it to stick without a linter is a months-long battle. The tooling side matters more than the decision itself.
Format on save
Configure your editor to format SQL on save using a shared tool and config file committed to the repo. Every engineer gets consistent output automatically, without thinking about it.
CI enforcement
Run your SQL formatter in --check mode on pull requests. The build fails if any SQL file is unformatted. This catches cases where someone bypassed the editor plugin or edited SQL outside their usual environment.
Reformatting existing files
Run the formatter across the entire codebase in a single dedicated commit, separate from any feature work. This makes the reformatting commit easy to exclude with git blame --ignore-rev, keeping your feature history clean.
SQL Keyword Casing Checklist
Before finalizing your team's keyword casing standard:
Audit your existing codebase — count how many files use uppercase vs lowercase. Switching direction is a larger effort than it appears.
Check your formatter's current default before configuring anything. If it already outputs uppercase and you have no contrary convention, you're done.
Commit a formatter config file to the repo root so every engineer uses identical settings automatically.
Add a pre-commit hook that runs the formatter in check mode. Catch violations before they reach a pull request.
Add a CI step that runs the same check as a safety net.
Document the chosen convention in your SQL style guide or CONTRIBUTING.md — one sentence is enough.
Land the full-codebase reformatting commit on its own, before enabling CI enforcement, so the reformatting PR itself doesn't trigger false failures.
Wrapping Up
SQL keyword casing is a style choice, not a correctness concern — every major database accepts both. But style choices compound: a consistent uppercase convention makes SQL faster to skim, easier to review, and eliminates the "which way does this team do it?" debate on every pull request.
If you want automatic enforcement without a long toolchain setup, sqlfmt formats SQL to uppercase keywords in one click, with no configuration needed. And if keyword casing sparked a broader style debate on your team, the next question is usually comma placement — our post on SQL leading comma style covers that in full.
select u.id, u.name, count(o.id) as order_countfrom users uleft Join orders o ON u.id = o.user_idWHERE u.active = 1group by u.id, u.namehaving count(o.id) > 0order BY u.name;
After: formatted with uppercase keywords
SELECT u.id, u.name, COUNT(o.id) AS order_countFROM users AS uLEFT JOIN orders AS o ON u.id = o.user_idWHERE u.active = 1GROUP BY u.id, u.nameHAVING COUNT(o.id) > 0ORDER BY u.name;