Companion notebook: https://github.com/oracle-devrel/oracle-umt-developer-hub
Key takeaways
- Multi-model database: a system that can store and query more than one data model — for example relational tables plus JSON documents, graphs, or vectors. By DB-Engines’ labeling, nine of the world’s ten most popular databases now qualify (See DB-Engines Ranking, June 2026, and methodology).
- Converged database: a multi-model system in which the architectural guarantees span the models — one ACID transaction boundary, one cost-based optimizer, one consistency model, one security and governance domain, shared access surfaces (See What Is a Converged Database? Definition, Five Tests, and AI Use Cases).
- The article uses runnable tests, not just product claims. It shows a single SQL statement combining relational, graph, and JSON data, with one optimizer plan and CI-validated assertions. The test: not “how many models can it store?” but “is there one transaction, one plan, one consistency model, and one set of controls across them?” The academic literature documented exactly this gap (See J. Lu and I. Holubová, “Multi-model Databases: A New Journey to Handle the Variety of Data,” ACM Computing Surveys 52(3), Article 55, 2019.
- Spanner is treated as a strong peer, but not fully converged by the article’s definition. The article credits Spanner’s transaction, planning, and consistency strengths, while arguing Oracle goes further on document APIs, relational-document duality, policy enforcement, and vector index maintenance.
Multi-model is a storage claim: one product can hold several data models. Converged is a guarantees claim: one engine gives every model the same transactions, the same optimizer, the same consistency, and the same governance. Most leading databases now make the first claim. Far fewer can demonstrate the second.
How saturated is the label? In the June 2026 DB-Engines ranking, nine of the top ten systems — Oracle, MySQL, SQL Server, PostgreSQL, MongoDB, Databricks, Redis, Db2, Cassandra — carry the “Multi-model” tag; among the top ten, only Snowflake does not (See DB-Engines Ranking, and methodology). When ninety percent of the leaderboard wears the same badge, the badge has stopped differentiating. The guarantees never did.

A short history of the label
“Multi-model database” was coined in May 2012 by Luca Garulli, creator of OrientDB, in a keynote at NoSQL Matters Cologne (See Wikipedia, “Multi-model database” (coinage, lineage); and “NoSQL Adoption — What’s the Next Step?”); the lineage of the idea runs back to the object-relational systems of the 1990s. The term named a genuine improvement over its alternative: rather than operating a different specialized database per data model — polyglot persistence — one product would hold several models.
DB-Engines formalized the label in 2019: systems are tagged with a primary model and any secondary models they deliberately support, and the “Multi-model” tag rewards intentional support rather than incidental possibility (“each relational system can be (mis-)used as a key-value store,” as their methodology note puts it) (See DB-Engines Ranking, and methodology). It is a taxonomy of what products store. It was never designed to measure what their architectures guarantee — and as JSON, search, and vector capabilities spread through the industry, the storage question stopped being the interesting one.
The interesting question had already been posed by the academics.
The academic bar: what the survey actually found
The peer-reviewed treatment of multi-model databases is Lu and Holubová’s survey in ACM Computing Surveys (2019) (See “Multi-model Databases: A New Journey to Handle the Variety of Data,” (author’s accepted text)). Three of its findings draw the line this article is about.
First, the bar. The survey rules that merely storing another model’s data does not make a system multi-model: a relational DBMS used as an RDF triple store is “not a multi-model database” when “there is no cross-model query language, respective optimization of query evaluation etc.” (See “Multi-model Databases: A New Journey to Handle the Variety of Data”. The capability must include querying — and optimizing — across models, not merely housing them.
Second, the transaction gap. Across the roughly twenty systems surveyed — ArangoDB, OrientDB, Cosmos DB, MongoDB, Couchbase, and the 2019-era Oracle among them — the authors report: “we have not managed to find any explicit information about existence of a special type of transaction management across diverse data models” (See “Multi-model Databases: A New Journey to Handle the Variety of Data”. In the survey’s capability table, the multi-model-transactions column goes unchecked for every system. As of 2019, in the academic record, no multi-model database offered cross-model transactions.
Third, the optimization gap. On query planning across models: “there seems to be no universally acknowledged optimal or sub-optimal approach suitable for the multi-model query optimization” (See “Multi-model Databases: A New Journey to Handle the Variety of Data” . The survey closes by calling the field “a long journey towards a mature and robust multi-model DBMS” — and lists multi-model query processing and optimization first among its open problems.
A worthwhile aside about that survey: its 2019 snapshot of Oracle is humble — JSON stored in VARCHAR2 or LOB columns with an IS JSON check constraint, queried through SQL/JSON functions, no native type (See “Multi-model Databases: A New Journey to Handle the Variety of Data”. No duality views, no vectors, no SQL property graphs existed yet. The survey did not crown anyone. It published a research agenda. The distance between that 2019 row and what is demonstrated below is the point.
Set the survey’s open problems beside the five convergence tests from the anchor article (What Is a Converged Database? Definition, Five Tests, and AI Use Cases) and the mapping is nearly one-to-one: their transaction gap is “one transaction boundary”; their optimization gap is “one optimizer”; their cross-model query-language bar is “shared access surfaces.” Converged is the survey’s research agenda, shipped and testable. The remainder of this article runs the tests — every claim backed by an asserted, CI-validated script in the companion repository, on a branch that ships with this article.
Running their figure: the canonical multi-model query in one statement
The survey’s running example — its Figure 1 — is the literature’s canonical multi-model challenge. An e-commerce scenario spans four models: a relational customers table (Mary, credit limit 5000; John, 3000; William, 2000), a social “knows” graph, orders as JSON documents, and a key/value pairing. The challenge query, from the figure’s caption: “Return all product_no which are ordered by a friend of a customer whose credit_limit > 3000.” The published answer: ['2724f','3424g'] (See “Multi-model Databases: A New Journey to Handle the Variety of Data”. The survey solves it twice — in ArangoDB’s AQL and OrientDB’s SQL dialect — each a proprietary language on its own engine.
Module 02 of the companion repository recreates the survey’s dataset (its published customers, credit limits, and result; the knows-topology and order contents are constructed to be consistent with both — the construction is documented in the script) and answers the challenge in one standard SQL statement:
SELECT DISTINCT jt.product_no /* THE statement — the survey's Fig. 1 query in
one standard SQL statement: graph hop via SQL/PGQ GRAPH_TABLE
(ISO/IEC 9075-16), document unnest via SQL/JSON JSON_TABLE (SQL:2016),
relational predicate on credit_limit — one engine, one optimizer */
FROM GRAPH_TABLE (smm_social
MATCH (c IS smm_customers) -[IS smm_knows]-> (f IS smm_customers)
WHERE c.credit_limit > 3000
COLUMNS (f.customer_id AS friend_id)) g
JOIN smm_orders o ON o.customer_id = g.friend_id
CROSS JOIN JSON_TABLE (o.doc, '$.Orderlines[*]'
COLUMNS (product_no VARCHAR2(16) PATH '$.Product_no')) jt;
The graph hop is GRAPH_TABLE — SQL/PGQ, ISO/IEC 9075-16:2023, a 269-page part of the SQL standard itself. The document unnest is JSON_TABLE — SQL/JSON, in the standard since 2016 (See ISO/IEC 9075-16:2023, SQL — Part 16: Property Graph Queries (SQL/PGQ); SQL/JSON in SQL:2016; native JSON type in SQL:2023). The relational predicate is a WHERE clause. The script’s assertion checks that the result set equals the survey’s published answer exactly — two products, 2724f and 3424g — and CI re-checks it on every change and every night.

It is worth pausing on the languages. Both operators are ISO SQL — the standard absorbed the models. SQL:2016 defined the JSON operator set; SQL:2023 added a native JSON type and the property-graph part. The absorption is industry-wide: Oracle shipped the first commercial SQL/PGQ implementation, DuckDB supports it through an extension, and PostgreSQL has committed GRAPH_TABLE for PostgreSQL 19, in beta as of June 2026 (See PostgreSQL: SQL/PGQ (GRAPH_TABLE) committed for PostgreSQL 19 (March 2026; Beta 1 June 2026). When the standard is multi-model, the question is no longer which query language each model needs. It is which guarantees surround the engine executing it.
One optimizer, in evidence
What does the engine do with the survey statement? EXPLAIN PLAN, captured by the same script (illustrative output from the lab container; plan hashes and system-generated index names vary per build):
| Id | Operation | Name |
| 0 | SELECT STATEMENT | |
| 1 | HASH UNIQUE | |
| 2 | NESTED LOOPS | |
| 3 | NESTED LOOPS SEMI | |
| 4 | MERGE JOIN CARTESIAN| |
| 5 | TABLE ACCESS FULL | SMM_CUSTOMERS | ← relational vertex table
| 6 | BUFFER SORT | |
| 7 | TABLE ACCESS FULL | SMM_ORDERS | ← JSON documents
| 8 | INDEX UNIQUE SCAN | SYS_C009222 | ← graph edge (knows) via PK index
| 9 | JSONTABLE EVALUATION | | ← document unnest, in-plan
One plan tree. The graph pattern has lowered entirely into relational row sources — Oracle’s documentation states GRAPH_TABLE “is internally translated into equivalent SQL” — the JSON unnest appears as a JSONTABLE EVALUATION row source inside the same plan, and the cost-based optimizer chose the join order across all of it. The script asserts all of this: plan captured, graph edge table costed, relational table costed, JSON documents costed, JSON evaluation present, one plan tree. (The anchor article’s module carries the four-model version of this evidence — graph, JSON, vector, and relational in one plan — in its 05-one-plan.sql (See converged-database-lab, module 01); this article does not duplicate it.)
This is what the survey said was missing. For contrast, the seams in other architectures are documented by their own projects:
- pgvector (the PostgreSQL vector extension): with HNSW indexes, “filtering is applied after the index is scanned” — a selective WHERE clause can decimate a top-k result; iterative scan modes were added in 0.8.0 as mitigation (See pgvector README and changelog (post-index filtering; iterative scans, v0.8.0+); single-instance vs. cluster). The extension genuinely shares PostgreSQL’s planner; the seam is what the planner can see. (Not every architecture shares this seam: Google Spanner pushes the predicate into vector-index selection — filtered vector indexes and leaf-level filtering — so a selective
WHEREnarrows the candidate set before ranking rather than after (See Vector indexing best practices); we return to Spanner below.) - Apache AGE (the PostgreSQL graph extension): Cypher queries pass through the PostgreSQL planner, but the planner is largely blind to
agtypegraph properties — Microsoft’s own AGE performance guide shows pattern matches compiling to sequential scans with opaque filter functions and notes that AGE creates no indexes on new graph labels by default (See Microsoft Learn, “Apache AGE performance best practices” (Azure Database for PostgreSQL); Apache AGE manual (setup, cypher usage)). PostgreSQL 19’s standardGRAPH_TABLEis the cleaner long-term path — and it makes this article’s point: the model moved into the engine. - MongoDB: real multi-document ACID transactions, including cross-shard, with documented operational parameters. But its search and vector search execute in
mongot, a separate Lucene-based process fed from the database by change streams — a different engine with its own consistency timeline, which is the subject of the next test (See MongoDB documentation: transactions production considerations; mongot architecture; Atlas Search index performance (consistency); “What is a Multi-Model Database?” (MongoDB’s own multi-model positioning)).
One enforcement domain, one consistency model
The same constraint, every door. The shared lab domain declares CHECK (qty > 0) on order line items. Module 02 attempts to violate it through the MongoDB-compatible document API — pushing qty: -1 into a duality-view document:
// (a) document API: push an illegal qty into the duality view.
let docErr = null;
try {
col.updateOne({ _id: 1 }, { $set: { 'items.0.qty': -1 } });
} catch (e) {
docErr = e;
}
const docMsg = docErr ? String(docErr.message || docErr.errmsg || docErr) : '';
print('ASSERT:mongo-api-rejected:' + (docErr !== null && docMsg.includes('ORA-02290') ? 'PASS' : 'FAIL'));
The write is rejected at the wire protocol with the engine’s own error (observed on the lab container, June 2026; constraint names are system-generated and vary):
MongoServerError:
ORA-42692: Cannot update JSON Relational Duality View 'LAB_USER'.'ORDER_DV':
Error while updating table 'ORDER_ITEMS'
ORA-02290: check constraint (LAB_USER.SYS_C...) violated
The same script then submits the same violation as a SQL UPDATE through the same MongoDB connection’s $sql stage — and receives the same ORA-02290. One constraint, declared once, enforced beneath every API. There is no per-surface validation layer to drift out of agreement, because there is nothing to keep in agreement.
Read-after-write, across a commit boundary. Text search is where multi-store architectures most visibly trade consistency for modularity. Module 02’s third proof inserts a ticket, commits, and finds it by CONTAINS in the next statement:
INSERT INTO support_tickets (customer_id, subject, body, status)
VALUES (1, 'm02 rw-search probe',
'read-after-write search probe, marker token zzqxw9347', 'open');
COMMIT;
SELECT /* the committed row is findable by CONTAINS immediately — same call
stack, same second, no sync window */
'ASSERT:contains-finds-committed-write:' ||
CASE WHEN COUNT(*) = 1 THEN 'PASS' ELSE 'FAIL' END
FROM support_tickets WHERE CONTAINS(body, 'zzqxw9347') > 0;
The index syncs on commit — search visibility arrives with the transaction (the lab’s index is created with SYNC (ON COMMIT); Oracle Text also offers manual and interval sync for write-heavy tradeoffs). Compare the documented behavior elsewhere, each from the vendor’s own documentation, as of June 2026:
- MongoDB search indexes are maintained by the separate
mongotprocess and are eventually consistent; the documentation describes replication lag and notes stale results can be served while an index rebuilds (See MongoDB documentation: transactions production considerations; mongot architecture; Atlas Search index performance (consistency)). - Couchbase’s default query consistency,
not_bounded, “may return out-of-date results”; waiting for the index is a per-query opt-in (See Couchbase documentation: services (Multi-Dimensional Scaling); query scan consistency). - Azure Cosmos DB scopes its consistency choices to the account, and its documentation specifies that “read consistency applies to a single read operation within a logical partition”. The API itself — NoSQL, MongoDB, Cassandra, Gremlin, Table — is fixed when the account is created; Microsoft’s FAQ recommends “using the same API for all accesses,” because the storage formats differ per API. Multiple APIs across the product is not the same property as multiple models over the same data. (See Microsoft Learn, Azure Cosmos DB: consistency levels; FAQ (multiple APIs); database account creation (
kind)). - ArangoDB deserves its concession stated plainly: in single-server and OneShard deployments, multi-collection queries are “fully ACID in the traditional sense” — a genuine cross-model transaction boundary. Its own documentation states the qualifier: in sharded clusters, multi-document transactions are not ACID across shards (See ArangoDB documentation: transaction limitations). The boundary holds exactly as far as one machine’s data.
The scorecard
The five guarantees, against the architecture classes — every cell from the cited vendor documentation, as of June 2026, re-verified at publication:
| Architecture | One txn boundary | One optimizer | One consistency model | One governance domain | Shared surfaces, same data |
|---|---|---|---|---|---|
| API-per-account (Cosmos DB) | partial — per logical partition | per-API | account-scoped levels; per-partition reads | per account | ✗ — API fixed at creation |
| Extension composite (PostgreSQL + pgvector/AGE/PostGIS) | ✓ — one WAL, one MVCC | partial — planner blind to extension internals; post-index filtering | ✓ | ✓ | SQL only |
| Engine + sidecar (MongoDB + mongot) | ✓ core / ✗ search & vector | core only — search planned separately | ✗ for search — eventually consistent | partial — roles don’t govern mongot internals | document API only |
| Single-engine multi-model (ArangoDB, single-server/OneShard) | ✓ — with documented cluster qualifier | AQL, own engine | ✓ single-instance | ✓ | AQL only |
| Distributed single-engine multi-model (Google Spanner) | ✓ — distributed ACID + external consistency (80K-mutation/commit cap) | ✓ — one plan; GQL lowers to relational; vector/FTS auto-indexed | ✓ for visibility — external consistency; FTS is read-your-writes, in-transaction; but ANN recall decays until the static ScaNN tree is rebuilt (See the source) | partial — unified roles + column-level; no row-level security | SQL + GQL + vector/FTS over the same tables; no document API or duality |
| Converged (Oracle AI Database 26ai) (See Oracle Property Graph Developer’s Guide; “Property Graphs in Oracle Database: the SQL/PGQ standard” (first commercial implementation); converged-database-lab; Oracle error reference: ORA-02290. | ✓ — module 01, proof 1 | ✓ — modules 01/05 + 02/01, in plan evidence | ✓ — modules 01/04 + 02/03 | ✓ — module 02/02 | SQL + MongoDB API + REST |
The last row’s citations are not documentation pages; they are runnable assertions. That is deliberate.
Spanner: the exception that proves the rule
The strongest challenge to a “label ≠ guarantees” argument is a system that actually delivers the guarantees — and in June 2026 Google made the case for one. Cloud Spanner’s multi-model “agentic era” positioning, unlike most of the leaderboard, has real architecture behind it: a property graph declared over node and edge tables, embeddings as a vector column, a full-text index as a structure on the same table — all in one storage substrate (Colossus), under one distributed transaction boundary and TrueTime’s external consistency. Spanner genuinely passes the three hardest tests. One ACID transaction spans relational, graph, JSON, and vector writes; one compiler plans across them; and — the property that separates it from every engine-plus-sidecar architecture above — its full-text search is transactionally consistent: the index is “updated in the same transaction,” and searches “return the latest transactionally-consistent committed data”. No eventually-consistent search process trails the primary. On consistency, Spanner is not a target; it is a peer. That is this article’s thesis, argued by a competitor: convergence is real, and the guarantee — not the badge — is the measure.
Where Spanner stops short of a converged engine is specific, and worth stating exactly.
The vector index is the seam — and it is the one to watch in an agentic workload. Spanner ships exactly one kind of vector index: ScaNN, a centroid tree whose structure is “optimized for the dataset at the time of creation, and is static thereafter,” so that adding different vectors later leaves it “sub-optimal, leading to poorer recall,” (See the reference) and you “periodically rebuild the vector index after you insert new data” (See the reference). Committed vectors stay visible immediately — this is recall decay, not stale data — but recall becomes a maintenance schedule, and an agent retrieving context against a drifted index quietly returns worse matches with no error to catch. Centroid indexes share this trait, and we will be exact: Oracle’s IVF index degrades the same way when the distribution shifts (See the reference). The difference is that Oracle does not force the tradeoff on you — it offers a choice and automates the upkeep. You can build an HNSW graph index that is incrementally maintained (new vectors “added into the graph,” deletions “tracked using compact bitmaps,” queries served “transactionally consistent results, based on their read snapshot”), or an IVF index that reorganizes automatically and online, “while it remains available for DMLs and queries”. One architecture asks you to plan rebuilds; the other reorganizes itself. In fairness, Oracle’s HNSW is a memory-resident structure bounded by server memory, where Spanner’s ScaNN targets ten-billion-vector scale (See Find ANN , HNSW Index Architecture and Vector index best practices) — if raw index scale is the binding constraint, that trade runs the other way.
The surface and the policy are the other two — and they are where a converged engine pulls ahead for agents. Spanner’s “multi-model” means SQL, GQL, vector, and search over relational tables; there is no document API and no bidirectional relational↔︎document projection. A JSON column queried with SQL is not a document store, and Google’s MongoDB-compatible product is a different database, Firestore (See the reference). Oracle inverts this: one canonical form projected into many shapes, including a MongoDB-compatible document API and JSON Relational Duality Views — model the domain once, project the access for every consumer. And where Spanner’s fine-grained access control stops at the column level with no row-level security, Oracle enforces row-, column-, and cell-level policy inside the engine — the control an AI agent acting as the end user actually depends on. Same physics of convergence; Oracle carries it across the surface and the policy, not only the transaction.
One more distinction — a cost, not a gap. Spanner earns its guarantees through distributed consensus, and that carries a write-path latency a shared-storage converged engine does not pay. Even the cheapest Spanner write commits only “once a majority of [the] replicas have stored the transaction mutation in stable storage,” and a transaction that spans splits adds “an extra layer of coordination (using the standard two-phase commit algorithm)” (Google Cloud Spanner, “Life of Spanner reads & writes”). On Autonomous Database — a converged engine over shared storage — a commit is a local redo-log write ordered by a monotonically increasing SCN, acknowledged once “all redo records … are safely on disk” (See the COMMIT reference): no cross-replica quorum vote, and no cross-shard two-phase commit on the write path. State the trade honestly. Spanner buys horizontal scale and always-on multi-zone durability with that consensus, and if you deploy Oracle’s own globally distributed (sharded) option you take on the same two-phase commit. And Spanner’s TrueTime “commit wait” is not the culprit — Google notes it “typically overlaps with the replica communication … so its actual latency cost is minimal” (See the reference). The standing cost is the quorum itself, on every write.
What this means for modernization — and for agents
For consolidation decisions, the practical consequence is that the label cannot tell you what you will be able to retire. A multi-model checkbox might mean “we can stop running a separate graph database” or it might mean “we still run a separate search process, with its own consistency timeline, inside the same product.” The guarantee list is the decision list.
For AI systems, the boundary you buy is the boundary your agents inherit. An agent retrieving context through an eventually-consistent search index reasons using historical data, not current data; an agent whose permissions live in application middleware rather than the engine is one unanticipated code path away from overreach. The anchor article develops the freshness argument (Article 1); the agent-specific treatment is Article 4.
FAQ
Is multi-model the same as converged? No. Multi-model describes what a product can store; converged describes which guarantees span the models. The 2019 ACM survey found no cross-model transaction management in any system it examined (See “Multi-model Databases: A New Journey to Handle the Variety of Data,” (author’s accepted text)) — storage breadth and guarantee breadth are different properties.
Which databases are multi-model? By DB-Engines’ labeling, most leading systems: nine of the June 2026 top ten carry the tag (See DB-Engines Ranking, and methodology). That is precisely why the label is no longer the discriminating question — the five guarantees are.
Is PostgreSQL with extensions a converged database? It is the strongest composite: pgvector, PostGIS, and AGE genuinely share one transaction manager, one MVCC, one security model. The documented seams are in optimization — post-index filtering in pgvector, planner opacity over graph properties in AGE (See “Apache AGE performance best practices”; Apache AGE manual). PostgreSQL 19’s standard GRAPH_TABLE moves graph queries into the engine proper, which narrows the gap — and validates the convergence direction.
Is Google Spanner a converged database? It is the closest of the widely used systems. Spanner passes the three hardest tests — one distributed ACID transaction across relational, graph, JSON, and vector; one query plan across them; and global external consistency, with full-text search maintained inside the transaction rather than in an eventually-consistent sidecar (See “The power of multi-model Spanner for the agentic era”; Spanner Graph; TrueTime external consistency; Google Cloud Spanner full-text search; Search indexes). Where it stops short of a converged engine is specific: no document API or relational↔︎document duality — its “multi-model” is SQL, graph, vector, and search over relational tables; no row-level security (See the reference); and a single static ScaNN vector index you periodically rebuild, versus a choice of incrementally maintained HNSW or auto-reorganizing, online IVF. Convergence is a spectrum, and Spanner sits high on it — which is exactly why the guarantees, not the label, are the right axis.
Did the SQL standard make the distinction obsolete? It moved the boundary. With JSON (SQL:2016, native type SQL:2023) and property graphs (SQL:2023) in the standard, model support is increasingly a language feature rather than a product category. What remains differentiating is the engine behind the language: one transaction boundary, one optimizer, one consistency model, one governance domain.
Methodology and freshness
Every code sample is a verbatim excerpt of a script in converged-database-lab (module 02, published with this article), executed by GitHub Actions CI — on every change and nightly — against Oracle AI Database 26ai Free. Module 02: 3 scripts, 18 assertions, including an exact-set check that the survey-challenge result equals the survey’s published answer. Reproduce in three commands:
docker compose up -d --build oracle
pip install -r validator/requirements.txt
python validator/run.py