Skip to content

Comparison Overview

This page summarizes high-level feature differences between DecentDB, SQLite, and DuckDB, then points to deeper comparison guides for other embedded databases that developers may consider instead of DecentDB.

Versions (as of 2026-06-28)

This comparison was written against: - SQLite 3.51.2 (sqlite3 CLI) - DuckDB v1.4.3 (duckdb CLI)

DecentDB's current workspace version is v2.15.0. This document describes the current feature set and constraints; details may change as DecentDB continues to evolve.

DecentDB is intentionally scoped around: - Priority #1: durable ACID writes (WAL-based) - Priority #2: fast reads - Concurrency model: one writer, many concurrent readers, with local native cross-process WAL coordination when the VFS supports it - SQL goal: a practical, Postgres-like subset for common application queries

SQLite and DuckDB are used as behavioral baselines for many SQL features, but DecentDB does not aim to be a drop-in replacement for either.

See also: SQL Feature Matrix for a concise per-feature support grid comparing DecentDB, SQLite, and DuckDB. For product-specific decision guides, see the comparison pages listed below.

Quick summary

Area DecentDB SQLite DuckDB
Primary focus OLTP-style embedded DB, durability-first Embedded general-purpose DB Embedded analytics (OLAP)
Durability model WAL-based, fsync-on-commit by default WAL or rollback journal, configurable Depends on storage mode; optimized for analytics workflows
Concurrency Single writer, many readers; local native cross-process WAL coordination when supported Multi-reader, single-writer (process-safe) Parallel query execution; analytics-oriented
SQL breadth Subset (deliberately small) Very broad (plus extensions) Very broad (esp. analytical SQL)
Extensibility Sandboxed Lua packages for scalar functions, table-valued functions, aggregates, and query-time collations; no arbitrary native loading Rich extension ecosystem (loadable extensions, virtual tables, UDFs) Rich extension ecosystem (install/load extensions, UDFs)
Local-first sync Built-in durable change journal, batch exchange, scoped peers, conflict workflows, doctor/retention tooling, CLI, and .NET SDK Not built in; usually application middleware or third-party replication layers Not built in; not a local-first replication focus
Branch/diff/restore workflows Built-in named snapshots, branch-local writes, primary-key row diff, guarded restore, and constrained merge Not built in; use file copies, backup APIs, sessions, or app tooling Not built in; typically use external copies or app/tooling
Substring search (LIKE '%pattern%') Built-in trigram index option (purpose-built for interactive “contains” queries) Typically full scan or use FTS/extensions Typically scan or use extensions (e.g., FTS)
Durability fault-injection hooks Built-in WAL failpoints + FaultyVFS for deterministic crash/torn-write testing Not typically exposed as a first-class user feature Not typically exposed as a first-class user feature

Notes: - SQLite and DuckDB can often match many of these behaviors via extensions or different usage patterns; the point here is what DecentDB bakes in and optimizes for by default.

What “extensions” means here: - The ability to add new SQL features without modifying the database core (e.g., new scalar/aggregate functions, new table-like modules such as SQLite virtual tables, or optional subsystems like full-text search). - DecentDB's extension answer is a sandboxed Lua package model with manifest-declared SQL objects and explicit content-hash trust. It is not SQLite .load, DuckDB native extensions, or host-language callbacks.

Detailed Comparison Pages

These pages are decision guides, not scorecards. They focus on fit, tradeoffs, and migration implications.

Local-first sync

DecentDB's biggest product-level differentiator is native local-first sync for embedded applications. It is built into the engine and exposed through the CLI, SQL inspection queries, and the .NET SDK.

The current sync surface includes:

  • durable row-level change capture in a sidecar sync journal
  • replica IDs, peer catalogs, and peer-to-scope bindings
  • manual JSON batch export/import for offline exchange
  • localhost/dev HTTP sync run and sync serve workflows
  • scoped replication with validated primary-key-based row filters
  • conservative conflict recording by default, plus manual show/resolve/reopen workflows and configurable policies
  • in-process reactive subscriptions for table, range, query, and change-stream invalidation without polling
  • canonical sys.* operational inspection views plus sys_sync_* compatibility queries for journals, peers, scopes, sessions, conflicts, peer lag, retention, and doctor summaries
  • retention reports, safe prune dry-runs, explicit data-loss override, and sync doctor guidance
  • a typed .NET DecentDBSyncClient for app integration

