OrioleDB: a table access method that replaces PostgreSQL's heap, undo log and VACUUM included
OrioleDB – building a modern cloud-native storage engine (... and solving some PostgreSQL wicked problems)
At a glance
- What is it?
- OrioleDB is a PostgreSQL storage engine shipped as an extension, currently in public beta. It swaps heap storage for an undo-log MVCC design and 64-bit transaction IDs, which removes table VACUUM and XID wraparound, at the cost of building a patched PostgreSQL first.
- Who is it for?
- Adopt OrioleDB for experiments, benchmarking and testing the removal of table VACUUM and XID wraparound, and only on a build that matches the commit pinned in .pgtags. Do not adopt it for production: the README states public beta status and explicitly does not recommend production usage, and it points commercial interest at [email protected] instead.
- Can I use it commercially?
- Yes. Apache-2.0 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 3 days ago.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 27, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The PostgreSQL problems OrioleDB is aimed at
OrioleDB targets three long-standing properties of PostgreSQL's heap storage. The first is bloat: old tuple versions stay in the main storage and dedicated VACUUM processes have to reclaim them, which the README calls "a significant and common cause of system performance deterioration and database outages". The second is the 32-bit transaction identifier and its wraparound problem; OrioleDB implements 64-bit transaction identifiers by default, which removes it. The third is scalability on modern hardware, where the README points at buffer mapping and atomic operations during page reads as legacy CPU bottlenecks.
The audience is narrow and technical. This is not a drop-in replacement for a managed PostgreSQL instance: it is an extension that requires a patched PostgreSQL build, and the README's Status section says it is "recommended for experiments, testing, benchmarking, etc., but is not recommended for production usage". If you run PostgreSQL and have never had to schedule a VACUUM or watch transaction ID age, you are not the user. If you operate large tables where autovacuum lags behind write traffic, the design is directly aimed at your problem.
How OrioleDB stores rows: undo log, copy-on-write checkpoints, row-level WAL
OrioleDB is a table access method, built on PostgreSQL's table access method framework and other standard extension interfaces. Rows live in a B-tree implementation, visible in the source layout under src/btree, with index access handlers under src/indexam and catalog caches under src/catalog.
MVCC works differently from heap. Old tuple versions are evicted into an undo log rather than left in main storage, and the README describes undo chains with page-level undo records that let the system reclaim space from deleted tuples quickly. Combined with page merges, the README states these mechanisms "eliminate bloat in the majority of cases" and that dedicated VACUUMing of tables is not needed. That is a strong claim and it is the one to test rather than assume: the README says "in the majority of cases", not in all cases.
Checkpoints are copy-on-write, which the README says provides a structurally consistent snapshot of data at every moment and suits modern SSDs. That in turn allows row-level WAL logging, which the README describes as easy to parallelize (done) and suitable for active-active multimaster (planned). Note the tense: parallel apply is implemented, active-active multimaster is not. The README also claims no buffer mapping and lock-less page reading, with in-memory pages linked directly to storage pages and page reads that avoid atomic operations.
Installing OrioleDB with Docker and creating your first table
The README offers two paths. Docker is the short one, with images for amd64 and arm64v8 under Alpine Linux, published under the orioledb/orioledb repository on Docker Hub. The README pulls the PostgreSQL 17 tag:
docker pull orioledb/orioledb:latest-pg17Running it looks like running the official postgres image, with one warning the README makes in a comment: set the default locale to C or POSIX, or use an ICU locale. The example passes the locale through POSTGRES_INITDB_ARGS:
docker run --name some-postgres -e POSTGRES_PASSWORD=... -e POSTGRES_INITDB_ARGS="--locale=C" -d -p5432:5432 orioledb/orioledb:latest-pg17After the container is up you have a PostgreSQL server on port 5432. The extension is what supplies the storage engine, so the table you create has to opt into it; the README does not print a CREATE TABLE example, so check doc/usage/getting-started.mdx for the exact syntax before assuming a plain CREATE TABLE uses OrioleDB.
Building from source is the longer path and it is where most first attempts fail. OrioleDB requires PostgreSQL with extensibility patches from github.com/orioledb/postgres, checked out at the exact commit listed for your major version in the .pgtags file. The README's own example reads the file rather than hardcoding a hash:
$ git clone https://github.com/orioledb/orioledb
$ cd orioledb
$ cat .pgtags
17: 7050019fd74d0d841040edc49ee1e16364a8b589
16: e5ef9e6a6d21f8e69e1d4bddcd4cdb83f054ca0bThat file is the contract. The README states the build verifies the patchset and refuses to compile against any other one, and there is a check_patchset_version.py at the repository root that enforces it. You also need the libzstd development package and Python 3.5+ with the testgres package; requirements.txt pins testgres==1.11.0 along with psycopg2, boto3, moto, Flask and pg8000, which suggests the Python dependencies are mostly for tests and the S3 loader rather than the server itself.
The patched PostgreSQL requirement is the real adoption cost
The most consequential constraint is not in the feature list. OrioleDB compiles against a specific patched PostgreSQL commit per major version, and the build refuses anything else. That means you cannot install it into an existing distribution PostgreSQL, and you cannot track PostgreSQL minor releases on your own schedule: you rebuild PostgreSQL when .pgtags moves.
The README's example makes this explicit, telling the reader to substitute the value from .pgtags and not copy the published hash because "it moves". A moving pin is normal for a project tracking upstream, but it puts the upgrade cadence in the maintainers' hands. If your deployment requires staying on a vendor-supported PostgreSQL build, OrioleDB is the wrong tool regardless of what it does for VACUUM.
There is a second, quieter constraint. The README says active-active multimaster is planned, not shipped, so the distributed story is a design property today rather than something to deploy. Treat the row-level WAL as the part you can evaluate now.
OrioleDB compared with PostgreSQL's default heap storage
The honest comparison is not OrioleDB against another extension. It is OrioleDB against the heap and VACUUM you already run.
With heap, dead tuples occupy table pages until VACUUM reclaims them, autovacuum is a background process you tune, and transaction ID wraparound is a maintenance event you monitor. With OrioleDB, per the README, old versions go to undo chains, page-level undo records plus page merges reclaim deleted-tuple space, dedicated table VACUUM is not needed, and transaction identifiers are 64-bit so wraparound does not arise. The buffer mapping layer is gone as well, replaced by direct links between in-memory and storage pages.
What you give up is the thing heap users take for granted: you are running a patched server, not stock PostgreSQL. Every operational tool, extension and assumption that depends on heap internals has to be re-checked against a table access method, and the catalog caches under src/catalog are OrioleDB's own. The README's own status line is the fairest summary of the trade: benefits are real enough to be worth testing, not settled enough to be worth betting production on.
Licence, patent grant and what upgrading costs you
OrioleDB is dual-licensed under Apache License 2.0 and the PostgreSQL License, with the SPDX identifier given as Apache-2.0 OR PostgreSQL. You choose either licence to govern your use, and all contributions are made under both. The repository carries LICENSE-APACHE.txt and LICENSE-POSTGRESQL.txt.
There is a separate patent grant from Supabase, documented in PATENTS.txt. That file is the one to read if patent exposure matters to your organisation; the README points at it without summarising its terms, and nothing here should be read as legal advice.
The practical upgrade cost follows from the patchset pin. Releases are frequent and small: beta17 arrived on 2026-09-04, beta16 on 2026-06-18, and nightly builds appear between them. The last push to the repository was on 2026-09-23. The repository is not archived. Upgrading means re-checking .pgtags, rebuilding the patched PostgreSQL at the new commit, rebuilding the extension, and running make installcheck with IS_DEV=1, which the README notes is required for the tests to actually run. Budget for a server rebuild, not a package upgrade.
Editorial conclusion
Adopt OrioleDB for experiments, benchmarking and testing the removal of table VACUUM and XID wraparound, and only on a build that matches the commit pinned in .pgtags. Do not adopt it for production: the README states public beta status and explicitly does not recommend production usage, and it points commercial interest at [email protected] instead. Before anything else, verify that the .pgtags commit for your major version is the one your patched PostgreSQL was built from, because the build refuses to compile against any other patchset.
Frequently asked questions
What is OrioleDB?
OrioleDB is a storage engine for PostgreSQL delivered as an extension, built on the table access method framework. It replaces heap storage with undo-log MVCC, copy-on-write checkpoints and row-level WAL, and implements 64-bit transaction identifiers. The README describes it as having public beta status.
Can PostgreSQL run with OrioleDB instead of its default storage engine?
Yes, but only on a patched build. OrioleDB requires PostgreSQL with extensibility patches from github.com/orioledb/postgres at the exact commit listed for your major version in .pgtags, and the build refuses to compile against any other patchset. The Docker images under orioledb/orioledb package that combination already.
Does OrioleDB still need VACUUM?
The README states that dedicated VACUUMing of tables is not needed, because old tuple versions are evicted into undo chains and page-level undo records plus page merges reclaim deleted-tuple space. It qualifies this by saying bloat is eliminated in the majority of cases, not all of them.
Is OrioleDB ready for production?
No. The README's Status section says OrioleDB has public beta status and is recommended for experiments, testing and benchmarking but not for production usage, and directs anyone interested in production benefits to contact [email protected].
How do I install OrioleDB?
The README gives two routes: pull orioledb/orioledb:latest-pg17 from Docker Hub and run it like a postgres container with the locale set to C, POSIX or an ICU locale, or build the patched PostgreSQL from .pgtags and then build the extension with USE_PGXS=1. The Docker route is the shorter one.
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/orioledb-orioledb)