Cloud Parts

Apache Doris

An open-source MPP analytical database, born at Baidu as Palo, that serves sub-second queries on fresh, updatable data through the MySQL protocol and also queries Iceberg, Hudi, Paimon and Hive tables in place.

Type
Open source
License
Apache 2.0
Facts checked
10 October 2026

What it is

A Doris cluster has two kinds of process. Frontends (FEs) speak the MySQL protocol, parse and plan SQL with a cost-based optimizer, and hold the metadata in BDB JE: one master writes it and replicates it to followers, which elect a new master if it fails, and observers add read capacity. Backends (BEs) store data in columns and run the plans. It is a massively parallel processing (MPP) engine: the planner cuts each query into fragments that run on every BE at once, and for joins it picks between broadcast, shuffle, bucket-shuffle and colocate strategies. Operators are vectorized, working on columns in batches with SIMD instructions. No ZooKeeper or other external service is needed.

You choose a table model when you create a table, and can’t change it later. Duplicate Key keeps every row, Aggregate Key folds rows with the same key using per-column functions such as SUM, and Unique Key keeps the latest row per key. Since 2.1, Unique Key tables use merge-on-write by default: a write looks up the old row in a primary-key index and marks it deleted in a bitmap, so queries never merge versions and SQL UPDATE and DELETE work. Every table is split twice, by PARTITION BY range or list (often a date, with partitions created automatically if you like) and then by DISTRIBUTED BY HASH into buckets, each a tablet with 3 replicas by default. On top come inverted indexes (since 2.0, built on CLucene) for fast filters and full-text MATCH queries, vector indexes (since 4.0, HNSW and later IVF, built on Faiss), single-table synchronous materialized views and multi-table asynchronous ones that can refresh only the partitions that changed. Data arrives through Stream Load over HTTP, Routine Load from Kafka with exactly-once delivery, plain INSERT, or the Flink and Spark connectors.

Since 3.0 (July 2024) Doris can also run with storage and compute separated: data lives in S3, Azure, Google Cloud, other object stores or HDFS, a Meta Service backed by FoundationDB keeps the data-layer metadata, and stateless BEs in separate compute groups share it with a local cache. External catalogs point Doris at Hive, Iceberg, Hudi, Paimon and Delta Lake tables and JDBC databases, and it can write back to Iceberg and Hive. Version 4.0 (October 2025) added vector search, LLM functions in SQL and spilling to disk, and 4.1 (April 2026) is the current line. Doris is an Apache top-level project; VeloDB, founded by original contributors, sells VeloDB Cloud, and Alibaba Cloud sells ApsaraDB for SelectDB, both built on it.

Why teams pick it

  • One engine for real-time dashboards, upserts and search: merge-on-write Unique Key tables take CDC updates within seconds, and inverted and vector indexes let the same table answer MATCH and nearest-neighbour queries without a separate Elasticsearch or vector database
  • Simple to run for a distributed database: only FE and BE processes in the classic mode, metadata replicated by the FEs themselves, and any MySQL client, driver or BI tool can connect
  • Built-in ingestion paths for common sources: Stream Load over HTTP, Routine Load from Kafka with exactly-once delivery, and a Flink connector that syncs whole MySQL, Oracle or PostgreSQL databases through Flink CDC
  • Also a lake query engine: one SQL session can join internal tables with Iceberg, Hudi, Paimon and Hive tables, write results back to Iceberg or Hive, and cache slow lake queries in materialized views

Watch out for

  • Schema choices are hard to undo: the table model can’t be changed after CREATE TABLE, and a Unique Key table’s partition columns must be part of its key, so a wrong choice means a new table and a full reload
  • Point writes are costly: each single-row UPDATE is its own transaction, so the docs recommend batching through Stream Load or group commit, and merge-on-write pays a key lookup on every load
  • Storage-compute separation adds moving parts: you run a FoundationDB cluster and the Meta Service as well as FEs and BEs, and queries that miss the local cache wait on object storage
  • Lake support is uneven: Hudi and Delta Lake (still experimental) are read-only, Iceberg tables in AWS Glue can’t be written, and Paimon writes are new in the 4.1 line
  • StarRocks began as a fork of Doris 0.13 in 2020 and the two have since diverged, so similar-looking SQL, docs and tuning advice don’t always carry over between them

