PGlite:把完整 Postgres 编译进浏览器的 WASM 数据库

数据库
PostgreSQL
WASM
开源
前端
2026/9/30
·

阅读时间: 大约 12 分钟

PGlite:把完整 Postgres 编译进浏览器的 WASM 数据库

PGlite 官网首页:Embeddable Postgres,浏览器中本地运行完整 Postgres

「Koala 聊开源」科技周报曾介绍 Crunchy Data 的 Postgres Playground——一个无需在后端起数据库实例、直接在浏览器里就能敲 SQL 的学习环境。其背后的技术脉络,在今天已经收敛到一个事实上的标准:PGlite。它由 Electric(原 ElectricSQL,现 Electric DB Inc.)开源(Apache-2.0),是把 PostgreSQL 整体编译为 WebAssembly(WASM)后封装成 TypeScript 客户端的嵌入式数据库。本文基于 PGlite 官方仓库、官网与 Crunchy Data 官方博客,梳理它到底解决了什么问题、怎么做到的,以及它的硬边界在哪里。

一、背景:为什么要把 Postgres 塞进浏览器

长期以来,浏览器端应用的数据层存在一个断层:要么用 localStorage / IndexedDB 这类 KV 或键值存储,能力弱、不支持 SQL 与事务;要么远程连一个服务器上的 Postgres,受网络与延迟制约,离线即不可用。前端工程师想要的是「本地就能跑一个真正的 Postgres」,以便:

  • 做**本地优先(local-first)**应用,离线可用、在线再同步;
  • 在文档、教程、IDE 插件、客服工具里内嵌一个可交互的 SQL 沙箱;
  • 用与生产环境**同一套 SQL 方言与扩展(JSONB、数组、pgvector、PostGIS)**做开发与测试,避免「本地 SQLite、生产 PG」的方言漂移。

Crunchy Data 在 2022 年 8 月的官方博客(作者 Craig Kerstiens)中就给出了早期答案:Postgres Playground 把 Postgres 编译为 WASM,在浏览器里分配约 512MB 内存运行一个实例,并预置数据集与引导式教程(psql 基础、分区、性能分析、Join、索引、PostGIS、窗口函数与 CTE)。官方特别强调:后端没有跑任何额外的 Postgres 实例,全部计算发生在浏览器内;也正因浏览器沙箱限制,除了内置的 psql 交互界面外,无法从外部直连这个实例。

二、是什么:PGlite 的定位

PGlite 把上述思路产品化、库化。官方仓库的定位很直接:它是「a WASM build of Postgres packaged into a TypeScript client library」,可以在浏览器、Node.js、Bun、Deno 中运行,且无需安装任何其他依赖。安装后一行代码即可起一个内存库:

import { PGlite } from "@electric-sql/pglite";
const db = new PGlite();
await db.query("select 'Hello world' as message;");

它既可以是易失的内存数据库,也可以持久化到磁盘(Node/Bun/Deno 写文件系统)或浏览器的 IndexedDB(new PGlite("idb://my-pgdata"))。也就是说,开发者拿到的不是「Postgres 风格的子集」,而是一个真正的 Postgres——包括它的数据类型、SQL 语法与扩展生态。

PGlite 官网三大特性:Lightweight / Extendable / Reactive

三、技术机制:为什么不套一个 Linux 虚拟机

很多人第一反应是「在浏览器里跑 Linux 虚拟机再装 Postgres」。官方明确指出:与以往的「Postgres in the browser」项目不同,PGlite 不使用 Linux 虚拟机,它就是 Postgres 本身的 WASM 构建。

其关键技术点有两个:

  1. Emscripten 把 C 编译为 WASM。PostgreSQL 原生采用「连接进来就 fork 一个新进程」的多进程模型,而 Emscripten 编译出的 WASM 程序无法 fork 新进程,只能单线程顺序执行,这与 Postgres 的进程模型天然冲突。
  2. 复用 Postgres 的「单用户模式(single user mode)」。Postgres 自带一个原本用于引导启动与崩溃恢复、供命令行使用的单用户模式。PGlite 在这个模式之上构建了一条输入/输出通路,让编译成 WASM 的 Postgres 可以通过函数调用与 JS 层交互,而不必 fork 进程。

