Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

A pivot and charting UI for DuckDB, ClickHouse and PostgreSQL

If your data already lives in an analytical database, you do not need to load it into Perspective’s engine to explore it. A virtual server implements Perspective’s protocol on top of an external engine: when a user drags a column to Group By, adds a filter or scrolls the grid, the resulting View configuration is translated into a native query, executed by the database, and only the visible window of the result is returned.

The user sees the same <perspective-viewer> — data grid, pivot table, WebGL charts, maps, saved layouts — and the database does the work.

EngineWhere it runsGuide
DuckDB-WASMIn the browser, no serverJavaScript
DuckDBPython serverPython
ClickHouseBrowser or Python serverJavaScript, Python
PostgreSQLPython serverPython
PolarsPython serverPython
Anything elseYour codeCustom virtual servers

DuckDB in Python

import duckdb
import tornado.ioloop
import tornado.web
from perspective.handlers.tornado import PerspectiveTornadoHandler
from perspective.virtual_servers.duckdb import DuckDBVirtualServer

conn = duckdb.connect()
conn.execute("CREATE TABLE trips AS SELECT * FROM 'trips/*.parquet'")

app = tornado.web.Application([
    (r"/websocket", PerspectiveTornadoHandler, {
        "perspective_server": DuckDBVirtualServer(conn),
    }),
])

app.listen(8080)
tornado.ioloop.IOLoop.current().start()
const websocket = await perspective.websocket("ws://localhost:8080/websocket");
const table = await websocket.open_table("trips");
document.querySelector("perspective-viewer").load(table);

DuckDB-WASM, entirely in the browser

With DuckDB-WASM the whole stack — database, query translation and UI — runs in the browser tab. Because Perspective does not intercept your SQL, DuckDB’s own Parquet, S3 and HTTP readers are available for loading data. See the DuckDB-WASM guide.

DuckDB-WASM can also attach a whole DuckLake lakehouse over HTTPS; see the DuckLake case study.

When to use a virtual server, and when not to

Use a virtual server when the data is larger than memory, already lives in the database, or must not leave it. Use Perspective’s own engine when the data is streaming: its Table applies update() calls incrementally and pushes changes to every view, which a request/response SQL engine does not do. The two can be mixed — one <perspective-viewer> workspace can hold panels backed by different engines.

Examples