Alternatives

What all real-time analytics databases have in common →

How it fits with other technologies

A Unique Key table in a one-FE, one-BE Docker cluster: upsert, update, aggregate · sql

-- Start Doris 4.1.4 in Docker (official images, arm64 and amd64), then connect:
--   curl -fsSL https://doris.apache.org/files/start-doris.sh | bash -s -- -v 4.1.4
--   mysql -uroot -P9030 -h127.0.0.1
-- (FE and BE used about 2.7 GB of memory together, idle, on an arm64 Mac.)

CREATE DATABASE shop;
USE shop;

CREATE TABLE orders (
    order_id BIGINT,
    order_date DATE,
    country VARCHAR(2),
    status VARCHAR(10),
    amount DECIMAL(10, 2)
)
UNIQUE KEY (order_id)
DISTRIBUTED BY HASH (order_id) BUCKETS 4
PROPERTIES ("replication_num" = "1");  -- one BE, so one replica

INSERT INTO orders VALUES
    (1, '2026-10-01', 'DE', 'created', 40.00),
    (2, '2026-10-01', 'US', 'paid', 25.50),
    (3, '2026-10-02', 'US', 'paid', 99.90),
    (4, '2026-10-02', 'DE', 'paid', 15.00);

-- Same key again: the new row replaces the old one.
INSERT INTO orders VALUES (1, '2026-10-01', 'DE', 'paid', 42.00);
SELECT * FROM orders WHERE order_id = 1;
-- +----------+------------+---------+--------+--------+
-- | order_id | order_date | country | status | amount |
-- +----------+------------+---------+--------+--------+
-- |        1 | 2026-10-01 | DE      | paid   |  42.00 |
-- +----------+------------+---------+--------+--------+

-- Unique Key tables also take SQL UPDATE and DELETE.
UPDATE orders SET status = 'refunded' WHERE order_id = 4;
DELETE FROM orders WHERE order_id = 3;

SELECT country, count(*) AS orders, sum(amount) AS revenue
FROM orders
GROUP BY country
ORDER BY country;
-- +---------+--------+---------+
-- | country | orders | revenue |
-- +---------+--------+---------+
-- | DE      |      2 |   57.00 |
-- | US      |      1 |   25.50 |
-- +---------+--------+---------+

-- SHOW CREATE TABLE orders shows "enable_unique_key_merge_on_write" = "true".

Three table models#

The KEY(...) clause names the columns each tablet is sorted by, and a sparse prefix index covers the first 36 bytes of that key. What happens to rows with the same key depends on the model.

ModelRows with the same keyUpdates and deletesFits
Duplicate KeyAll kept, appended as writtenNo UPDATE; reload insteadLogs, click streams, IoT readings, raw facts
Unique KeyOnly the latest kept; merge-on-write marks the old row deleted at write timeSQL UPDATE and DELETE, partial-column upserts, a sequence column for out-of-order CDC eventsCDC sinks, orders, user profiles, dimension tables
Aggregate KeyFolded into one row with each value column’s function (SUM, MAX, REPLACE, BITMAP_UNION)DELETE only on key columnsFixed rollups such as clicks per ad per day

Lake tables Doris can reach#

An external catalog stores only connection details; Doris fetches schemas, partitions and file locations from the metastore each time. This is the 4.x documentation’s support matrix.

FormatReadWrite backNotes
Apache IcebergYesINSERT, INSERT OVERWRITE, UPDATE, DELETE, MERGE INTOHive Metastore, REST, Glue, file system and Aliyun DLF catalogs; no writes or DDL through Glue or DLF
Apache HiveYesYesHive Metastore, Glue (read only) or DLF
Apache PaimonYesNew in 4.1Table DDL since 4.1.0; the REST catalog is experimental
Apache HudiYes, including time travel and incremental readsNoCopy-on-write and merge-on-read tables
Delta LakeExperimental, since 3.0.1NoReads through Trino’s Delta Lake connector, loaded as a plugin on all FE and BE nodes

Ways to run it#

Self-managed, storage and compute together

Apache 2.0

The classic FE plus BE cluster on Linux (x86 with or without AVX2, or ARM64), with data on the BEs’ local disks. The Docker quick start runs the same images, but only for testing: data is lost when the container goes.

