DecentDB vs H2: When to Choose Which¶
This document helps developers decide between DecentDB and H2 for embedded SQL workloads. Both can run inside an application process, but they serve different ecosystems and different production assumptions.
Versions compared: DecentDB 2.15.0 workspace behavior vs public H2 documentation as of 2026-06-28.
Scope note: This page focuses on H2 as an embedded Java/JDBC database. H2 can also run in server mode and in-memory mode; those are called out where they materially change the decision.
See also: DecentDB vs SQLite, DecentDB vs DuckDB, SQL Feature Matrix, and SQL Reference.
They Overlap Mostly in JVM Applications¶
H2 is a mature Java relational database with JDBC API support, embedded and server modes, disk and in-memory databases, transaction support, MVCC, a small pure-Java footprint, browser console tooling, encryption, and full-text search.
DecentDB is a Rust-native embedded relational database with a C ABI and multi-language bindings. It is not a Java-only database and does not try to be an in-memory test double for other database engines.
The short version:
- Choose H2 when the project is JVM-centered, the JDBC ecosystem is the deciding factor, or the database is primarily an in-memory/test database.
- Choose DecentDB when the database is durable application state, needs to work consistently across multiple languages, or needs DecentDB-native branch, sync, policy, and crash-testing surfaces.
At a Glance¶
| Dimension | DecentDB | H2 |
|---|---|---|
| Core identity | Rust-native embedded relational database | Java SQL database engine |
| Primary ecosystem | Rust plus C ABI bindings for many languages | JVM/JDBC |
| Modes | Embedded local database; Web/WASM support through DecentDB surfaces | Embedded, server, in-memory, disk-based |
| SQL direction | Practical Postgres-like application SQL subset | H2 SQL with compatibility modes for selected dialect behavior |
| Default durability posture | WAL + fsync-on-commit by default for native files | Depends on H2 mode, URL options, and storage configuration |
| Concurrency model | One writer, many readers; local native cross-process WAL coordination when supported | MVCC and Java engine concurrency; exact behavior depends on mode |
| Best test use | Test DecentDB behavior directly | Fast JVM tests, Spring/JDBC fixtures, in-memory database |
| Best production use | Durable embedded app data with DecentDB features | JVM-local SQL where H2's engine and tooling are acceptable |
| Tooling | DecentDB CLI, SQL/CLI sync and branch tooling, bindings | JDBC, H2 Console, Java tooling |
| Search | Full-text and trigram substring indexes | Full-text search support |
| Security features | TDE, row policies, projection masks, audit context | Encrypted databases and user/role features |
| License | MIT or Apache-2.0 | EPL/MPL dual license |
When DecentDB Is the Better Fit¶
1. The database is production application state, not just a test fixture¶
H2 is widely used as a convenient embedded or in-memory database in Java tests. That is a legitimate use. It is less compelling when the real requirement is a durable local database used by production applications across runtimes.
DecentDB's default native-file posture is durability-first:
BEGIN;
INSERT INTO events (kind, payload) VALUES ($1, $2);
COMMIT; -- WAL-backed and fsynced before returning by default
If your product ships a local database file that must survive power loss and be inspected by non-JVM tooling, DecentDB is the more direct fit.
2. You need the same database from several languages¶
DecentDB exposes one engine through a stable C ABI and maintained bindings:
- Rust;
- C/C++;
- Python;
- .NET;
- Go;
- Java;
- Node.js;
- Dart.
H2 is strongest in JVM applications. It can be reached through JDBC and server mode, but its primary advantage is Java-native deployment. If your product is a polyglot CLI, desktop app, server component, and binding surface, DecentDB's language strategy is more aligned.
3. You need local branch/diff/restore workflows¶
DecentDB includes database-native local validation workflows:
decentdb snapshot create --db app.ddb --name before-migration
decentdb branch create --db app.ddb --name migration-test --from before-migration
decentdb exec --db app.ddb --branch migration-test --sql "ALTER TABLE users ADD COLUMN tier TEXT"
decentdb branch diff --db app.ddb --left main --right migration-test
H2 users can copy files, export SQL, use migration frameworks, or rely on JVM test workflows. DecentDB is better when branch/diff/restore is part of the database product itself.
4. You want local-first sync state inside the database¶
DecentDB exposes sync state as queryable local data:
SELECT * FROM sys_sync_status;
SELECT * FROM sys_sync_journal ORDER BY sequence DESC LIMIT 20;
SELECT * FROM sys_sync_conflicts;
SELECT * FROM sys_sync_doctor;
H2 can be embedded in applications that implement sync, but H2 itself is not primarily a local-first sync engine. If sync journals, scoped exchange, conflicts, retention, and diagnostics should be first-class database surfaces, DecentDB is the better fit.
5. You need row policies, projection masks, and audit context locally¶
DecentDB includes engine-enforced application data controls:
SET AUDIT CONTEXT actor = 'support-user-17';
CREATE POLICY tenant_filter ON tickets
USING tenant_id = current_tenant();
CREATE MASK phone_mask ON customers(phone)
USING '***' || right(phone, 4);
H2 supports database users and SQL features, but DecentDB's policies, masks, and audit context are designed for embedded application data governance.
6. You do not want a JVM dependency¶
H2's pure-Java distribution is a strength for Java applications. It is a cost for native CLIs, Rust services, Go applications, Python packages, or small native binaries that do not otherwise need a JVM.
DecentDB is a native library and CLI. Choose it when "no Java runtime" is an operational requirement.
7. You need deterministic database crash/fault testing hooks¶
DecentDB's test strategy includes FaultyVFS and WAL failpoint hooks. That makes crash-safety testing part of the database engineering surface.
H2 has a mature codebase and useful Java testing ergonomics, but DecentDB is more explicit about validating local durability behavior under injected storage failures.
When H2 Is the Better Fit¶
1. You are building a JVM application and want JDBC-first embedding¶
H2 is a natural fit when the application is Java/Kotlin/Scala and the database is accessed through JDBC:
Connection conn = DriverManager.getConnection("jdbc:h2:./appdb");
try (PreparedStatement ps =
conn.prepareStatement("select * from users where id = ?")) {
ps.setLong(1, 42);
ps.executeQuery();
}
DecentDB has a Java binding/JDBC surface, but H2's center of gravity is JDBC. If JDBC compatibility and JVM-local deployment are the main requirements, H2 is the lower-friction choice.
2. You need fast in-memory test databases¶
H2's in-memory mode is one of its best-known uses:
This is useful for unit tests, quick fixtures, demos, and local development tools. DecentDB can be used in tests too, but H2 is purpose-built for the JVM test fixture niche.
The caveat is compatibility. H2 compatibility modes are useful, but they are not exact emulators of PostgreSQL, MySQL, Oracle, or other engines. Use H2 as a test database when H2 behavior is acceptable, not as proof that another production database behaves identically.
3. You want one small pure-Java dependency¶
H2's small pure-Java jar is attractive when deployment simplicity means "add a jar, no native library." That matters in environments where native shared libraries are difficult to package or audit.
DecentDB is a native Rust library. That gives it strong performance and cross-language embedding properties, but it is not as simple as dropping one Java jar into a classpath.
4. You need H2 Console and Java-oriented admin tooling¶
H2 includes a browser-based console and Java command-line tools. If your team already uses H2 Console as part of development, demos, or support workflows, that is a practical reason to keep H2.
DecentDB has a CLI and docs-focused workflow, but it is not trying to replicate H2 Console.
5. You use H2 server mode¶
H2 can run as an embedded engine or as a server. That flexibility can be useful for local development, debugging, or small Java deployments that want a network connection during development.
DecentDB is primarily an embedded local database. If you want a Java database that can switch between embedded and server modes, H2 is the better fit.
6. You depend on H2-specific SQL or compatibility modes¶
H2 supports its own SQL grammar plus compatibility modes for selected dialects. If your application or tests already depend on H2 behavior, moving to DecentDB is a real migration, not a configuration change.
Side-by-Side Examples¶
JVM test fixture¶
// H2: fast in-memory database for JVM tests.
Connection conn = DriverManager.getConnection("jdbc:h2:mem:testdb");
conn.createStatement().execute("""
create table users (id bigint primary key, name varchar not null)
""");
Prefer H2 when this is the core use case.
Production local file with branch validation¶
# DecentDB: validate a migration on a branch before touching main.
decentdb snapshot create --db app.ddb --name before-upgrade
decentdb branch create --db app.ddb --name upgrade-test --from before-upgrade
decentdb branch diff --db app.ddb --left main --right upgrade-test
Prefer DecentDB when local operational workflows matter as database features.
Multi-language embedding¶
# DecentDB: same database engine from Python.
import decentdb
conn = decentdb.connect("app.ddb")
conn.execute("insert into jobs (kind) values ($1)", ("email",))
Prefer DecentDB when the same engine must be embedded outside Java.
Summary Decision Matrix¶
| Your situation | Recommendation |
|---|---|
| JVM app, JDBC-first database access | H2 |
| In-memory database for Java tests | H2 |
| Small pure-Java dependency is the priority | H2 |
| H2 Console/server mode is useful | H2 |
| Application already depends on H2 SQL behavior | H2 |
| Durable local application data across languages | DecentDB |
| Need native library/CLI without a JVM | DecentDB |
| Need local branch/diff/restore/time-travel workflows | DecentDB |
| Need sync journal/conflict/retention inspection | DecentDB |
| Need row policies, projection masks, audit context | DecentDB |
| Need deterministic local crash/fault validation hooks | DecentDB |
Bottom Line¶
Pick H2 for Java-first embedded SQL, in-memory tests, JDBC tooling, and small pure-Java deployment.
Pick DecentDB for durable embedded application data that should behave the same across languages and expose branch, sync, policy, and crash-safety workflows as database features.
The fair comparison is not "which database is better." It is whether the application is really asking for a Java/JDBC database or for a durable multi-language embedded application database.