15 min read

Time-Series Databases Compared: InfluxDB, TimescaleDB, and S3

DatabasesTime-SeriesIoTArchitecture

When we started ingesting telemetry from 1,500+ mining devices, each emitting multiple metrics every few seconds, the first question was where to put it all. Time-series data has specific characteristics: high write volume, append-only, queried mostly by time range, and old data becomes less valuable over time. A general-purpose database can handle it up to a point, but eventually you need to make a deliberate choice.

This post compares the three options I evaluated seriously: InfluxDB, TimescaleDB, and S3 with a query layer. I will cover write throughput, query patterns, retention handling, and cost at scale, then give you a decision framework.

What Makes Time-Series Data Different

Before comparing tools, it helps to be precise about the workload:

That last point deserves emphasis. Ten devices with ten metrics is 100 series. Easy. But 1,500 devices with 50 metrics each is 75,000 series, and if you add per-site or per-shift dimensions, you can hit millions. Cardinality is the number one thing to model before choosing.

Put numbers on it before you sign anything. Take a concrete fleet: 1,500 devices, 20 metrics each, one reading every 5 seconds. That is 30,000 series and 6,000 points per second, roughly 518 million points per day. At typical compressed sizes of 10 to 20 bytes per point, you are writing 5 to 10 GB per day of raw telemetry, before indexes, replicas, and downsampled copies. Now add the failure mode nobody models: a firmware bug that makes every device emit at 10x its normal rate at 3 AM. Your Tuesday average is 6,000 points per second. Your worst hour is 60,000. If your database falls over at 20,000, you lose the exact data you needed to diagnose the bug. Size for the worst day, then add headroom.

InfluxDB

InfluxDB is purpose-built for time-series. Its storage engine (TSM) compresses well and handles high write throughput.

Strengths:

Weaknesses:

Best for: Teams that want a dedicated time-series engine, have moderate cardinality (under a few million series), and value built-in retention and downsampling.

TimescaleDB

TimescaleDB is PostgreSQL with time-series superpowers. It partitions regular Postgres tables into chunks by time (hypertables) and adds compression, continuous aggregates, and retention policies.

Strengths:

Weaknesses:

Best for: Teams already on Postgres, workloads where time-series data needs to join with relational data, and moderate-to-high write volumes where SQL familiarity outweighs raw ingest speed.

S3 with a Query Layer

The third option is to skip the database entirely for raw storage: write Parquet files to S3 partitioned by time, and query with Athena, Trino, or a purpose-built engine.

Strengths:

Weaknesses:

The cost gap is worth making concrete. Take the 518 million points per day from the example above: about 15.5 billion points per month. A managed time-series service charging per million points ingested can turn that into thousands of dollars per month before you store a single byte long term. The same data as compressed Parquet is roughly 250 GB per month, which on S3 costs under $6 per month in storage. Querying it with Athena costs per TB scanned, so a monthly compliance report scanning 250 GB costs about $1.25. The database is not 2x more expensive. It is 100x more expensive for data nobody looks at. That is the entire economic argument for tiering: pay database prices only for data that earns it through query frequency.

Best for: Cold storage, compliance archives, and analytical workloads where query latency of seconds is acceptable. Almost always paired with a hot store for recent data.

The Hot/Warm/Cold Pattern

In practice, most serious IoT deployments end up with a tiered approach:

  1. Hot (last 1-24 hours): In-memory or fast SSD store for real-time dashboards and alerting. This can be the time-series database itself, or Redis for the very latest values.
  2. Warm (days to weeks): The time-series database (InfluxDB or TimescaleDB) with full query capability.
  3. Cold (months to years): S3 Parquet for compliance, batch analytics, and ML training data.

The boundaries depend on your query patterns. If operators only look at the last 4 hours in real time and everything else is analytical, your hot tier can be tiny.

Reference Architecture: Tiered Time-Series Platform

Here is the full system, with each tier doing exactly one job. Data flows one direction, hot to cold, and every arrow is a place where backpressure and buffering live.

+----------------+     +----------------+     +----------------+
| Devices        |---->| Edge Gateway   |---->| Stream Proc    |
| 1500 Symbots   |     | MQTT broker    |     | alerting       |
| sensors        |     | local buffer   |     | live aggs      |
+----------------+     +-------+--------+     +-------+--------+
                               |                      |
                               v                      v
                       +----------------+     +-------+--------+
                       | Cold Path      |     | Hot Store      |
                       | batch archive  |     | Redis plus TSDB|
                       | to S3 Parquet  |     | last 24 hours  |
                       +-------+--------+     +-------+--------+
                               |                      |
                               v                      v
                       +----------------+     +-------+--------+
                       | Cold Store     |     | Warm Store     |
                       | S3 Parquet     |     | TimescaleDB    |
                       | years          |---->| days to weeks  |
                       +----------------+     +-------+--------+
                                                      |
                                                      v
                                              +----------------+
                                              | Dashboards     |
                                              | Grafana alerts |
                                              +----------------+

Reading the diagram: devices publish to a local edge gateway running an MQTT broker with persistent buffering, so a WAN outage does not lose data. The gateway forwards to a stream processor that does two things at once: it evaluates alerting rules on live data and writes recent points to the hot store. The hot store (Redis for latest values plus the time-series database itself) serves real-time dashboards looking at the last 24 hours. A batch job continuously downsamples and archives: raw points age out of the hot store into the warm TimescaleDB instance that serves ad hoc queries over days to weeks, and everything lands in S3 as Parquet for years of retention, compliance, and ML training.

