On this page
Database marketing runs on acronyms, and the acronyms have drifted until they mean "our product". HTAP is the worst case: it has been claimed by systems that differ in every property you would care about. So this post starts with definitions narrow enough to be useful, then sorts real products by what they do rather than what they call it, and ends with Loams: what we ship, what we do not, and the plan in design 58.
Our opinion, up front: the acronym does not matter. Five properties do. How fresh the analytical view is, and whether that bound is stated. How many copies of the data exist, and who keeps them in sync. Whether the analytical copy is in an open format you can read with other engines. Where a commit is acknowledged. And whether a heavy query can hurt a checkout. Every system below makes a different trade among those five, and most of them make it well for their market.
Definitions
OLTP (online transaction processing). Many short transactions, each touching a few rows found by key or index, each needing a commit in milliseconds, with concurrency control so that two of them do not corrupt each other. Row-oriented storage and B-tree or LSM indexes. Postgres, MySQL and the distributed KV under Loams Live are OLTP stores.
OLAP (online analytical processing). Few long queries, each scanning many rows but only a few columns, aggregating them. Columnar storage with statistics, so whole files can be skipped, and vectorized execution. Freshness of minutes or hours is usually acceptable, and data typically arrives in bulk. ClickHouse, DuckDB, Snowflake and Iceberg tables queried by Trino or Spark are OLAP.
HTAP (hybrid transactional/analytical processing). Analytical queries over the transactional data itself, rather than over a copy someone loads overnight. We hold the term to three conditions: the analytical view has a stated freshness bound (seconds, not "whenever the job ran"); you do not operate a pipeline to get it; and analytical load is isolated from transactional latency. A system that meets one of the three is not HTAP; it is a database with a connector.
LTAP (lake transactional/analytical processing). Databricks' name, announced on 2026-06-16 for Lakebase, its Neon-based Postgres service, and still marked "coming soon". The idea: the Postgres storage layer (the pageserver) transcodes pages from row format into open columnar files as it materializes them, so the transactional database's own storage is a lake table. Analytical queries read object storage as of an LSN and fetch the newest changes from the pageserver (Databricks). LTAP is a specific shape of HTAP, not a new category, and it is a good one.
The four shapes
Design 58 sorts every shipping HTAP system into four shapes (§1.2, Appendix A.3). The shape decides the five properties more than any feature list does.
1. One engine with a hybrid format. One process stores rows and columns and plans across both: CedarDB (from TUM's Umbra research, Postgres-compatible, Cloud generally available on 2026-10-14), SingleStore and OceanBase. Freshness is immediate, because there is one copy. The cost is that analytics lives inside one vendor's engine and storage format, and isolation between the two workloads is that engine's scheduling problem.
2. A synced columnar replica. The row store stays the leader, and a columnar copy follows its replication log. TiDB's TiFlash is a Raft learner of TiKV's regions; Spanner's columnar engine became generally available on 2026-04-17; AlloyDB has a columnar engine in memory. Isolation is good, because analytical queries run on other nodes. Freshness is the replication lag. There are two copies, but one system keeps them consistent, which is the part people underrate.
3. Columnar at the storage layer. The storage layer writes open columnar files as part of its normal work, and reads merge recent changes. This is LTAP. One copy, open format, bounded freshness. Nobody ships it yet.
4. CDC into a lake. Debezium or a vendor connector streams the change log into Iceberg or Delta tables. Open format, any engine can read it, and it works with any source database. It is also two systems, a pipeline to run, and minutes of lag. It is the common default because it is the only shape you can build from parts.
What each product gets right, and what it misses
These are short, and each is about fit, not quality. All of these are serious systems.
Snowflake. Snowflake's hybrid tables, part of what it calls Unistore, add a row store with indexes and enforced primary keys for point reads and writes, next to its columnar storage. What it gets right: one platform, one governance model, analytics on fresh rows without a pipeline. What it misses, for us: it is proprietary, the data lives in Snowflake's storage rather than your bucket in an open format, and it does not speak the Postgres or MySQL wire protocol that application frameworks expect.
Databricks. Lakebase is built on Neon's architecture, which Databricks acquired in 2025: a commit is acknowledged by a quorum of Paxos safekeepers, and the pageserver writes page history to object storage off the commit path (Databricks). LTAP is the right idea, and we say so in design 58 §6.5: our phases 2 and 3 are the same idea. What it misses: it is a managed service, and Neon's public repository has been dormant since the acquisition, with no commit since 2026-08-31 (design 51 §2). You cannot run LTAP yourself.
TiDB. TiDB is the most complete open-source HTAP system we know: MySQL wire, distributed transactions on TiKV, and TiFlash as a columnar learner (shape 2). PingCAP also opened a PostgreSQL-protocol public preview on TiDB Cloud Starter on 2026-10-15, and its TiDB X architecture persists the Raft log to local disk first and uploads WAL chunks to object storage in the background (docs). What it misses for us: TiFlash's columnar data is in TiFlash's own format, not a lake table other engines read, and TiDB X's shared-storage engine is not public yet; PingCAP has said its core code is to be open-sourced by the end of 2026 (design 58 Appendix A.1). We run TiDB as Loams SQL's compute and do not depend on TiFlash (D131).
SingleStore. One engine with rowstore and columnstore tables and the MySQL wire protocol (shape 1, docs). It gets the hardest part right: one copy and one planner for both workloads. It is proprietary, and its storage is its own.
Neon. Neon separated Postgres compute from storage and put history on object storage, which gave it branching and scale to zero. That design is why we forked it as Loams Postgres. It never had an analytical path: analytics on Neon meant CDC to somewhere else.
ClickHouse. The best OLAP engine you can run yourself, and an honest one: its documentation describes row updates as mutations, heavy operations that rewrite data parts asynchronously. That is a deliberate trade for scan speed. ClickHouse is the analytical half of an HTAP pair, never the transactional half, which is exactly how we use it in the Loams House (as chDB, ClickHouse as a library).
DuckDB. An in-process analytical engine with excellent Parquet and Iceberg readers. Its concurrency model allows one process to read and write a database file at a time. It is the best tool for analytics on your laptop, and a great reader of lake tables someone else writes. It does not try to be a shared transactional database, and should not.
Design 58 sums up the landscape in one sentence, and we have not found a counterexample since: nobody ships all four together, open source, Postgres wire, HTAP, and S3 as the source of truth (§1.2). That gap is what our plan aims at. It is a gap in shipping, not in ideas. Databricks has published the idea, and the difference rests on whether we ship it, open, on your bucket (§6.5).
Where commits are acknowledged
One more finding from the same research shapes everything else: serious databases on object storage keep commits off S3 (design 58 §1.2, Appendix A.2). Neon and Lakebase acknowledge on a Paxos quorum. TiDB X persists the Raft log locally first. OceanBase acknowledges on its LogService. S3 holds history and branches; it is not on the commit path.
We measured why: a pure bucket WAL in our spike took 22 ms at p50 and 148 ms at p99 (D234). So Loams Postgres acknowledges a commit on loams-wal's quorum and group-commits to the bucket every 250 ms (D714). That matters for HTAP because the analytical copy can only be as fresh as the point where the durable log becomes readable, and our phase 3 reads that log directly.
What Loams has today
From the 0.1.0 feature status table, stated as plainly as it is there:
- Loams SQL (available): MySQL-compatible SQL on a patched TiDB over the shared TiKV, designed with one keyspace per branch (D723).
- Loams Postgres (available): our Neon fork, storage on the bucket. Its images are still pinned to Neon's last public build until the fork's own builds land, and the development stack runs with
fsync = off. - Loams House (experimental): ClickHouse-compatible analytics on chDB, whose only storage of record is Iceberg on the bucket (D762). Its lake tables take DDL, reads,
INSERT,CREATE TABLE … AS SELECTandTRUNCATE, and the engine reaches it over TLS on a private network. Nothing feeds it from Loams SQL or Loams Postgres yet: that is phase 1 below. - The engine: collections, hybrid retrieval, SQL over Arrow Flight SQL, and the Postgres and MySQL wire protocols over collections (all available).
- Iceberg analytics in the engine: planned. The engine does not write Iceberg tables yet.
So today Loams has an OLTP side (Loams SQL, Loams Postgres, Live) and an OLAP side (the House), on one bucket, with no HTAP path between them. If you want analytics on your Postgres data in Loams today, you would build shape 4 yourself. We would rather say that than let the acronym imply otherwise.
The plan: three phases
We settled on HTAP in three phases on 2026-10-16 (D1051). Phases 2 and 3 come after Loams Postgres is generally available.
Phase 1: CDC into Iceberg (D1052). Nothing new is invented. pgoutput logical replication feeds a Loams stream, with the slot confirmed only after the append (D154). A House pipe reads the stream and writes an Iceberg lake table, committing the consumed offsets in the same Iceberg snapshot as the rows (D769), which makes the path exactly-once without a lease service. A replace-on-key mode turns updates and deletes into a table that reflects them. One command, loams pg analytics enable <project>/<branch>, will create the publication, bridge, stream, table and pipe together. Postgres goes first; Loams SQL follows when loams-sqlcdc, our consumer of TiKV's change feed, is built (D738, Q922). This is shape 4, but a pipeline we run for you, with lag visible in system.loams_pipes.
Phase 2: the pageserver writes columnar (D1053). The pageserver already reconstructs whole pages when it creates image layers. For a table that opts in (ALTER TABLE … SET (loams.columnar = on)), it also decodes those pages' heap tuples into Arrow, writes Parquet, and commits an Iceberg snapshot through Lakekeeper tagged with the image layer's LSN. One copy, written by the component that already writes it, no pipeline. The hard parts are named in the design: tuple visibility at that LSN needs the commit log, TOASTed values must be de-TOASTed from the same LSN, and schema changes need the catalog as of then. It is off by default, per table, because it costs pageserver CPU and bucket writes, and those costs must show in usage.
Phase 3: fresh analytics (D1054). The House and the engine's DataFusion read the relation's Iceberg snapshot as of LSN L, then merge the changes after L, decoded from loams-wal or the pageserver's delta layers into Arrow and applied by primary key at read time.
This is the rule the retrieval engine already uses for its own tail: data committed to the log but not yet in its indexed form is merged into every strong read (the log is the spine). Every result reports the LSN it read up to and its lag. A client picks fresh or the cheaper snapshot. A tail over 256 MiB of WAL forces a snapshot read with a warning. That is our freshness bound: stated, reported per result, and enforced.
Around the phases. BI tools reach analytics through ADBC rather than ODBC (D1055): a thin Loams ADBC driver over the Flight SQL driver the engine already serves, and a Power Query connector, timed to Microsoft's move of Power BI and Fabric to ADBC (D1056). And the durability substrates stay separate by role (D1057): TiKV for small transactions and metadata, loams-wal for the Postgres byte log, the bucket for history and the columnar files.
How we score ourselves
Against the five properties from the start of this post, after phase 3:
| Property | Loams' answer (planned) |
|---|---|
| Freshness | Stated per result: the LSN read and the lag; fresh merges to the current commit |
| Copies | One for opted-in tables (phase 2); two with a managed pipeline otherwise (phase 1) |
| Open format | Iceberg and Parquet in your bucket, through an Iceberg REST catalog |
| Commit acknowledgement | loams-wal's quorum on local disk; the bucket every 250 ms |
| Isolation | Analytics run in House workers or engine query nodes, not in the Postgres compute |
Every row in that table is a design, not a shipped feature. The risks are written down too (design 58 §11): phase 2's tuple decoding is rated high risk, which is why phase 1 ships first and stays as the fallback, and why CI will check phase 2's files against a SELECT at the same LSN. LTAP, or someone else, may ship the same thing first. If so, our position is not novelty; it is that all of it is open source and runs on your bucket.
What actually matters
If you are choosing a system for analytics on transactional data, ignore the acronym on the box and ask five questions. What is the freshness bound, and does each result tell you what it reflects? How many copies are there, and who keeps them consistent when something fails halfway? Can another engine read the analytical copy without asking the vendor? Where is a commit acknowledged, and what is on that path? And what happens to checkout latency when someone runs a full scan at noon?
TiDB answers most of them well today. Databricks will answer them well for Lakebase customers. We intend to answer them in the open, on your bucket, and we are not there yet. What Loams is bad at today has the rest of that list.