代价也因此写在明处:PGlite 是单用户/单连接的。它不是为多并发客户端设计的服务端,而是一个嵌入到单个 JS 运行时里的库。扩展方面,它提供动态扩展加载机制,官方明示支持 pgvector(向量检索)与 PostGIS(空间数据),这意味着在浏览器里做向量相似度查询、地理空间查询都成为可能。

四、关键数据(官方口径)

指标数值来源口径
体积完整 WASM 构建 < 3MB(gzipped)官网首页「Lightweight」
运行环境浏览器 / Node.js / Bun / Deno官方 README
持久化内存、文件系统(服务端运行时)、IndexedDB(浏览器)官方 README
并发模型单用户 / 单连接官方 README 明示
扩展pgvector、PostGIS,动态加载官网「Extendable」
GitHub Stars / npm 周下载约 16.1K Stars、约 21.4M 周下载官网首页截图(2026-09)
开源协议Apache-2.0GitHub 仓库
Crunchy Playground 内存配额约 512MB(早期配置)Crunchy Data 官方博客

需要说明的是:「<3MB」是 gzip 压缩后的分发体积,不是运行时常驻内存;WASM 实例加载后解包、配合 Postgres 自身缓冲,实际内存占用远大于此,Crunchy 早期示例直接给浏览器实例分配了 512MB 就是旁证。Stars 与下载量是官网前端实时渲染数字,会随时间变动,此处为截图时点的约数。

五、评测方法与口径批判

PGlite 官方没有发布独立的 benchmark 数字(如每秒事务数、查询延迟),官网与 README 强调的是「体积、兼容性、可扩展」这类工程指标,而非吞吐。这本身就是一个需要警惕的口径:

  • 单连接 + WASM 单线程的架构,决定了它不能拿来对标服务端 Postgres 的 QPS;任何「PGlite 多快」的讨论都应放在「嵌入式、本地、单用户」的前提下,否则就是拿苹果比橘子。
  • 「完整 Postgres」指的是 SQL 方言与扩展兼容度,而非并发、复制、高可用这些服务端能力;它没有流复制、没有连接池、没有故障切换。
  • Crunchy Playground 的 512MB 内存是「当前配置」,官方博客也明说后续可能调整,不能当作固定规格。

六、适用与不适用场景

适合:

  • 本地优先应用、离线优先的协作工具,本地存真 Postgres、再通过同步层上云;
  • 教程、文档、AI 工具里的可交互 SQL 沙箱(这正是 Crunchy Playground 的初心);
  • 需要在前端跑 pgvector 做本地向量检索、或 PostGIS 做空间分析的轻量场景;
  • 单页应用中用 SQL/JSONB 替代手写状态管理,获得事务与查询能力。

不适合:

  • 需要多连接、高并发读写的后端服务——那是服务端 Postgres 的地盘;
  • 对体积极度敏感的首屏关键路径(3MB WASM 仍需按需加载/动态加载扩展);
  • 需要流复制、主从高可用、水平扩展的生产数据库。

七、客观分析:优势与局限

优势:

  1. 方言一致性:本地与生产用同一套 Postgres SQL 与扩展,消除 SQLite/PG 差异;
  2. 零依赖、跨运行时:一套包同时跑在浏览器、Node、Bun、Deno;
  3. 不依赖虚拟机:纯 WASM 构建比「浏览器里跑 Linux」更轻、更快启动;
  4. 生态顺势:背靠 Electric 的本地优先/实时同步路线,reactive live query 与后续同步能力是其差异化方向。

局限:

  1. 单连接硬约束:无法作为多客户端共享数据库;
  2. 无服务端能力:复制、高可用、连接池一概没有;
  3. 体积与加载成本:3MB gzip 对移动端首屏仍不轻,扩展需按需动态加载;
  4. 生态年轻:相对成熟服务端,周边 ORM/工具链的深度适配仍在演进。

八、它意味着什么

PGlite 代表了一个明确趋势:数据库正在从「远端服务」下沉为「可嵌入的运行时组件」。当 Postgres 这种重量级关系库都能以 <3MB 的 WASM 形态跑在浏览器里,前端就第一次拥有了「与生产同构」的本地数据层。对开发者而言,它不是要替代服务端 Postgres,而是把 SQL 的能力边界推到了离用户最近的地方——做工具、做教程、做本地优先产品的团队,值得认真评估。

参考来源