There is no single fastest database, because “fastest” is the wrong word. The honest question is “fastest for what,” and the answer changes depending on whether the workload is transactional reads, transactional writes, analytical queries, in-memory key-value, embedded single-node, or time-series. A team that picks the wrong database for the workload pays 10x to 100x in latency, 3x to 10x in cost, or both. The benchmarks that compare apples to oranges produce the “X is the fastest database” headlines that get shared and that nobody should trust.
The reason the question is so popular is that the answer matters. A team building a real-time analytics dashboard does not want to hear “it depends” — they want to know which database to provision. A team building a transactional application does not want to hear “it depends” — they want to know which database to use. The honest answer is “it depends,” and the rest of this post is the “on what” and the “for what” and the “with what trade-offs.”
Table of contents
- The six workloads and the database that wins each one
- OLTP reads: Postgres is the boring winner
- OLTP writes: Postgres, again, with the right tuning
- OLAP at scale: ClickHouse is the answer
- Key-value and cache: Redis is the answer
- Embedded single-node: DuckDB or SQLite
- Time-series: the specialized field
- The benchmarks that actually matter (and the ones that don’t)
- The cost dimension that the “fastest” question usually skips
- When the answer is “use two databases, not one”
- How to pick without overthinking it
- FAQ
The six workloads and the database that wins each one
The “fastest database” question collapses to one of six workload categories. Each one has a clear winner, and the wrong choice is expensive in latency, in cost, or in both.
| Workload | The fastest realistic choice | Why it wins |
|---|---|---|
| OLTP reads (web app, point lookups by primary key) | Postgres | B-tree index on the primary key is the most optimized data structure in any database. The read latency is sub-millisecond for a hot row. |
| OLTP writes (inserts, updates, deletes) | Postgres (with WAL tuning) | Postgres is the only one that does ACID writes at high throughput AND gives you a SQL interface. The write path is well-engineered. |
| OLAP at scale (analytics, aggregations, dashboards) | ClickHouse | Columnar storage + vectorized execution = 10-100x faster than row-oriented databases for analytical queries on large datasets. |
| Key-value / cache (session, rate limit, leaderboard) | Redis | In-memory + simple data structures = the lowest possible latency for non-persistent data. |
| Embedded single-node (mobile, edge, desktop) | DuckDB or SQLite | Embedded means no server, no deploy, no auth. The two mature options are SQLite (general purpose) and DuckDB (analytical). |
| Time-series (metrics, IoT, observability) | TimescaleDB (Postgres extension) or InfluxDB | Specialized compression and retention policies for time-stamped data. |
The “winner” of each row is not a universal “fastest database” — it is the database that is fastest for the workload. The same team might use Postgres for the application, ClickHouse for the analytics, and Redis for the cache. The team that picks one database for every workload is the team that pays the cost of the mismatch.
OLTP reads: Postgres is the boring winner
Online Transaction Processing (OLTP) is the work the application does on every request: a primary key lookup, a join on a foreign key, a row update. The latency target is sub-10-millisecond. The throughput target is thousands of queries per second per node.
Postgres wins this workload because the B-tree index on the primary key is the most optimized data structure in any database. The read path is: hash the primary key, walk the B-tree, return the row. The latency is dominated by the disk seek (or the in-memory cache hit), and the database engine does not have to do anything fancy.
The alternatives (MySQL, MariaDB, SQL Server, Oracle) all have similar B-tree performance. The reason Postgres is the default is the feature set: JSON support, full-text search, generated columns, window functions, common table expressions, and an extension ecosystem that covers the long tail of use cases. For most OLTP workloads, the choice between Postgres and MySQL is a matter of taste, but Postgres is the more modern default.
For a real production workload, the OLTP read performance is determined less by the database and more by the index. A query that uses the primary key returns in sub-millisecond. A query that does a full table scan returns in seconds. The performance is in the index, and the index is in the schema, and the schema is in the design.
For a managed Postgres like the one on RunxBuild, the OLTP read performance is the same as self-hosted Postgres. The platform handles the backups, the replication, the upgrade path. The application talks to the same Postgres wire protocol.
OLTP writes: Postgres, again, with the right tuning
OLTP writes are the workload that exposes the difference between databases. A write is a row inserted, a row updated, a row deleted. The latency target is sub-10-millisecond. The throughput target is thousands of writes per second per node.
Postgres wins this workload because it does ACID writes at high throughput. The Write-Ahead Log (WAL) is the part that makes Postgres safe — every write is recorded to the log before the row is updated, so a crash mid-write does not corrupt the database. The cost is the disk write to the log, which is the bottleneck for write-heavy workloads.
The tuning for high-throughput writes is well-known:
Use COPY for bulk inserts. COPY is 10x faster than INSERT for large batches. The COPY command streams the data into the table without parsing individual statements. For a migration that loads millions of rows, COPY is the difference between 30 seconds and 5 minutes.
Tune synchronous_commit. The default is on, which means the WAL is flushed to disk on every commit. Setting it to off (or local for a single-node setup) gives sub-millisecond commit latency at the cost of losing the last few transactions in a crash. For a non-critical workload, the trade-off is worth it.
Use UNLOGGED tables for ephemeral data. A staging table that gets truncated after use does not need WAL protection. The UNLOGGED keyword tells Postgres to skip the WAL, and the write throughput is 5-10x faster. The trade-off is that the data is lost on a crash, which is fine for ephemeral data.
For a managed Postgres, the platform handles the WAL tuning defaults. The application does not have to think about the WAL. The platform’s job is to give the application the right defaults, and the application’s job is to not override them without a reason.
OLAP at scale: ClickHouse is the answer
Online Analytical Processing (OLAP) is the work the analytics dashboard does: aggregate a billion rows, group by a column, compute a percentile, return in seconds. The latency target is sub-second for interactive dashboards. The throughput target is billions of rows per query.
ClickHouse wins this workload by a wide margin. The architecture is columnar — the data is stored by column, not by row — and the query engine is vectorized — the operations process batches of values using CPU SIMD instructions. The combination is the difference between a 30-second query and a 300-millisecond query on the same dataset.
The benchmark that tells the story is ClickBench, an open-source benchmark that runs the same query suite against multiple analytical databases. The results consistently show ClickHouse at the top, with DuckDB close behind for single-node workloads and ClickHouse 10-100x faster than row-oriented databases like Postgres for analytical queries.
The trade-offs are real:
ClickHouse is not a transactional database. There is no ACID, no row-level updates, no foreign keys. The data is append-mostly, and the updates are eventually consistent.
ClickHouse is harder to operate than Postgres. The configuration is finicky, the storage is columnar, and the failure modes are different. A team that already knows Postgres should think hard before adding ClickHouse to the stack.
ClickHouse is not free at scale. The open-source version is free; the managed versions (ClickHouse Cloud, Tinybird, Altinity) are not. The cost is in the same order of magnitude as a managed Postgres for the same data volume, but the feature set is different.
For a team that is starting from scratch and the workload is mixed (some transactional, some analytical), Postgres is the right default. For a team that has outgrown Postgres for analytics (the dashboard takes 30 seconds, the data is 100 million rows, the queries are aggregation-heavy), ClickHouse is the right answer.
Key-value and cache: Redis is the answer
Key-value and cache is the work the application does between the request and the database: session storage, rate limit counters, leaderboards, ephemeral state. The latency target is sub-millisecond. The throughput target is hundreds of thousands of operations per second per node.
Redis wins this workload because it is in-memory, the data structures are simple, and the protocol is text-based and fast. The latency is dominated by the network round-trip, and Redis is the lowest-latency persistent option in the mainstream.
The alternatives (Memcached, KeyDB, DragonflyDB) all have similar performance. The reason Redis is the default is the feature set: pub/sub, transactions, Lua scripting, streams, and a client library in every language. For most key-value workloads, the choice between Redis and Memcached is a matter of taste, but Redis is the more modern default.
The trade-off is persistence. Redis is in-memory, which means the data is lost on a crash unless the persistence is enabled. The default RDB snapshots are good enough for a cache (the data is ephemeral by design) but not good enough for a primary store. For a primary store, the data should be in Postgres and the cache should be a copy.
For a managed Redis like the one on RunxBuild, the cache and the primary store are separate concerns. The primary store is Postgres, the cache is Redis, and the application reads from the cache first and falls back to the database. The same pattern works for any cache layer.
Embedded single-node: DuckDB or SQLite
Embedded single-node is the workload for a mobile app, an edge function, a desktop application, a CLI tool, or a small server that does not need a separate database process. The data is local to the application, the latency is sub-millisecond, and the throughput is “enough for the application.”
SQLite wins the general-purpose embedded workload. The database is a single file, the API is the C library, and the bindings exist for every language. The performance is excellent for transactional workloads, and the database has been battle-tested for 20+ years.
DuckDB wins the analytical embedded workload. The database is a single file, the API is the C++ library, and the bindings exist for Python, R, Java, and Node. The performance is excellent for analytical workloads, and the database is the “SQLite for analytics.”
The trade-off is the same as the columnar-vs-row decision at scale. SQLite is row-oriented and transactional. DuckDB is columnar and analytical. For a mobile app that does point lookups, SQLite. For a CLI tool that aggregates a CSV, DuckDB.
For an application that needs both, the right answer is two databases: SQLite for the transactional state, DuckDB for the analytical queries. The data flow is the application writes to SQLite and reads from DuckDB, and the two are kept in sync by a background process. The same pattern works for any embedded application that has both transactional and analytical workloads.
Time-series: the specialized field
Time-series is the workload for metrics, IoT sensors, observability data, and any other workload where the data is a sequence of timestamped values. The latency target is sub-millisecond for the hot path and sub-second for the cold path. The throughput target is millions of inserts per second and billions of rows stored.
The honest answer for time-series is that the field is specialized enough that the right choice depends on the specific use case.
TimescaleDB is the Postgres extension that turns Postgres into a time-series database. The trade-off is operational simplicity (one database to run) for analytical performance (slower than ClickHouse for the same workload).
InfluxDB is the dedicated time-series database. The trade-off is operational complexity (a separate database to run) for analytical performance (faster than TimescaleDB for the same workload).
ClickHouse with the MergeTree engine is a third option. ClickHouse is not specifically a time-series database, but the MergeTree engine is well-suited for time-series data, and the analytical performance is the best in class.
For a team that already runs Postgres, TimescaleDB is the right default. The data lives in Postgres, the queries are SQL, and the operational footprint is the same. For a team that has outgrown TimescaleDB for analytics, ClickHouse is the right answer. For a team that is starting from scratch, the right answer depends on the team’s existing operational footprint.
The benchmarks that actually matter (and the ones that don’t)
A benchmark tells you the latency and throughput of a specific query on a specific dataset on a specific machine. The benchmark is a data point, not an answer. The benchmarks that matter are the ones that match your workload.
TechEmpower Framework Benchmarks is the most-cited benchmark for web frameworks. The benchmark runs a small set of HTTP requests against a small set of web frameworks, and the results show which framework is the fastest for a small set of queries. The benchmark is useful for choosing a web framework, not for choosing a database.
ClickBench is the most-cited benchmark for analytical databases. The benchmark runs a set of analytical queries against multiple databases, and the results show which database is the fastest for the specific query suite. The benchmark is useful for choosing an analytical database, not for choosing a transactional database.
The benchmark that matters for your application is the one that runs your queries against your data. A team that has a real workload should run a load test against the candidate databases with the real queries, on the real dataset, on the real machine. The benchmark that the team runs themselves is the benchmark that matters, and the one that the team does not run is the one that gets them in trouble.
The reason the “X is the fastest database” headlines are misleading is that the benchmark is a single query on a single dataset on a single machine. The headline is “X is fast” but the answer is “X is fast for this specific query on this specific dataset on this specific machine.” The general claim is not supported by the specific data.
The cost dimension that the “fastest” question usually skips
A database that is 10x faster than its competitor at 10x the cost is not the right answer. The “fastest” question ignores the cost dimension, and the cost dimension is the one that decides the production architecture.
Postgres is free. The database is open-source, the community edition is fully featured, and the only cost is the operational overhead. The managed versions (RDS, Cloud SQL, RunxBuild) charge per hour, and the cost is predictable.
ClickHouse is free for the open-source version. The managed versions (ClickHouse Cloud, Tinybird) charge per query or per data volume, and the cost is more variable. For a high-throughput analytical workload, the managed ClickHouse can be 3-10x the cost of a managed Postgres for the same data volume.
Redis is free for the open-source version. The managed versions (Redis Cloud, Upstash) charge per request or per data volume. For a high-throughput cache, the managed Redis can be 1-3x the cost of a managed Postgres for the same data volume.
MongoDB, Elasticsearch, Cassandra, and the other “fast” databases all have the same pattern: free for the open-source version, paid for the managed version, and the managed version is the one that the team actually uses in production.
The total cost of the database is not the license fee. The total cost is the license fee plus the operational overhead plus the engineering time to make the database work for the workload. A team that picks the “fastest” database without thinking about the operational overhead is the team that spends six months learning how to operate a database that the team did not need.
When the answer is “use two databases, not one”
The honest answer to “what is the fastest database” is often “two databases, not one.” The team that uses one database for every workload is the team that pays the cost of the mismatch. The team that uses two databases for the right workloads is the team that gets the latency, the cost, and the operational simplicity right.
The common pattern:
Postgres for the application state. The application reads and writes the primary data to Postgres. The OLTP workload is what Postgres is best at. The operational overhead is the same as a single database.
Redis for the cache. The application reads frequently-accessed data from Redis first and falls back to Postgres. The cache hit ratio is 90%+, and the average read latency is sub-millisecond.
ClickHouse for the analytics. The application writes a copy of the data to ClickHouse for the analytics dashboard. The analytical queries run on ClickHouse, not on Postgres, so the OLTP workload is not affected by the analytical workload.
The three-database pattern is the right answer for a team that has outgrown a single database. The single-database pattern is the right answer for a team that has not. The “fastest database” question is the question that gets asked when the team is between the two, and the right answer is “it depends on the workload.”
How to pick without overthinking it
A short, opinionated decision tree for the team that has to pick a database this week.
Step 1. If the workload is a single application with OLTP queries, pick Postgres. The reasoning is in the OLTP section above. The cost is free, the operational overhead is well-known, and the feature set covers the long tail of use cases.
Step 2. If the workload has a cache layer, add Redis. The reasoning is that the cache hit ratio is 90%+, and the cost of the cache is a small fraction of the cost of the database.
Step 3. If the workload has analytical queries that take more than 5 seconds on Postgres, add ClickHouse. The reasoning is that the analytical queries should not run on the OLTP database, and ClickHouse is the best-in-class option.
Step 4. If the workload is a mobile app or a desktop application, pick SQLite or DuckDB depending on whether the queries are transactional or analytical.
Step 5. If the workload is time-series, pick TimescaleDB (the Postgres extension) for a small scale, InfluxDB or ClickHouse for a larger scale.
The decision tree is not perfect. The right answer for any specific workload depends on the specific queries, the specific data, and the specific operational footprint. The decision tree is the right answer for 80% of the teams, and the remaining 20% should read the rest of this post.
FAQ
What is the fastest database overall?
There is no single fastest database. The honest answer is “fastest for what,” and the answer changes depending on whether the workload is OLTP, OLAP, key-value, embedded, or time-series. The table above covers the six workloads and the database that wins each one.
Is Postgres fast enough for most workloads?
Yes. Postgres is the right default for most OLTP workloads, and the performance is fast enough for the vast majority of applications. The cases where Postgres is not fast enough are analytical queries on large datasets (ClickHouse is the right answer) and in-memory cache (Redis is the right answer).
Why is ClickHouse faster than Postgres for analytics?
ClickHouse stores the data by column, not by row, and the query engine uses vectorized execution (CPU SIMD instructions) to process batches of values at once. The combination means that an analytical query that reads 10 columns from a 1-billion-row table reads 10 columns from disk, not 1 billion rows. The reduction in I/O is the source of the 10-100x speedup.
When should I use Redis as a primary store?
Almost never. Redis is in-memory, which means the data is lost on a crash unless persistence is enabled, and the persistence is not as durable as a transactional database. For a primary store, use Postgres (or another transactional database), and use Redis as a cache. The data that needs to survive a crash should be in Postgres. The data that can be rebuilt from the primary store should be in Redis.
Is MongoDB fast?
MongoDB is fast for the use cases it is designed for (document store, flexible schema, horizontal scaling). MongoDB is not fast for the use cases it is not designed for (relational queries, complex aggregations, transactional consistency). A team that picks MongoDB for a relational workload is the team that pays for the mismatch.
What database does the team behind ChatGPT use?
The team behind OpenAI uses Postgres for the application state and ClickHouse for the analytics, the same pattern recommended above. The pattern is not unique to OpenAI; the pattern is the default for any team that has outgrown a single database for both OLTP and analytics.
How do I benchmark a database for my specific workload?
The benchmark that matters is the one that runs your queries against your data. The setup is: take a representative sample of the production data, take a representative sample of the production queries, and run the queries against the candidate databases on the same machine. The result is the latency and throughput for your specific workload, and the answer is the database that is fast enough for your latency target and cheap enough for your cost target.