Preview status & limitations
jed is in a public preview and is not ready for production use. It is feature-rich and heavily exercised by its test suites: three independent cores (Rust, Go, and TypeScript) agree byte-for-byte on every query result and on the on-disk format, and a large conformance corpus is checked against PostgreSQL as an oracle. But automated testing is not the same as real-world mileage — jed has not been proven in production use, and bugs that only surface under real workloads should be expected. Do not use it as a system of record or for anything you can’t afford to lose. It has not yet reached a stable release.
What “0.x preview” means
- No stability guarantee. While the version is
0.x, any release may change SQL behavior, the host API, or the on-disk file format. A database file is only guaranteed readable by the jed version that wrote it. - No format migration yet. There is no automatic on-disk upgrade path between versions. Treat a preview database as reproducible or disposable, not as a system of record.
- Limited distribution. This release ships the Go module (
go get) and the website/playground. The Rust crate, thejedCLI, the npm package, and the Ruby gem build from source but are not yet published. See Installation. - Performance is not yet tuned. Some features are implemented but unoptimized — a query can run
noticeably slower than on a mature database (for example, a pattern that currently falls back to a
full table scan, or a large sort materialized before its
LIMIT). Correctness and cross-core byte-identity come first during the preview; performance work is ongoing.
Deliberate differences from PostgreSQL
jed’s standing rule is to match PostgreSQL unless there’s an overriding reason — but it is not a
drop-in PostgreSQL clone. It implements a curated subset of PostgreSQL’s surface (no wire
protocol, no pg_catalog, no extensions, DO blocks, or COPY … TO/pg_read_file escape
hatches — that curation is part of what keeps untrusted SQL safe). A few behaviors differ on purpose:
- No roles, users, or in-database
GRANT. Authorization is a per-session capability envelope the host configures (per-table privileges, anallow_ddlgate, cost budgets), enforced by the engine — not an in-database permission catalog. numericis always finite. There is noNaNorInfinity; division by zero raises22012.- Sequences are transactional.
nextval()rolls back with its transaction — chosen for determinism, where PostgreSQL’s sequences are deliberately non-transactional. - A single writer at a time. Readers never block except during the brief commit. This is not MVCC: there is one committed version plus one writer’s pending changes.
- Stricter in places, by design. jed uses its own number-literal grammar (hex, digit
underscores, and
NaNare rejected with22P02), and several conversions PostgreSQL does implicitly require an explicitCAST/::.
Each intentional divergence is recorded in the relevant design doc in the spec.
Not yet implemented
jed implements a broad surface, but notable gaps remain. As representative (not exhaustive) examples:
- Foreign-key referential actions beyond the default —
ON DELETE/ON UPDATEwithCASCADE,SET NULL, orSET DEFAULT— are rejected atCREATE TABLE(0A000);NO ACTION(the default) andRESTRICTare supported. - Some date/time surface is pending —
to_char/to_timestamp,date_part,age, and a separatetimetype. - Spill-to-disk covers
ORDER BY; the spilling hash join, aggregate, andDISTINCTare still in progress. - Composite (row) types cannot yet be a
PRIMARY KEYor index key. - A file does not yet shrink back to the OS (dead space is reused internally, but not returned).
The authoritative, always-current picture lives in the project’s spec and TODO.md.