---
title: "Online SQLite Playground with a Sample Database"
description: "SQLite playground with a sample database — run SQL in your browser on Chinook, no signup, no install. A full SQL IDE running SQLite 3.49 in WebAssembly."
url: "https://jamsql.com/tools/sqlite-playground/"
html_url: "https://jamsql.com/tools/sqlite-playground/"
generated: "2026-08-22T20:19:26.896Z"
---

# Online SQLite Playground with a Sample Database

Write and run SQL in your browser against a real, preloaded sample database — no signup, no install, no server. The window below is the browser build of [Jam SQL Studio](/): a full SQL IDE (object tree, query editor, results grid, table editor) running **SQLite 3.49.1 compiled to WebAssembly**. Pick Chinook in the connections dialog, paste one of the [example queries](#examples), and press Execute.

Loading the SQLite playground…

Runs entirely in this tab. The embedded frame hides the top bar, so use the full-screen playground for the Export and Reset buttons. [Open full-screen playground](/demo/)

The playground needs a wider screen than a phone — an object tree, an editor and a results grid do not fit side by side below about 900 pixels. [Open it full screen](/demo/) anyway, or come back on a laptop. Everything else on this page — the schema, the example queries, the limits — reads fine here.

## What is actually running

The engine is **sql.js 1.13** — the official SQLite amalgamation compiled to WebAssembly. Ask it for its version and it answers `3.49.1`. That means the SQL you write here is real SQLite, not a parser or a teaching emulator: window functions, common table expressions, `json_extract`, `PRAGMA table_info`, triggers and views all behave the way they do in the `sqlite3` CLI.

The interface is not a bespoke web page wrapped around a SQL box — it is the same React application that ships in the desktop app, with the Electron layer replaced by a browser shim. So the object explorer, context menus, Table Explorer, dependency viewer, charts and keyboard shortcuts are the real ones. What the shim cannot provide (native database drivers, the file system, the process terminal) is genuinely absent rather than faked, and the list below says exactly which parts those are.

Two files are downloaded to your browser when you start: the SQLite WebAssembly binary, and the sample database you choose. After that, every query executes inside the tab. No SQL statement, result set or uploaded file is sent to a server — there is no server-side query endpoint in this build at all.

## The sample databases

Three databases are offered in the connections dialog. Row counts below are the exact contents of the files this site ships, so a query that counts rows will agree with them until you change something.

Database

Tables

Download

What is in it

**Chinook** (start here)

11

~1 MB

A digital music store: artists, albums, tracks, playlists, customers, invoices and employees.

**Sample**

5

28 KB

`categories`, `customers`, `products`, `orders`, `order_items` — a handful of rows each, useful for testing DDL and joins from scratch.

**Lahman Baseball**

29

63 MB

Historical baseball statistics, 1871–2019: `batting` (107,429 rows), `fielding` (143,046), `appearances` (107,356), `people` (19,878), `salaries` (26,428). Use it to see how the grid behaves on real volume.

### Chinook schema and row counts

Table

Rows

Key columns

`Artist`

275

ArtistId, Name

`Album`

347

AlbumId, Title, ArtistId

`Track`

3,503

TrackId, Name, AlbumId, MediaTypeId, GenreId, Composer, Milliseconds, Bytes, UnitPrice

`Genre`

25

GenreId, Name

`MediaType`

5

MediaTypeId, Name

`Playlist`

18

PlaylistId, Name

`PlaylistTrack`

8,715

PlaylistId, TrackId

`Invoice`

412

InvoiceId, CustomerId, InvoiceDate, BillingCity, BillingCountry, Total

`InvoiceLine`

2,240

InvoiceLineId, InvoiceId, TrackId, UnitPrice, Quantity

`Customer`

59

CustomerId, FirstName, LastName, Company, City, Country, Email, SupportRepId

`Employee`

8

EmployeeId, FirstName, LastName, Title, ReportsTo, HireDate, City, Country

Invoices run from 2021 to 2025 — 83 invoices a year for the first four years and 80 in the last, so year-over-year aggregates return five rows rather than one lonely bar. Every table has real foreign keys, which is what makes the dependency viewer and the "Referenced by" tab in Table Explorer worth clicking on this data set.

## Seven queries to paste in

Connect to Chinook, open a query tab and paste any of these. Each one was run against the exact file this page serves, through the same sql.js engine the playground uses, so the results below are what you will see.

### 1\. Revenue by genre

```
SELECT g.Name AS Genre,
       ROUND(SUM(il.UnitPrice * il.Quantity), 2) AS Revenue,
       COUNT(*) AS LinesSold
FROM InvoiceLine il
JOIN Track t ON t.TrackId = il.TrackId
JOIN Genre g ON g.GenreId = t.GenreId
GROUP BY g.Name
ORDER BY Revenue DESC
LIMIT 10;
```

A three-table join with an aggregate. Rock wins with 826.65 across 835 invoice lines, then Latin at 382.14 and Metal at 261.36.

### 2\. Top customers by spend

```
SELECT c.CustomerId,
       c.FirstName || ' ' || c.LastName AS Customer,
       c.Country,
       ROUND(SUM(i.Total), 2) AS Spend
FROM Customer c
JOIN Invoice i ON i.CustomerId = c.CustomerId
GROUP BY c.CustomerId, Customer, c.Country
ORDER BY Spend DESC
LIMIT 10;
```

Note `||` for string concatenation — SQLite has no `CONCAT` in the SQL Server sense. Helena Holý of the Czech Republic tops the list at 49.62.

### 3\. Longest tracks, with album and artist

```
SELECT ar.Name AS Artist,
       al.Title AS Album,
       t.Name  AS Track,
       ROUND(t.Milliseconds / 60000.0, 1) AS Minutes
FROM Track t
JOIN Album al ON al.AlbumId = t.AlbumId
JOIN Artist ar ON ar.ArtistId = al.ArtistId
ORDER BY t.Milliseconds DESC
LIMIT 10;
```

The top two are television episodes rather than songs — 88.1 and 84.8 minutes — a good reminder that a sample database has messy edges like a real one.

### 4\. Revenue per year

```
SELECT strftime('%Y', InvoiceDate) AS Year,
       COUNT(*) AS Invoices,
       ROUND(SUM(Total), 2) AS Revenue
FROM Invoice
GROUP BY Year
ORDER BY Year;
```

SQLite stores dates as text, so date grouping goes through `strftime`. Five rows come back: 449.46 for 2021 through 450.58 for 2025. Switch the results panel to the Chart tab to plot it.

### 5\. Artists with more than five albums

```
SELECT ar.Name AS Artist, COUNT(al.AlbumId) AS Albums
FROM Artist ar
JOIN Album al ON al.ArtistId = ar.ArtistId
GROUP BY ar.ArtistId, ar.Name
HAVING COUNT(al.AlbumId) > 5
ORDER BY Albums DESC;
```

Six artists qualify, led by Iron Maiden with 21 albums and Led Zeppelin with 14.

### 6\. Employees and their managers (self join)

```
SELECT e.FirstName || ' ' || e.LastName AS Employee,
       e.Title,
       m.FirstName || ' ' || m.LastName AS ReportsTo
FROM Employee e
LEFT JOIN Employee m ON m.EmployeeId = e.ReportsTo
ORDER BY e.EmployeeId;
```

Eight rows, one `NULL` manager — Andrew Adams, the General Manager, reports to nobody. Right-click `Employee` in the tree and choose Show Dependencies to see the same self-reference drawn as a graph.

### 7\. Most-playlisted track per genre (window function)

```
SELECT Genre, Track, Plays FROM (
  SELECT g.Name AS Genre,
         t.Name AS Track,
         COUNT(*) AS Plays,
         ROW_NUMBER() OVER (PARTITION BY g.Name ORDER BY COUNT(*) DESC) AS rn
  FROM PlaylistTrack pt
  JOIN Track t ON t.TrackId = pt.TrackId
  JOIN Genre g ON g.GenreId = t.GenreId
  GROUP BY g.Name, t.Name
) WHERE rn = 1
ORDER BY Plays DESC
LIMIT 10;
```

Proof that this is a modern SQLite build: `ROW_NUMBER() OVER (PARTITION BY …)` works. "2 Minutes To Midnight" leads Metal with 10 playlist appearances.

### Bonus: writes are real

```
CREATE TABLE Favourite (Id INTEGER PRIMARY KEY, TrackId INTEGER, Note TEXT);

INSERT INTO Favourite (TrackId, Note)
SELECT TrackId, 'long one' FROM Track ORDER BY Milliseconds DESC LIMIT 5;

SELECT f.Id, t.Name, f.Note
FROM Favourite f JOIN Track t ON t.TrackId = f.TrackId;
```

DDL and DML execute against the in-tab database and are written back to browser storage, so they are still there after a refresh. The Reset button in the top bar of the full-screen playground puts the sample back exactly as shipped.

## What works here, and what does not

This is the honest split. The browser build is the desktop app minus everything that needs a native driver, a file system or a background process — which is more than a marketing page usually admits, so here it is in full.

### Works in the browser

-   Query editor with multi-statement batches, execution timings, and one result grid per statement
-   Schema-aware autocomplete from the connected database: SQL keywords, and column completions after a table name and a dot (the full table list on a bare `FROM` is a known gap in this build)
-   Object explorer tree, with Select Top 1000 Rows and Script Table as SELECT on the context menu
-   Table Explorer: browse, sort, filter, and edit cells with a preview of the generated `UPDATE` before it runs
-   Referenced-by (inbound foreign key) navigation, from `PRAGMA foreign_key_list`
-   Dependency viewer for tables and views, as a tree or a graph
-   Schema overview, table metadata, and scripting a table as CREATE, SELECT, INSERT, UPDATE or DELETE
-   Charts on any result set, drawn client-side from the returned rows
-   Copy cells, rows or a selection to the clipboard as text, TSV or HTML
-   Export the whole database back out as a `.sqlite` file; reset a sample to baseline
-   Load your own `.sqlite`, `.db` or `.sqlite3` file
-   Dark and light themes, command palette, keyboard shortcuts

### Desktop app only

-   SQL Server, PostgreSQL, MySQL, MariaDB and Oracle connections — they need native drivers a browser tab cannot load
-   Execution plans (capture, import and export)
-   Exporting a result set to CSV, Excel or JSON — copy to clipboard is the browser substitute
-   SQL notebooks: cell execution, opening and saving `.ipynb`
-   Schema compare, data compare, clone table and clone database
-   The data import wizard (CSV, XLSX, JSON into a table)
-   Backup and restore
-   The integrated terminal, and mounting a folder of `.sql` scripts
-   The MetaInfo layer: loose foreign keys, JSON-column declarations, enum columns
-   The AI workspace and the local MCP server for coding agents
-   Fetching the untruncated value of a very large cell (the grid shows the preview instead)
-   Language-server IntelliSense for T-SQL and PL/pgSQL

## Concrete limits

-   **10,000 rows per execution.** A batch returns at most 10,000 rows to the grid and marks the result truncated beyond that. The query itself still runs in full — aggregate in SQL rather than scrolling.
-   **200 MB upload ceiling**, with a warning above 50 MB. Files are checked for the `SQLite format 3` header before anything is opened, so a renamed CSV is rejected with a message instead of a stack trace.
-   **No auto-save above 25 MB.** Smaller databases are checkpointed to IndexedDB after every write; larger ones are not, because writing tens of megabytes on each statement would stall the tab. Use Export to keep those changes.
-   **Memory is the tab's memory.** The whole database lives in the page, so the 63 MB baseball file is a 63 MB download plus an in-memory copy. It works, but it is the point where you feel the difference from a desktop client.
-   **Private browsing disables persistence.** When storage is unavailable the app says so in the top bar, and your work lasts only as long as the tab.
-   **One database at a time.** Connecting to another sample closes the current one; there is no cross-database query.

## Where your data lives

Sample databases are cached in IndexedDB under two keys: a pristine baseline and, once you write to it, a modified copy. Reset simply deletes the modified copy. A file you load from disk is read by the browser's `FileReader` and handed to the WebAssembly engine — it is never uploaded, and it is cached the same local way so it is still there when you come back. Connection entries live in `localStorage`. Clearing site data for jamsql.com removes all of it.

## Frequently asked questions

### Do I need to sign up to use this SQLite playground?

No. There is no account, no email box, and no trial timer. The playground opens straight into the workspace, and the Pro features of Jam SQL Studio are unlocked in the browser build without a licence key. Nothing on this page asks who you are.

### Which SQL engine actually runs in the browser?

SQLite 3.49.1, compiled to WebAssembly and shipped as sql.js 1.13. It is the real SQLite library, so window functions, CTEs, JSON functions, PRAGMA statements, triggers and views all behave the way they do in the sqlite3 CLI. It is not a SQL parser or an emulator, and it is not a shared server database that other visitors can see.

### What sample database is loaded, and can I use my own?

Three sample databases are offered: Chinook, a music store with 11 tables (3,503 tracks, 8,715 playlist entries, 412 invoices dated 2021 to 2025); a 5-table Sample database of customers, orders and products; and the Lahman baseball statistics database, 29 tables and about 63 MB covering 1871 to 2019. You can also load your own .sqlite, .db or .sqlite3 file, up to 200 MB, from the connections dialog.

### Is my database uploaded to a server?

No. A file you open is read by the browser and handed straight to the WebAssembly engine in the same tab, and every query you run is executed there. Nothing about your data is sent anywhere. Two things are downloaded to your browser when you start: the SQLite WebAssembly binary and, if you pick one, the sample database file.

### Do my changes survive a page reload?

Yes. After a write statement the modified database is checkpointed into IndexedDB, so INSERT, UPDATE, DELETE and CREATE TABLE survive a refresh, and a Reset button restores the pristine sample. Two exceptions: databases over 25 MB are not auto-saved, so use Export to keep those changes, and private or incognito windows may block storage entirely, in which case the app warns that changes will not persist.

### What can the desktop app do that the browser playground cannot?

The browser build is SQLite only: SQL Server, PostgreSQL, MySQL and Oracle connections need the desktop app, because they require native database drivers. Execution plans, SQL notebooks, schema compare, data compare, the data import wizard, backup and restore, the integrated terminal, the MCP server for AI agents, and exporting a result set to CSV or Excel are all desktop-only too. Copying cells, exporting the whole SQLite file, and everything listed above as working are available here.

## Keep reading

-   [SQLite in Jam SQL Studio](/databases/sqlite/) — what the desktop client adds for SQLite files on disk.
-   [SQLite performance](/blog/sqlite-performance/) — indexes, `EXPLAIN QUERY PLAN` and the settings that actually matter.
-   [SQLite JSON support](/blog/sqlite-json-support-guide/) — `json_extract`, generated columns and indexing JSON paths.
-   [Table Explorer](/docs/table-explorer/) and [Query Editor](/docs/query-editor/) — the two surfaces you are using in the frame above.

## Need more than SQLite in a tab?

The desktop app is the same workspace with the parts a browser cannot host: SQL Server, PostgreSQL, MySQL, Oracle and SQLite connections, execution plans, SQL notebooks, schema and data compare, an import wizard, and an MCP server your AI agent can query.

[Download Free](/#download) [Quick Tour](/quick-tour/)

Free for personal use • No account required • Mac, Windows, Linux

## More free SQL tools

[

### All Free SQL Tools

The full collection — formatters, converters, and generators for everyday SQL work.

](/tools/)[

### SQL Formatter

Format and beautify SQL with dialect-aware rules for T-SQL, PostgreSQL, MySQL, PL/SQL, and SQLite.

](/tools/sql-formatter/)[

### CSV to SQL Converter

Paste CSV or spreadsheet data and get INSERT statements or a CREATE TABLE script with inferred column types.

](/tools/csv-to-sql/)[

### SQL Data Type Converter

Map data types across SQL Server, PostgreSQL, MySQL, Oracle, and SQLite — with precision and pitfall notes.

](/tools/sql-data-type-converter/)