SQLite and DuckDB can participate in sync architectures when an application or external service layers replication around them. DecentDB's direction is different: offline writes, sync state, conflict inspection, scoped exchange, and operational diagnostics are first-class database capabilities.

See Local-first sync for the user guide and CLI Reference for command details.

SQL surface area

DecentDB's current baseline includes: - DDL: CREATE TABLE, CREATE INDEX, CREATE TRIGGER, CREATE VIEW, CREATE TEMP TABLE, CREATE TEMP VIEW, DROP TABLE, DROP INDEX, DROP TRIGGER, DROP VIEW, ALTER TABLE, ALTER VIEW ... RENAME TO ... - DML: SELECT, INSERT, UPDATE, DELETE, INSERT ... RETURNING, INSERT ... ON CONFLICT - Joins: INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL OUTER JOIN, CROSS JOIN, NATURAL JOIN - Clauses: WHERE, ORDER BY, LIMIT, OFFSET, FETCH, GROUP BY, HAVING, DISTINCT, DISTINCT ON - Aggregates: COUNT, SUM, AVG, MIN, MAX, TOTAL, GROUP_CONCAT, STRING_AGG, STDDEV, VARIANCE, BOOL_AND, BOOL_OR, ARRAY_AGG, MEDIAN, PERCENTILE_CONT, PERCENTILE_DISC (with supported DISTINCT and aggregate ORDER BY forms) - Set operations: UNION, UNION ALL, INTERSECT, INTERSECT ALL, EXCEPT, EXCEPT ALL - CTEs: WITH ... AS (recursive and non-recursive) - Window functions: ROW_NUMBER(), RANK(), DENSE_RANK(), LAG(), LEAD(), FIRST_VALUE(), LAST_VALUE(), NTH_VALUE() with OVER (...) - Predicates: comparisons (=, !=, <>, <, <=, >, >=), AND/OR/NOT, LIKE/ILIKE, IN, BETWEEN, EXISTS, IS NULL/IS NOT NULL - Math functions: ABS, ROUND, CEIL/CEILING, FLOOR, SQRT, POWER/POW, MOD, SIGN, LOG, LN, EXP, RANDOM - String functions: LENGTH, LOWER, UPPER, TRIM, LTRIM, RTRIM, REPLACE, SUBSTRING/SUBSTR, INSTR, LEFT, RIGHT, LPAD, RPAD, REPEAT, REVERSE, CHR, HEX - Date/time functions: NOW(), CURRENT_TIMESTAMP, CURRENT_DATE, CURRENT_TIME, date(), datetime(), strftime(), EXTRACT(), DATE_TRUNC(), DATE_PART(), DATE_DIFF(), LAST_DAY(), NEXT_DAY(), MAKE_DATE(), MAKE_TIMESTAMP(), TO_TIMESTAMP(), AGE(), and timestamp/date INTERVAL arithmetic - JSON functions: JSON_EXTRACT, JSON_ARRAY_LENGTH, json_type, json_valid, json_object, json_array, ->, ->> - Table-valued functions: json_each(), json_tree(), generate_series(), and SQLite-compatible pragma_*() introspection helpers - Compatibility catalog views: sqlite_schema / sqlite_master, temp schema aliases, and minimal information_schema.schemata, information_schema.tables, and information_schema.columns - Query-time compatibility syntax: main. / temp. qualified names for local objects, and COLLATE BINARY|NOCASE|RTRIM for ordering and comparisons - Generated columns: GENERATED ALWAYS AS (expr) in STORED and VIRTUAL modes - Other functions: COALESCE, NULLIF, CAST, CASE, GEN_RANDOM_UUID, UUID_PARSE, UUID_TO_STRING, PRINTF, current_database(), current_schema(), database(), schema(), version() - SQLite-style PRAGMAs for safe configuration probes and schema introspection, including foreign_keys, journal_mode, synchronous, wal_checkpoint, user_version, application_id, table_xinfo, table_list, index_list, index_info, index_xinfo, and foreign_key_list - Operators: +, -, *, /, % (modulo), || (string concatenation) - Transaction control: BEGIN, BEGIN IMMEDIATE/BEGIN EXCLUSIVE (treated as BEGIN), COMMIT, ROLLBACK, SAVEPOINT, RELEASE SAVEPOINT, ROLLBACK TO SAVEPOINT - Parameters: positional $1, $2, ... (Postgres-style) - EXPLAIN / EXPLAIN ANALYZE plan output