Why this shape works: each tier fails independently. If the warm database goes down for maintenance, alerting and real-time dashboards keep working off the hot store. If the WAN link drops, the gateway buffers and the site keeps running locally. The expensive fast storage only holds data people actually query every day, which is a small fraction of the total.

Decision Framework

Here is how I think about the choice:

Choose InfluxDB if:

Choose TimescaleDB if:

Choose S3 + query layer if:

Choose a tiered combination if:

What We Did

For X-Radar, we went with a tiered approach. Kinesis streams feed real-time processing for alerting (hot path, seconds of latency). Aggregated data lands in a time-series store for dashboards covering days to weeks. Raw events archive to S3 in Parquet for long-term analysis and model training.

The key lesson: model your cardinality first, measure your actual query patterns for a week before committing, and do not underestimate how much data you will generate at 3 AM when a firmware bug causes a device to emit at 10x its normal rate. Your storage choice needs headroom for the worst day, not the average day.

Scalability

At 10x (15,000 devices, ~60,000 points/sec): A single well-tuned TimescaleDB node starts to strain here. Write throughput is usually fine with batched inserts, but concurrent analytical queries over growing tables slow down as indexes bloat. InfluxDB on a single node handles 60K points/sec comfortably, but cardinality climbs toward 750,000 series, and query planning on high-cardinality group-bys gets expensive. The first bottleneck is rarely ingest. It is queries competing with writes for the same disk and memory. The standard move at 10x is to split ingest from query: dedicated write nodes, read replicas for dashboards, and aggressive continuous aggregates so dashboards never touch raw tables.

At 100x (150,000 devices, ~600,000 points/sec, ~7.5M series): Single-node anything is off the table. You need a buffer in front of the database (Kafka or Kinesis) so ingest bursts do not hit the database directly, partitioning by device ID hash so each shard owns a slice of the series space, and a distributed engine. Options that survive this: clustered InfluxDB, Timescale multi-node, or ClickHouse with a time-series schema. At this scale S3 stops being the cold tier and becomes the system of record; the hot and warm tiers are caches over it. Compaction and downsampling jobs become first-class citizens with their own monitoring, because a stalled downsample job means the warm tier grows unbounded.

What breaks first: In practice, the order is predictable. First, dashboard queries slow down as cardinality grows and someone writes a group-by over an unindexed tag. Second, disk fills faster than retention policies delete, because deletes lag under write load. Third, a traffic spike (firmware bug, reconnect storm) overwhelms ingest and you start dropping points at the edge. Design mitigations in that order: query guardrails and aggregate-first dashboards, retention automation with disk headroom alerts, and edge buffering sized for the worst spike you have seen plus margin.

Horizontal scaling strategy: Shard by device, not by time. Time-based sharding creates hot partitions (everyone writes to the current partition). Device-hash sharding spreads writes evenly and makes it trivial to add shards. Keep a routing layer that maps device ID to shard, and make shard assignment part of device provisioning so new devices land on the emptiest shard.

Security Considerations

Device authentication. Every device gets its own identity: a unique client certificate or token, issued at provisioning and rotated on a schedule. Never share one credential across the fleet. When a single device is compromised or decommissioned, you revoke one certificate, not the fleet key. Use mutual TLS between devices and the gateway so both sides prove who they are.

Encryption. TLS 1.2 or better for everything in transit: device to gateway, gateway to cloud, database replication, dashboard access. At rest, encrypt database volumes and S3 buckets (SSE with customer-managed keys if compliance requires it). Telemetry often contains location and operational data that is commercially sensitive even when it is not formally classified.

Network segmentation. The MQTT broker and ingestion endpoints should not be reachable from the public internet. Devices connect over VPN, private APN, or site-to-site links. Dashboards sit behind SSO. The database accepts connections only from the application tier.

Attack vectors specific to telemetry. Spoofed sensor data is the one people miss. If an attacker (or a misconfigured device) publishes plausible but wrong readings, your alerting fires on fiction and your aggregates lie. Mitigate with payload signing or at least per-device rate and range validation at ingest: reject a temperature reading of 900 degrees from a sensor whose valid range tops out at 120. Also watch for credential theft from physically accessible devices: assume any secret stored on a device in the field will eventually be extracted, which is why per-device credentials and short lifetimes matter.

Secrets handling. Certificates, API keys, and database passwords live in a secrets manager (Vault, AWS Secrets Manager), never in firmware images or config files checked into git. Automate rotation. Audit who accessed what secret and when.

Production Checklist

Metrics to monitor:

Alert thresholds (tune to your baseline):

Failure modes and runbooks:

Capacity planning: Revisit quarterly. Inputs: device count growth, metrics per device, sampling interval changes, and the worst spike seen since the last review. Keep 3x headroom on ingest throughput and 2x on storage after retention. The cheapest capacity review is the one that happens before the disk fills.

A Note on Retention

Whatever you choose, define retention policies on day one. "Keep everything forever" is not a strategy, it is a deferred cost crisis. Decide:

Write these down, automate them, and review them quarterly as data volume grows. The cheapest byte is the one you never store.

More articles