2.17x write throughput, up to 67x faster queries, 1/18 storage footprint—GreptimeDB shows significant performance advantages in the standard TSBS benchmark.
TimescaleDB is one of the most popular time-series databases, built on PostgreSQL with a mature ecosystem. GreptimeDB is a next-generation cloud-native observability database written in Rust, designed for high throughput and low latency. These two represent distinct approaches: one extends time-series capabilities on top of a mature relational database, while the other is purpose-built from the ground up.
This article shares our benchmark results using TSBS. You'll learn the specific differences in write, query, and storage performance, the technical reasons behind them, and complete steps to reproduce the tests yourself.
Key Findings
- Write throughput: GreptimeDB achieves 2.17x the throughput of TimescaleDB (285,301 vs 131,531 rows/sec)
- Query performance: GreptimeDB outperforms TimescaleDB in 13 of 15 query types, with speedups up to 67x
- Storage efficiency: GreptimeDB uses only 1/18 of the storage (1.1 GB vs 20 GB)
- Where TimescaleDB wins:
lastpointandgroupby-orderby-limitqueries
Test Environment
| Component | Configuration |
|---|---|
| Instance | AWS c5d.2xlarge (8 vCPU, 16 GB RAM) |
| OS | Ubuntu 24.04 LTS |
| Storage | 300 GB gp3 SSD |
| GreptimeDB | v1.0.0-beta.2 |
| TimescaleDB | 2-postgresql-17 |
We used TSBS (Time Series Benchmark Suite), an industry-standard benchmark developed by the TimescaleDB team. We ran tests with GreptimeDB's fork, which adds GreptimeDB support.
TSBS ensures fair comparison by design: data and queries are pre-generated using the same pseudo-random seed, so each database loads identical data and runs identical queries.
Dataset
We used the cpu-only scenario, simulating CPU metrics from 4,000 servers over 3 days:
- Scale: 4,000 hosts
- Time range: 2023-06-11 to 2023-06-14 (3 days)
- Interval: 10 seconds
- Total: 103.6 million rows, over 1 billion metrics
Each record contains:
- 10 Tags: hostname, region, datacenter, rack, os, arch, team, service, service_version, service_environment
- 10 Fields: usage_user, usage_system, usage_idle, usage_nice, usage_iowait, usage_irq, usage_softirq, usage_steal, usage_guest, usage_guest_nice
This models typical infrastructure monitoring: multi-dimensional tags identify hosts, while metric fields record CPU usage statistics.
Write Performance
Test parameters: batch size 10,000, 8 concurrent workers.
| Metric | TimescaleDB | GreptimeDB | Comparison |
|---|---|---|---|
| Write rate | 131,531 rows/sec | 285,301 rows/sec | 2.17x |
| Disk usage | 20 GB | 1.1 GB | 18x compression |
Why GreptimeDB Writes Faster
Columnar storage (Parquet format): GreptimeDB uses Apache Parquet as its SST file format, storing data from the same column contiguously. During batch writes, same-type data compresses and flushes together, reducing random I/O.
Better compression: Grouping similar data improves compression dramatically. GreptimeDB achieves 30–40x compression ratios for time-series data. In this test, storage is just 1/18 of TimescaleDB's—significant cost savings for cloud deployments.
Mito storage engine: GreptimeDB's Mito engine uses an LSM-Tree architecture optimized for append-only time-series patterns, enabling high-throughput ingestion.
TimescaleDB uses PostgreSQL's row-based storage. Hypertable partitioning and compression help, but there's still a gap in raw throughput.
Query Performance
After ingestion, we restarted both databases and ran each query multiple times to get average latency.
Query Types Explained
| Query Type | What It Does | Use Case |
|---|---|---|
| cpu-max-all- | Max of all CPU metrics across all hosts over N hours | Peak monitoring |
| single-groupby-X-Y-Z | Aggregation over X metrics, Y hosts, Z hours | Drill-down analysis |
| double-groupby- | Group by time and host, hourly averages per host | Trend comparison |
| high-cpu- | Find hosts above CPU threshold | Anomaly detection |
| lastpoint | Latest data point per host | Real-time dashboards |
| groupby-orderby-limit | Group, aggregate, sort, return Top N | Leaderboards |
GreptimeDB Wins (13/15 Queries)
| Query Type | TimescaleDB (ms) | GreptimeDB (ms) | Speedup |
|---|---|---|---|
| cpu-max-all-8 | 6,012 | 89 | 67x |
| single-groupby-1-1-12 | 571 | 9 | 62x |
| high-cpu-1 | 623 | 16 | 39x |
| single-groupby-1-8-1 | 439 | 20 | 22x |
| cpu-max-all-1 | 411 | 23 | 18x |
| single-groupby-5-1-12 | 166 | 14 | 12x |
| double-groupby-1 | 8,559 | 1,028 | 8.3x |
| single-groupby-1-1-1 | 54 | 7 | 7.7x |
| double-groupby-5 | 7,654 | 1,566 | 4.9x |
| double-groupby-all | 10,717 | 2,270 | 4.7x |
| single-groupby-5-8-1 | 95 | 29 | 3.2x |
| high-cpu-all | 8,731 | 5,661 | 1.5x |
| single-groupby-5-1-1 | 15 | 10 | 1.5x |
TimescaleDB Wins (2/15 Queries)
| Query Type | TimescaleDB (ms) | GreptimeDB (ms) | TimescaleDB Advantage |
|---|---|---|---|
| groupby-orderby-limit | 122 | 728 | 6x |
| lastpoint | 131 | 1,131 | 8.7x |
Why These Differences?
Where GreptimeDB Excels
Large time-range aggregations: cpu-max-all-8 (8-hour max across all hosts) shows the biggest gap at 67x. These queries scan lots of data and compute aggregates. GreptimeDB wins because:
Columnar storage reduces I/O: Parquet format reads only the columns needed, not entire rows. Reading 10 metric columns takes far less I/O than full rows with all tags.
Vectorized query engine: GreptimeDB builds its query engine on Apache DataFusion, which uses vectorized execution—processing data in batches rather than row by row—fully utilizing CPU cache locality.
Time partitioning and indexing: GreptimeDB organizes data by time windows and uses MinMax, BloomFilter, and other indexes to quickly locate data blocks within time ranges, avoiding full table scans.
Long time-range, single host: single-groupby-1-1-12 (1 metric, 1 host, 12 hours) hits 62x speedup. Even for one host, 12 hours means 4,320 data points at 10-second intervals. Columnar storage shines in this "narrow but long" pattern.
Short time-range, multi-host: single-groupby-1-8-1 (1 metric, 8 hosts, 1 hour) achieves 22x speedup. DataFusion's multi-threaded streaming execution engine processes multiple time series in parallel, fully utilizing multi-core CPUs.
Where TimescaleDB Excels
lastpoint queries: Get the latest value for each host. TimescaleDB is 8.7x faster.
This is classic point-lookup territory. PostgreSQL's B-tree indexes excel at "find latest value for key" queries.
GreptimeDB will further optimize for this scenario in future releases.
groupby-orderby-limit: Group, sort, return Top N. TimescaleDB is 6x faster.
PostgreSQL creates a separate index on the timestamp column during table creation, which accelerates ORDER BY + LIMIT queries.
Pattern Summary
| Query Pattern | Better Choice | Why |
|---|---|---|
| Large time-range aggregation | GreptimeDB | Columnar storage + vectorized execution |
| Multi-host parallel scans | GreptimeDB | Reduced I/O |
| Point lookups / latest value | TimescaleDB | B-tree optimization |
| Top N sorting | TimescaleDB | B-tree optimization |
No database wins everywhere. Choose based on your workload.
When to Use Which
| Scenario | Recommendation | Reason |
|---|---|---|
| High-throughput ingestion (>100K rows/sec) | GreptimeDB | 2.17x write performance |
| Large time-range aggregations | GreptimeDB | Up to 67x faster |
| Storage cost sensitive | GreptimeDB | 18x compression |
| Deep PostgreSQL integration | TimescaleDB | Full SQL compatibility |
| Frequent lastpoint queries | TimescaleDB | 8.7x point query advantage |
| Top K leaderboards | TimescaleDB | Better sorting |
Reproduce It Yourself
Complete steps to run this benchmark on Ubuntu 24.04.
1. Install Go and Build TSBS
# Install Go
wget https://go.dev/dl/go1.25.5.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.25.5.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin
# Verify
go version # go version go1.25.5 linux/amd64
# Clone and build TSBS
git clone https://github.com/GreptimeTeam/tsbs.git
cd tsbs
make
# Set up working directory
mkdir -p ~/tsbs-bench/bench-data ~/tsbs-bench/logs
cp -r bin ~/tsbs-bench/
cd ~/tsbs-bench2. Generate Test Data
# TimescaleDB format
./bin/tsbs_generate_data --use-case="cpu-only" --seed=123 --scale=4000 \
--timestamp-start="2023-06-11T00:00:00Z" \
--timestamp-end="2023-06-14T00:00:00Z" \
--log-interval="10s" --format="timescaledb" \
> ./bench-data/timescaledb-data.csv
# GreptimeDB format (InfluxDB Line Protocol)
./bin/tsbs_generate_data --use-case="cpu-only" --seed=123 --scale=4000 \
--timestamp-start="2023-06-11T00:00:00Z" \
--timestamp-end="2023-06-14T00:00:00Z" \
--log-interval="10s" --format="influx" \
> ./bench-data/influx-data.lp3. Generate Query Files
QUERY_TYPES=(
"cpu-max-all-1:100"
"cpu-max-all-8:100"
"double-groupby-1:50"
"double-groupby-5:50"
"double-groupby-all:50"
"groupby-orderby-limit:50"
"high-cpu-1:100"
"high-cpu-all:50"
"lastpoint:10"
"single-groupby-1-1-1:100"
"single-groupby-1-1-12:100"
"single-groupby-1-8-1:100"
"single-groupby-5-1-1:100"
"single-groupby-5-1-12:100"
"single-groupby-5-8-1:100"
)
# TimescaleDB
for item in "${QUERY_TYPES[@]}"; do
IFS=':' read -r qtype count <<< "$item"
./bin/tsbs_generate_queries \
--use-case="devops" --seed=123 --scale=4000 \
--timestamp-start="2023-06-11T00:00:00Z" \
--timestamp-end="2023-06-14T00:00:01Z" \
--queries=$count \
--query-type $qtype \
--format="timescaledb" \
> ./bench-data/timescaledb-queries-${qtype}.dat
done
# GreptimeDB
for item in "${QUERY_TYPES[@]}"; do
IFS=':' read -r qtype count <<< "$item"
./bin/tsbs_generate_queries \
--use-case="devops" --seed=123 --scale=4000 \
--timestamp-start="2023-06-11T00:00:00Z" \
--timestamp-end="2023-06-14T00:00:01Z" \
--queries=$count \
--query-type $qtype \
--format="greptime" \
> ./bench-data/greptime-queries-${qtype}.dat
done4. Install TimescaleDB
# Dependencies
sudo apt install gnupg postgresql-common apt-transport-https lsb-release wget
# PostgreSQL repo
sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh
# TimescaleDB repo
echo "deb https://packagecloud.io/timescale/timescaledb/ubuntu/ $(lsb_release -c -s) main" \
| sudo tee /etc/apt/sources.list.d/timescaledb.list
wget --quiet -O - https://packagecloud.io/timescale/timescaledb/gpgkey \
| sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/timescaledb.gpg
# Install
sudo apt update
sudo apt install timescaledb-2-postgresql-17 postgresql-client-17
# Tune (accept defaults)
sudo timescaledb-tune
# Restart and set password
sudo systemctl restart postgresql
sudo -u postgres psql -c "\password postgres"
# Password: greptime5. Install GreptimeDB
# Download from https://greptime.com/download
mkdir -p ~/greptimedb-data
# Config
cat > ~/greptimedb-data/config.toml << 'EOF'
[http]
addr = "0.0.0.0:4000"
timeout = "30s"
[storage]
data_home = "/home/ubuntu/greptimedb-data/data/"
type = "File"
EOF
# Start
./greptime standalone start -c ~/greptimedb-data/config.toml6. Run Write Tests
# TimescaleDB
./bin/tsbs_load_timescaledb \
--file=./bench-data/timescaledb-data.csv \
--batch-size=10000 \
--pass="greptime" \
--workers=8 2>&1 | tee ./logs/timescaledb-load.log
# GreptimeDB
./bin/tsbs_load_greptime \
--urls=http://localhost:4000 \
--file=./bench-data/influx-data.lp \
--batch-size=10000 \
--gzip=false \
--workers=8 2>&1 | tee ./logs/greptime-load.log7. Run Query Tests
Restart databases to clear caches before testing:
# Restart TimescaleDB
sudo systemctl restart postgresql
# TimescaleDB queries
for qtype in cpu-max-all-1 cpu-max-all-8 double-groupby-1 double-groupby-5 \
double-groupby-all groupby-orderby-limit high-cpu-1 high-cpu-all \
lastpoint single-groupby-1-1-1 single-groupby-1-1-12 single-groupby-1-8-1 \
single-groupby-5-1-1 single-groupby-5-1-12 single-groupby-5-8-1; do
./bin/tsbs_run_queries_timescaledb \
--file=./bench-data/timescaledb-queries-${qtype}.dat \
--pass="greptime" \
--db-name=benchmark 2>&1 | tee ./logs/timescaledb-queries-${qtype}.log
done
# Restart GreptimeDB (stop and start)
# GreptimeDB queries
for qtype in cpu-max-all-1 cpu-max-all-8 double-groupby-1 double-groupby-5 \
double-groupby-all groupby-orderby-limit high-cpu-1 high-cpu-all \
lastpoint single-groupby-1-1-1 single-groupby-1-1-12 single-groupby-1-8-1 \
single-groupby-5-1-1 single-groupby-5-1-12 single-groupby-5-8-1; do
./bin/tsbs_run_queries_influx \
--file=./bench-data/greptime-queries-${qtype}.dat \
--db-name=benchmark \
--urls="http://localhost:4000" 2>&1 | tee ./logs/greptime-queries-${qtype}.log
done8. Check Results
Extract average latency (mean value in ms):
grep "mean:" ./logs/*.logConclusion
GreptimeDB strengths:
- 2.17x write throughput for high-frequency ingestion
- 2–67x faster aggregation queries for time-range analysis
- 18x storage efficiency, cutting cloud costs
TimescaleDB strengths:
- Faster point queries (lastpoint)
- Better Top K sorting for leaderboards
- Full PostgreSQL ecosystem compatibility
Choose based on your workload. High-throughput writes and aggregation analysis favor GreptimeDB. Frequent point queries or deep PostgreSQL integration favor TimescaleDB.
Benchmark results vary with hardware, data scale, and query patterns. We've provided full reproduction steps—validate these conclusions in your own environment.