Self-managed, storage and compute separated

since 3.0

FEs, a FoundationDB-backed Meta Service and stateless BEs in compute groups, with data in object storage or HDFS. The Doris Operator deploys either mode on Kubernetes.

VeloDB Cloud

VeloDB

A managed service from VeloDB, founded in May 2023 by original Doris contributors. Runs on AWS, Google Cloud and Azure, as SaaS or in your own cloud account (BYOC), with storage and compute separated and SOC 2, SSO and encryption added.

ApsaraDB for SelectDB

Alibaba Cloud

Alibaba Cloud’s managed service, described as 100% compatible with Apache Doris. Its kernel is a cloud-optimized Doris supported by Alibaba Cloud and the SelectDB team, with data in Alibaba’s OSS and several compute clusters sharing it.

See it in a real stack

No architecture uses Apache Doris yet. Drop it into the playground and wire it up yourself.Open playground →
Where it came from2017–2026

Baidu’s advertising platform had to show every advertiser detailed statistics, updated within minutes, both as live reports with low latency and as high-throughput ad-hoc analysis. It first ran on sharded MySQL, which stopped keeping up as data grew, and then on an in-house statistics database built on a key-value store, which scanned slowly, needed code instead of SQL and depended on many other systems. Other teams stitched together Spark SQL or Impala on HDFS and HBase, MySQL fed by MapReduce, and commercial databases. Baidu’s answer was Palo: Google Mesa’s data model for storage, with its own distributed storage engine that needed no distributed file system, joined to the Apache Impala query engine, in one tightly coupled system.

Baidu open-sourced Palo in 2017. It entered the Apache Incubator in July 2018 and was renamed Doris, and graduated as a top-level project in June 2022, when the ASF counted more than 500 companies using it. Along the way, in 2020, a separate team took Doris 0.13 and built a commercial product on it, DorisDB, which became StarRocks: it kept Doris’s framework and columnar storage and added its own vectorized engine, optimizer and update engine. The two projects have developed independently since.

Doris itself moved well beyond reporting. Version 2.0 (August 2023) added inverted indexes for search, 2.1 (March 2024) made merge-on-write the Unique Key default and added asynchronous materialized views, 3.0 (July 2024) separated storage from compute and could write back to data lakes, and 4.0 (October 2025) added vector search and LLM functions. VeloDB, founded in May 2023 by original contributors, says half of the Doris PMC members and committers work there.

Why it’s built this way

One tightly coupled system with no external dependencies
Baidu’s earlier statistics database depended on many other systems and was hard to operate. Palo put query planning and the catalog in the frontend and storage and execution in the backend, so a cluster is just those two daemons; even frontend replication and leader election run on an embedded BDB JE.
Speak the MySQL wire protocol
Engineers preferred SQL, MySQL compatibility made existing BI tools such as Tableau easy to connect, and the many MySQL client libraries cut both Baidu’s development cost and users’ cost of adopting it.
Two-level partitioning: range, then hash buckets
Hashing a fact table only by user skews when one user is huge, and ranging only by date skews when one day explodes. Range partitions by date with hash buckets inside separate old data from new, avoid merging partitions nobody updates, and let each partition have its own bucket count.
An in-memory catalog with replicated logs
Keeping metadata in an external database is fine for occasional ad-hoc queries, but Hive’s metadata lookups sometimes took tens of seconds or even minutes, far too slow for high-concurrency reporting. Palo kept the catalog in memory, logged every change, checkpointed to local disk and replicated the log to follower and observer frontends.

Timeline

  1. 2017

    Baidu open-sources Palo, its ad-reporting database

  2. 2018

    Enters the Apache Incubator in July and is renamed Doris

  3. 2020

    Version 0.13 released; a separate team builds DorisDB, later StarRocks, on it

  4. 2022

    Graduates as an Apache top-level project in June

  5. 2024

    Version 3.0 in July adds storage-compute separation and writes back to lakes

  6. 2025

    Version 4.0 in October adds vector search and AI functions

  7. 2026

    Version 4.1 in April; 4.1.4.1 follows in September

Sources35 · facts checked 10 October 2026

Improve this page on GitHub