After the disaster that was InfluxDB’s later versions, I decided it was time to move on from InfluxDB 1.11. For my evaluation, I tested three databases using real-world data and the actual queries I rely on. The versions tested were:
• InfluxDB: 1.11.8
• QuestDB: 8.2.3
• ClickHouse: 25.3.2
The test setup included two tables:
• price with over 7.7 billion rows (7,745,168,884)
• 1dayprice with around 13.5 million rows (13,580,249)
“ClickHouse only outperforms in specific queries like full time-range selects—for example, fetching BTC data from 1dayprice. However, after converting and testing multiple queries, it consistently performed slower in most other cases. So, while ClickHouse is a powerful database, it’s not the best fit for these scenarios.“
To clarify, I’m not testing import or ingestion speed—only SELECT query performance. All databases were pre-loaded with batch writes.
All DB use Compressions, For clickhouse column, for influxdb and questdb ZFS
Influxdb(ZFS) | QuestDB(ZFS) | ClickHouse |
384G | 254G | 225G |
Now let’s get into the testing. I won’t be using any benchmarking tools—just running the actual queries I use in production.
QuestDB | Influxdb |
SELECT coin, last(price_btc) AS price_last_btc, last(price) AS price_last, last(volume) AS value24_native, (last(volume) * last(price)) AS value24, first(price) AS yprice, last(mcap) AS mkcap, last(supply) AS supply, avg(price) AS price24_mean, min(price) AS min, max(price) AS max FROM ‘price_all’ WHERE time >= dateadd(‘h’, -24, now()) GROUP BY coin | SELECT last(price_btc) as btc, last(price) as price, last(volume) as volume, first(price) as price24, last(mcap) as mcap, last(supply) as supply, mean(price) as price24_mean, min(price) as min_price, max(price) as max_price FROM price_all WHERE time > now() – 24h GROUP BY coin |
89 milliseconds | 1160 milliseconds |
QuestDB | Influxdb |
SELECT coin, first(price) as ‘7day’, first(volume) as ‘7day_vol_n’, ( first(price) * first(volume) ) as ‘7day_vol’, first(mcap) as ‘7day_mcap’, max(price) as ‘7day_maxp’, min(price) as ‘7day_minp’ FROM ‘price_all’ WHERE time >= dateadd(‘h’, -180, now()) | SELECT first(price), first(volume), ( first(price) * first(supply) ), first(mcap), max(price), min(price) FROM \ “price_all\” WHERE time >= now() – 180h AND time <= now() – 158h GROUP BY coin |
307 milliseconds | 736 milliseconds |
QuestDB | Influxdb |
SELECT coin, first(price) as ‘1day’, first(volume) as ‘1day_vol_n’, (first(price) * first(volume)) as ‘1day_vol’, first(mcap) as ‘1day_mcap’, max(price) as ‘1day_maxp’, min(price) as ‘1day_minp’ FROM ‘price_all’ WHERE time >= dateadd(‘h’, -24, now()) | SELECT time, first(price), first(volume), ( first(price) * first(supply) ) FROM \ “price_all\” WHERE time >= now() – 24h GROUP BY coin |
53 milliseconds | 334 milliseconds |
QuestDB | Influxdb |
SELECT day, coin, first(price) AS s_open, min(price) AS s_min, max(price) AS s_max, last(price) AS s_close FROM ( SELECT date_trunc(‘day’, time) AS day, coin, price FROM price_all WHERE time > dateadd(‘d’, -2, now()) ) GROUP BY coin, day | SELECT time, first(price), min(price), max(price) FROM “price_all” WHERE time > now() – 2d GROUP BY coin,time(1d) |
716 milliseconds | 1862 milliseconds |
QuestDB | Influxdb |
SELECT t1.coin, t1.avg_price AS ath_price, CAST(t1.time AS STRING) as ath_time FROM “1dayprice” t1 JOIN ( SELECT coin, max(avg_price) AS max_avg_price FROM “1dayprice” GROUP BY coin ) t2 ON t1.coin = t2.coin AND t1.avg_price = t2.max_avg_price; | SELECT time,max(avg_price) FROM “1dayprice” GROUP BY coin |
606 milliseconds | 21507 milliseconds |
QuestDB | Influxdb |
SELECT coin, first(avg_price) as ’30day’, first(volume) as ’30day_vol’, first(mcap) as ’30day_mcap’, FROM “1dayprice” WHERE time >= dateadd(‘d’, -31, now()) AND time <= dateadd(‘d’, -29, now()) GROUP BY coin | SELECT time, first(avg_price), first(volume), first(mcap) FROM \ “1dayprice\” WHERE time >= now() – 31d AND time < now() – 29d GROUP BY coin |
12 milliseconds | 167 milliseconds |
QuestDB | Influxdb |
SELECT coin, first(avg_price) AS f_price_p, CAST(first(time) AS STRING) AS f_price FROM ‘1dayprice’ GROUP BY coin; | SELECT time,first(avg_price) FROM \”1dayprice\” GROUP BY coin |
236 milliseconds | 21032 milliseconds |
From this point something interesting is happening
QuestDB | Influxdb |
SELECT time, last(price) AS price, last(mcap) AS mcap, last(volume) * last(price) AS market_volume, last(price_btc) AS price_btc FROM price_all WHERE coin = ’90’ AND time > dateadd(‘d’, -1, now()) SAMPLE BY 10m ALIGN TO CALENDAR | SELECT last(price), last(mcap), ( last(volume) * last(price) ), last(price_btc) FROM “price_all” WHERE coin=’90’ AND time > now() – 1d group by time(10m) fill(none) |
(First run 10556) After 102 milliseconds | 52 milliseconds |
In this situation as long I go in past as more time questdb needs, seams after first request it cache response but as soon cache expire request difference is insane.
QuestDB | Influxdb |
SELECT max(high_price), max(mcap), max(volume), max(price_btc) FROM ‘1dayprice’ WHERE coin=’90’ GROUP BY time(7d) FILL(none) | SELECT max(high_price), max(mcap), max(volume), max(price_btc) FROM “1dayprice” WHERE coin=’90’ group by time(7d) fill(none) |
449 milliseconds | 278 milliseconds |
QuestDB | Influxdb |
SELECT high_price, mcap, volume, price_btc FROM “1dayprice” WHERE coin = ’90’ AND time > dateadd(‘d’, -365, now()); | SELECT high_price, mcap, volume, price_btc FROM “1dayprice” WHERE coin=’90’ AND time > now() – 365d |
172 milliseconds | 168 milliseconds |
Overall, QuestDB significantly outperforms InfluxDB v1 in most queries. However, there are issues with certain queries that use SAMPLE BY. Even on the second execution, performance drops noticeably as the cache expires quickly—making it a deal-breaker for our use case.
Another strange issue we encountered: when executing a large number of requests to retrieve the full dataset, QuestDB would freeze and become unresponsive. Since it’s Java-based, we tried tuning the JVM parameters, but the problem still persisted.
-Xmx34g -Xms18g
t’s performing better now after some tuning, but it still doesn’t seem to handle concurrency as well as InfluxDB. Based on system load observations, QuestDB appears less stable under high parallel query loads—possibly due to memory not being freed efficiently or in time.

The query runs in a loop across all price points from the downsampled table. Under the same workload, InfluxDB handles it smoothly—CPU usage stays under 20% and it maintains responsiveness with just 15GB of memory. In contrast, QuestDB starts to struggle, showing signs of instability and inconsistent performance under load.
Table in QuestDB
CREATE TABLE price_all (
time TIMESTAMP,
coin SYMBOL CAPACITY 60000 CACHE INDEX,
mcap DOUBLE,
price DOUBLE,
supply DOUBLE,
volume DOUBLE
)
TIMESTAMP(time)
PARTITION BY DAY
DEDUP UPSERT KEYS(time, coin);
After running extensive tests across multiple scenarios, I decided to also give TimescaleDB a try. QuestDB definitely shows promise, but it’s clear that it’s not quite there yet for our production needs.