pglite-fusion: an SQLite database living inside a PostgreSQL column
Embed an SQLite database in your PostgreSQL table. AKA multitenancy has been solved.
At a glance
- What is it?
- A PostgreSQL extension that stores a whole SQLite database as a column value and exposes SQL functions to query and modify it. The README's claim that multitenancy is solved is a slogan, but the mechanism is concrete.
- Who is it for?
- pglite-fusion suits a team that wants per tenant data isolated in its own database file while keeping one PostgreSQL instance to operate, and that is comfortable writing SQL that shells into SQLite. It does not suit a workload that needs cross tenant queries in one statement, since the embedded database is reached through functions rather than joined relationally.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 71 days ago.
- What is it written in?
- Mainly Nix, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A column that holds an entire SQLite database
The idea is one sentence: embed an SQLite database in a PostgreSQL table. Each row can carry its own SQLite database as a binary value, which is what makes the multitenancy pitch work, because a tenant's rows cannot be reached by another tenant's queries since they are separate database engines rather than rows filtered by a column. The extension adds a SQLITE column type and the functions to work with it. The repository's one-line self description is that multitenancy has been solved, which is marketing rather than a technical claim, but the underlying mechanism is specific and inspectable. The implementation is a Rust crate built on pgrx, the framework for writing PostgreSQL extensions in Rust, with rusqlite providing the embedded SQLite engine and serde handling serialization.
The function set: initialise, query, execute, extract
The API is a small set of SQL functions with clear division of labour. init_sqlite takes an initialisation query and returns a database with that query already applied, which is what the column default in the demo uses. query_sqlite runs a query against an embedded database and returns the rows as JSON-encoded values, and empty_sqlite produces an empty database for cases where no default is wanted. execute_sqlite runs a statement such as an INSERT, UPDATE or DELETE and returns the modified database as a new binary object, which is why the demo assigns it back to the column. Reading a value out of a result row needs a separate accessor: get_sqlite_text, get_sqlite_integer and get_sqlite_real take a row and a column index. The demo wires those together with a subquery and json_agg.
CREATE TABLE people (
name TEXT NOT NULL,
database SQLITE DEFAULT init_sqlite('CREATE TABLE todos (task TEXT)')
);For writing, the pattern is always assign the result back:
UPDATE people
SET database = execute_sqlite(
database,
'INSERT INTO todos VALUES (''solve multitenancy'')'
)
WHERE name = 'frectonz';Two more inspection functions exist for schema work: list_sqlite_tables returns table names and sqlite_schema returns the CREATE TABLE statements.
One Docker image per PostgreSQL major version
The fastest way to try it is the published image, which already has the extension installed. The default image runs PostgreSQL 18:
docker run --network=host frectonz/pglite-fusionThe README then lists tagged images for the other supported majors, pg14, pg15, pg16, pg17 and pg18, each run the same way with the tag appended. Once the container is up, you connect with psql:
psql postgresql://postgres@localhost:5432/Inside that session you create the extension and work through the demo. One thing to notice is a small gap between the two sources of truth. The Docker tags in the README start at PostgreSQL 14, while the crate manifest lists cargo features for pg13 through pg18 with pg18 as the default. A version 13 deployment would need a build from source rather than a published image.
Building from source with Nix and pgrx
The source route uses a Nix flake for the toolchain and pgrx for the extension harness. The README's sequence is:
git clone [email protected]:frectonz/pglite-fusion.git
cd pglite-fusion
nix develop
cargo pgrx init --pg18 download # this will take some time, since you are compiling postgres from source
cargo pgrx run # this will drop you into a psql repl, you can then follow the example shown aboveThe init step compiles a PostgreSQL from source, which the README flags as slow, and the run step drops you into a psql repl against a locally built server so you can follow the same demo. The repository root holds a flake.nix and flake.lock for the Nix environment, a .envrc for direnv, a pglite_fusion.control file in the Debian packaging style, and a Cargo.toml pinning pgrx at 0.18.1 and rusqlite at 0.40.2 with the bundled, backup and serialize features enabled, which is why the extension carries its own SQLite build rather than linking a system one.
Parallel safety with two documented exceptions
The API documentation states that every function is parallel-safe except for two. import_sqlite_from_file loads a SQLite database from a path into PostgreSQL, and export_sqlite_to_file writes an embedded database out to disk. Both touch the filesystem, which is why they are called out, and both are useful for moving data in and out of the extension: a backup written to a file, or an existing SQLite file imported into a column. Other housekeeping functions are included as well: vacuum_sqlite runs the SQLite VACUUM command to reclaim unused space, and count_sqlite_rows counts the rows of a named table inside the embedded database. For a developer thinking about storage growth inside tenant rows, VACUUM is the function to know about, because every write in the demo pattern produces a new binary value.
Version 0.0.7, no releases, MIT licence
State of the project is the part to weigh. The crate manifest gives the version as 0.0.7 with edition 2021, which places it clearly before a stable release, and the repository has no GitHub releases, so there is no tag to pin a deployment to and no changelog to consult beyond the commit history. The repository is not archived and the last push was on 2026-08-13, so the code is still being worked on. The licence is MIT, which is permissive for a dependency you ship inside a database extension, and the manifest's release profile is tuned for production, with fat link time optimisation, a single codegen unit and an opt level of 3. A top level META.json is present for packaging metadata, and the crate builds as both a cdylib and a library so it can be loaded by PostgreSQL and tested in process.
Editorial conclusion
pglite-fusion suits a team that wants per tenant data isolated in its own database file while keeping one PostgreSQL instance to operate, and that is comfortable writing SQL that shells into SQLite. It does not suit a workload that needs cross tenant queries in one statement, since the embedded database is reached through functions rather than joined relationally. Before adopting, pin the version deliberately, because the crate manifest still says 0.0.7, and check that the PostgreSQL major version you run matches the image tag you pull.
Frequently asked questions
How do I run pglite-fusion?
Run docker run --network=host frectonz/pglite-fusion for the default PostgreSQL 18 image, then connect with psql postgresql://postgres@localhost:5432/. Tagged images exist for pg14 through pg18.
Which PostgreSQL versions does pglite-fusion support?
The crate manifest defines cargo features for pg13, pg14, pg15, pg16, pg17 and pg18, with pg18 enabled by default. The README publishes Docker images for PostgreSQL 14 through 18.
How do I query the SQLite database stored in a PostgreSQL column?
Call query_sqlite with the column value and a SQL string, which returns JSON-encoded rows. Values are then extracted with get_sqlite_text, get_sqlite_integer or get_sqlite_real given a row and a column index.
How do I build pglite-fusion from source?
Clone the repository, run nix develop, then cargo pgrx init --pg18 download to build a PostgreSQL from source, and cargo pgrx run to start a local server in a psql repl.
Which pglite-fusion functions are not parallel-safe?
The documentation states that every function is parallel-safe except import_sqlite_from_file and export_sqlite_to_file.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/frectonz-pglite-fusion)Was this useful?