SQL Playground
Run real SQL in your browser on PostgreSQL 18 or SQLite 3, with sample databases. SELECT, JOIN, CREATE, ALTER, GRANT — the real engine, nothing simulated.
● Runs 100% in your browser — nothing you type leaves this page.
Engine
● Real PostgreSQL 18.6 (PGlite 0.5.10) running in your browser. Nothing is simulated, nothing is sent anywhere. MySQL, MariaDB, SQL Server and Oracle can’t run in a browser. For their syntax, see the SQL Dialect Reference.
Starting PostgreSQL 18.6 in your browser (downloaded once, a few MB)…
Results
Run a query to see the results here.
Examples
Click to load an example into the editor and run it.
The address bar updates as you go, so you can bookmark or share the result.
What exactly runs here?
Two real database engines, compiled to WebAssembly and running inside your browser tab:
| Engine | Version | How |
|---|---|---|
| PostgreSQL | 18.6 | PGlite — the actual PostgreSQL source code, built for the browser |
| SQLite | 3.54.0 | sql.js — the official SQLite library, built for the browser |
Nothing is simulated: every query, result and error comes from the real engine. Nothing leaves your browser either — there is no server behind this page. Reset database puts the sample data back.
Note
MySQL, MariaDB, SQL Server and Oracle are not available here, and we won’t fake them. MySQL and MariaDB have no stable browser build yet; SQL Server and Oracle are commercial products that can’t run in a browser. To see how the same query is written for them, use the SQL Dialect Reference.
How to use it
- Pick the engine and a sample database: Company (employees, departments, projects), Shop (customers, products, orders) or an empty one.
- Write SQL in the editor — table and column names autocomplete — and press Run or Ctrl+Enter. You can run several statements at once, separated by
;. - Each statement gets its own result: rows for
SELECT, “rows affected” forINSERT/UPDATE/DELETE, OK for everything else. - Click a table on the left to preview it, or an example to load and run it.
The link in your address bar contains your query, so you can share it.
Practice permissions (PostgreSQL)
Users and GRANT behave exactly like on a PostgreSQL server. Try this on the Company database:
CREATE ROLE analyst LOGIN;GRANT SELECT ON employees TO analyst;SET ROLE analyst;SELECT count(*) FROM employees; -- worksDELETE FROM employees WHERE id = 20; -- ERROR: permission denied for table employeesThen run RESET ROLE; to become the superuser again. The sidebar always shows who you are connected as. SQLite has no users or permissions, so this only works on PostgreSQL.
FAQ
Is my data saved?
No. The database lives in your browser tab’s memory and starts fresh when you reload the page — perfect for experimenting, DROP TABLE included.
Why does an error still change my data?
When you run several statements, the ones before the failing statement have already been executed — just like in psql or the sqlite3 shell. Wrap them in BEGIN; … COMMIT; to make them all-or-nothing.
How big is the download?
PostgreSQL is a few megabytes and SQLite about one; both download only when you open this page, and your browser caches them afterwards.
Where can I practice with set tasks?
In the SQL Exercises, on the same engines and sample data, with your results checked as you go.
Can I run the examples in the articles?
Yes. SQL examples in the PostgreSQL articles have a Run button: the block runs right under it, on the same engine, loaded on the first click, with the article’s sample data and the examples above it on the page. “Run it in the SQL Playground” opens them here instead, to change and explore.
Articles
Learn more
PostgreSQL "relation does not exist": when the table is right there
Fix PostgreSQL "ERROR: relation does not exist": check the schema and search_path, quoted names with capitals, which database you are in, and whether migrations have run.
Beginner · 4 min read
PostgreSQL "column must appear in the GROUP BY clause or be used in an aggregate function"
Fix the GROUP BY error in PostgreSQL: understand why it happens, then aggregate the column, group by it or by the primary key, or pick one row per group with DISTINCT ON.
Beginner · 3 min read
PostgreSQL "invalid input syntax for type integer": find the bad value and handle it
Fix "invalid input syntax for type integer": find empty strings and text where a number is expected, convert with NULLIF and pg_input_is_valid, import clean data.
Beginner · 3 min read
PostgreSQL "duplicate key value violates unique constraint": causes and fixes
Fix "duplicate key value violates unique constraint" in PostgreSQL: tell a real duplicate from a sequence that is out of sync, and fix both safely.
Intermediate · 4 min read
PostgreSQL "permission denied for table": causes and fixes
Fix "ERROR: permission denied for table" in PostgreSQL: check what a role can do, grant the right privileges, and fix the schema, sequence and future-table cases.
Intermediate · 4 min read