PostgreSQL Playground

This postgres playground runs PostgreSQL 18.3 itself, compiled to WebAssembly, inside the page you are reading. Statements execute against a database that lives in your browser tab, so nothing you type reaches a server. The first Run seeds three tables with foreign keys to query.

Playground

Tables and rows stay in this browser's IndexedDB until you press Reset. Ctrl or Cmd with Enter runs the statements.

What it does and how to use it

The editor opens on a three-table join over customers, orders and order_items, though nothing is running behind it yet. With the first press of Run the engine downloads and the seed script creates those three tables, so the join has something to answer with. Press it again, or use Ctrl+Enter, and every statement in the box executes in order. Whatever returns rows gets a table under the column names Postgres reported, while the rest report their command tag and how many rows they touched.

When the engine refuses a statement, its own message is what you read, SQLSTATE and character position included, together with the DETAIL line naming the key that a constraint tripped over. The Schema tab re-reads information_schema after each run, so a CREATE TABLE turns up there straight away. Reset asks a second time before erasing anything, and a freshly seeded database takes the old one's place.

What runs in the browser, and what does not

select version() answers PostgreSQL 18.3 (PGlite 0.5.8) on wasm32-unknown-emscripten, and that banner is not decoration. Because this is the Postgres source built for WebAssembly rather than a parser that imitates the dialect, the planner and the wording of every error are the ones your own server would produce. All of the following ran here on 2026-09-11, in headless Chromium against the page you have open.

  • EXPLAIN ANALYZE on the query in the editor, which answers with its 33-line plan, actual timings and buffer counts included
  • Window functions, WITH RECURSIVE, jsonb_path_query, to_char and regexp_replace
  • Partial and expression indexes, and a DEFERRABLE INITIALLY DEFERRED foreign key letting a child row land before its parent inside one transaction
  • 10,000 rows written from generate_series in 100 ms

Four contrib modules sit ready for a CREATE EXTENSION, namely uuid-ossp, pg_trgm, citext and hstore. Ask for pgcrypto and Postgres replies that the extension is not available, since each one is a separate download and Postgres 18 answers gen_random_uuid() and uuidv7() without any extension at all.

Whatever needs a host machine is gone. dblink and postgres_fdw are not available, psql backslash commands such as \dt are client syntax and come back as a syntax error, and COPY ... FROM STDIN is refused by this page before it reaches the engine, because the server would sit waiting for copy data that no tab can hand it. Unlike db-fiddle and the other hosted sandboxes, nothing is uploaded, which also means there is no link to share and nobody else looking at your rows.

FAQ

Frequently asked questions

It runs a PostgreSQL 18.3 server compiled to WebAssembly in your browser tab and executes the SQL you type against it. Tables, rows and query plans all stay in that tab, since no database of ours sits behind the page.

select version() reports PostgreSQL 18.3 under PGlite 0.5.8, so Postgres 18 built-ins such as uuidv7() answer here. Four extensions are loaded and work after create extension, namely uuid-ossp, pg_trgm, citext and hstore. Anything else, pgcrypto included, reports that the extension is not available.

Yes, in this browser's IndexedDB under the name /pglite/seedfast-playground, so coming back tomorrow leaves your tables where they were. Reset deletes that store and seeds a fresh database, while a window that blocks IndexedDB gets a memory-only instance instead.

Paste the CREATE TABLE and INSERT statements and run them, which is how a plain SQL dump goes in. This version has no file upload and no pg_restore, and it refuses COPY ... FROM STDIN, which would leave the engine waiting for data the page cannot send.

A headless Chromium run on this page wrote 10,000 rows from generate_series in about 100 milliseconds. The ceiling is the memory your tab gets and the IndexedDB quota the browser grants this origin, neither of which we set.

Nothing does. The page has no endpoint that receives SQL, and the engine is a WebAssembly module downloaded once and then run locally, which is also why a query here carries no share link.

The playground is free and asks for no account. Once a statement does what you meant, the formatter and the syntax checker under Related tools take it further, and the docs page below walks through filling a real database.