SQLite and DuckDB generally include all of the above, plus substantial additional SQL.

Views

Feature DecentDB SQLite DuckDB
Non-materialized views (CREATE VIEW ... AS SELECT ...) Yes; read-only views Yes Yes
CREATE OR REPLACE VIEW Yes Not supported as a single statement Yes
Updatable views Limited: via narrow INSTEAD OF trigger subset (decentdb_exec_sql('<single DML>'), no NEW/OLD) Via INSTEAD OF triggers Limited / generally not the default
TEMP views Yes (session-scoped, not persisted) Yes Yes

SQL roadmap

DecentDB has implemented many previously planned baseline features, including: - Richer expression support (IS NULL, CASE, CAST, BETWEEN, IN, EXISTS, LIKE ... ESCAPE, ||, core scalar functions) - UPSERT and DML conveniences (INSERT ... ON CONFLICT DO NOTHING/DO UPDATE, INSERT ... RETURNING) - Recursive and non-recursive CTEs, set operations (UNION ALL, UNION, INTERSECT, INTERSECT ALL, EXCEPT, EXCEPT ALL) - CHECK constraints, FK CASCADE / SET NULL actions, table-level FOREIGN KEY constraints - Broader ALTER TABLE (ADD COLUMN, RENAME COLUMN, DROP COLUMN, ALTER COLUMN TYPE) - Trigger subsets (AFTER row triggers on tables, INSTEAD OF row triggers on views) - Window functions (ROW_NUMBER(), RANK(), DENSE_RANK(), LAG(), LEAD(), FIRST_VALUE(), LAST_VALUE(), NTH_VALUE() with OVER (...)) - Date/time functions (NOW(), CURRENT_TIMESTAMP, CURRENT_DATE, CURRENT_TIME, date(), datetime(), strftime(), EXTRACT(), DATE_TRUNC(), DATE_PART(), DATE_DIFF(), LAST_DAY(), NEXT_DAY(), MAKE_DATE(), MAKE_TIMESTAMP(), TO_TIMESTAMP(), AGE(), and timestamp/date INTERVAL arithmetic) - Math functions (SQRT, POWER/POW, MOD, SIGN, LOG, LN, EXP, RANDOM) - String functions (LTRIM, RTRIM, LEFT, RIGHT, LPAD, RPAD, REPEAT, REVERSE, CHR, HEX, INSTR) - JSON functions (JSON_EXTRACT, JSON_ARRAY_LENGTH, json_type, json_valid, json_object, json_array, ->, ->>, json_each(), json_tree()) - Indexing options (multi-column, partial v0 subset, expression index v0 subset) - EXPLAIN / EXPLAIN ANALYZE plan output - Join types (INNER, LEFT, RIGHT, FULL OUTER, CROSS, NATURAL) - DISTINCT ON, DISTINCT aggregates (COUNT(DISTINCT ...), SUM(DISTINCT ...), AVG(DISTINCT ...), plus supported forms for statistical and collection aggregates) - DEFAULT and generated columns (STORED + VIRTUAL) - CREATE TEMP TABLE / CREATE TEMP VIEW (session-scoped) - SAVEPOINT / RELEASE SAVEPOINT / ROLLBACK TO SAVEPOINT - SQL and PRAGMA compatibility quick wins, including safe SQLite-style PRAGMA probes, sqlite_schema, minimal information_schema, generate_series, main./temp. qualifiers, and query-time built-in collations

