Skip to content

Comparison: DecentDB vs SQLite vs DuckDB

This page summarizes high-level feature differences between DecentDB, SQLite, and DuckDB.

Versions (as of 2026-03-28)

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

DecentDB is currently at v2.0.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: single process, one writer, many concurrent reader threads - 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.

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 (threads, same process) 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 No loadable extension / UDF plugin surface in the current baseline (extend by contributing to core) Rich extension ecosystem (loadable extensions, virtual tables, UDFs) Rich extension ecosystem (install/load extensions, UDFs)
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 does support multiple language bindings, but those bindings are about how you call DecentDB, not a general-purpose SQL extension/plugin system.

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 (with DISTINCT modifier) - 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() - JSON functions: JSON_EXTRACT, JSON_ARRAY_LENGTH, json_type, json_valid, json_object, json_array, ->, ->> - Table-valued functions: json_each(), json_tree() - 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 - 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()) - 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 ...)) - DEFAULT and generated columns (STORED + VIRTUAL) - CREATE TEMP TABLE / CREATE TEMP VIEW (session-scoped) - SAVEPOINT / RELEASE SAVEPOINT / ROLLBACK TO SAVEPOINT

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 v0 limits (multi-column BTREE; partial col IS NOT NULL; narrow deterministic single-expression BTREE) 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 small compatibility subset of SQLite-style PRAGMAs (page_size, cache_size, integrity_check, database_list, table_info(table)) and intentionally does not implement SQLite's broader PRAGMA surface.

Common PRAGMA DecentDB Alternative
PRAGMA journal_mode Not applicable; DecentDB uses WAL-only mode
PRAGMA foreign_keys Always enabled; cannot be disabled
PRAGMA synchronous Not configurable; commits are durable by default (fsync-on-commit). Use bulk-load --durability=... for ingestion tradeoffs
PRAGMA cache_size Query is supported. Changing cache size requires reopen: CLI --cachePages/--cacheMb, Rust openDb(..., cachePages=...)
PRAGMA page_size Query is supported. Changing page size requires reopening with matching DbConfig.page_size
PRAGMA table_info(t) Supported via PRAGMA table_info(t) and via decentdb describe --db=... --table=t

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.