For remaining roadmap and deferred capabilities, see: - Road to RTM - ADRs

Data types and functions

DecentDB’s baseline types cover the most common application needs: - NULL, INT64, BOOL, FLOAT64, TEXT (UTF-8), BLOB, UUID, DECIMAL(p,s) / NUMERIC(p,s), DATE, TIMESTAMP

SQLite and DuckDB both offer larger built-in ecosystems of types and functions. DuckDB, in particular, has many analytics-oriented types and functions (nested types, extensive math/statistics), while SQLite’s strength is portability, flexibility, and a long list of optional extensions.

Capability DecentDB SQLite DuckDB
B-tree secondary indexes Yes Yes Yes
Fast substring search for LIKE '%pattern%' Yes, via trigram index on configured columns Usually via FTS extension or full scans Often via functions/extensions; not a primary focus
Advanced index options (partial/expression/multi-column, etc.) Supported with limits (multi-column BTREE; single-column BTREE partial predicates; narrow deterministic single-expression BTREE; covering INCLUDE) Many are available Many are available

DecentDB emphasizes predictable behavior, durability, and correctness testing rather than broad operational surface area.

SQLite-Specific Features: Explicit Decisions

DecentDB intentionally does not support certain SQLite-specific features. This section documents those decisions and provides alternatives where applicable.

PRAGMA

DecentDB supports a practical compatibility subset of SQLite-style PRAGMAs for tooling probes and schema discovery. These PRAGMAs are intentionally safe: configuration PRAGMAs report DecentDB's actual behavior, and assignment forms are accepted only as no-ops or for DecentDB-owned metadata.

Common PRAGMA DecentDB Alternative
PRAGMA journal_mode Supported as a WAL-only compatibility probe. PRAGMA journal_mode = WAL succeeds and returns wal; rollback/off/delete modes are rejected.
PRAGMA foreign_keys Supported and returns 1. ON is a no-op; disabling foreign keys is rejected.
PRAGMA synchronous Supported as a compatibility probe. Assignments succeed only when they match the open-time WAL sync mode; use bulk-load durability options for ingestion tradeoffs.
PRAGMA cache_size Query is supported. Changing cache size requires reopen: CLI --cachePages/--cacheMb, Rust DbConfig.cache_size_mb, or binding open options such as cache_size=64MB.
PRAGMA page_size Query is supported. Changing page size requires reopening with matching DbConfig.page_size.
PRAGMA table_info(t) / table_xinfo(t) Supported, including generated-column visibility through hidden in table_xinfo.
PRAGMA table_list, index_list, index_info, index_xinfo, foreign_key_list Supported for SQLite-style schema browsers and ORMs.
PRAGMA user_version, application_id Supported as durable, transactional signed 32-bit application metadata.
PRAGMA busy_timeout Supported for connection-local queued-write timeout defaults.
PRAGMA read_uncommitted, ignore_check_constraints, defer_foreign_keys Rejected; DecentDB does not expose dirty reads or constraint-disabling modes.

rowid / rowid Pseudo-Columns

SQLite exposes implicit rowid as a queryable pseudo-column. DecentDB has an internal rowid but does not expose it to SQL.

Recommendation: Use an explicit INT64 primary key (e.g. id INT PRIMARY KEY). If the table has a single INT64 primary key column, omitting the value on INSERT will auto-assign an ID.

WITHOUT ROWID Tables

SQLite optimization for tables where the PRIMARY KEY is the clustering key. Not applicable to DecentDB's storage architecture.

ATTACH DATABASE

SQLite's mechanism for querying multiple database files simultaneously. Not supported.

Recommendation: Use application-level multi-database coordination.

Recursive CTEs

WITH RECURSIVE is supported for iterative fixpoint queries (counting, tree/graph traversal). Recursive CTEs use UNION or UNION ALL between anchor and recursive terms and are limited to 1000 iterations per statement.