---
title: "Prometheus Long-Term Storage: Backends Compared"
description: "Prometheus long-term storage options compared: Thanos, Mimir, VictoriaMetrics, and PostgreSQL via remote_write, with a decision framework. "
section: "Data Center & Infrastructure Telemetry"
---

> **TimescaleDB is now Tiger Data.**

You're scraping 500 targets every 15 seconds. After two weeks, Prometheus's local TSDB hits its default retention window and starts dropping data. The on-call engineer needs three months of metrics to complete the post-mortem. The capacity planning team needs six months to model seasonal load. Compliance wants a year.

The answer isn't to keep stretching `--storage.tsdb.retention.time` and hoping the disks hold. Prometheus's local storage is designed for recent data at single-node scale. Long-term retention is a different problem, and the `remote_write` API is how Prometheus hands it off.

But `remote_write` opens a backend decision that the official Prometheus docs don't make for you. This guide evaluates the four main approaches to prometheus remote storage: Thanos, Grafana Mimir, VictoriaMetrics, and PostgreSQL with TimescaleDB. For each, we cover architecture, trade-offs, and the conditions under which it is genuinely the right choice.

One transparency note upfront: Tiger Data builds a PostgreSQL-native time-series database. The TimescaleDB section reflects our perspective, but this guide includes honest assessments of all four options, including cases where TimescaleDB is not the right fit.

## Why Prometheus local storage isn't designed for long-term retention

Prometheus TSDB writes incoming samples to a write-ahead log, compacts them into 2-hour blocks, and progressively merges blocks into larger chunks covering up to 31 days. That design is optimized for fast recent writes and bounded range queries on a single node. It was never intended to be a durable long-term store.

There are two local retention levers:

- `--storage.tsdb.retention.time` (default: 15 days) controls how long Prometheus keeps data before dropping chunks. You can raise this to 30 or 90 days on local disk, and for small deployments that is sometimes sufficient.
- `--storage.tsdb.retention.size` caps total disk usage. Set both flags simultaneously and Prometheus enforces whichever limit is reached first.

But local-only retention has three structural limits that matter at scale. First, there is no high availability: one Prometheus node is one single point of failure. If it goes down during a retention window, that data is gone. Second, there is no horizontal query scaling: a single Prometheus instance handles all queries against its local TSDB, and query latency grows as retention windows extend and cardinality increases. Third, disk cost grows linearly with cardinality multiplied by retention window. Extending local retention to a year on a high-cardinality fleet is a significant infrastructure commitment with no redundancy.

This is the architectural gap `remote_write` fills. Prometheus can stream samples to an external endpoint in parallel with writing to local TSDB. Once a remote backend is in place, you reduce the local buffer to a short window (2-7 days) and let the remote backend own durable long-term storage.

For a deeper look at [<u>how Prometheus stores and indexes data internally</u>](https://www.tigerdata.com/blog/how-prometheus-querying-works-and-why-you-should-care), including block structure, WAL mechanics, and chunk compaction, that blog post covers the internals in detail.

## How Prometheus remote_write works

`remote_write` is straightforward in concept: Prometheus serializes metric samples as protocol buffer batches and POSTs them to one or more configured endpoints. The receiving system is responsible for durable storage and query serving. Prometheus continues writing to local TSDB simultaneously, so a transient remote backend failure doesn't cause data loss during the WAL retention window.

`remote_read` is the companion feature. It allows Prometheus's own query engine to pull historical data from a remote backend when answering PromQL queries. In practice, most teams skip it. The more common pattern is configuring the remote backend as a Grafana datasource directly, which avoids double-proxying and keeps query latency lower.

Three `remote_write` queue parameters matter for high-cardinality environments:

- `queue_config.capacity` sets the number of samples the queue holds before blocking. On high-cardinality scrapers, undersizing this causes WAL growth and backpressure.
- `max_samples_per_send` controls batch size per request to the remote endpoint. Tune this against the backend's ingestion throughput.
- `batch_send_deadline` sets the maximum time to wait before sending a partial batch. Lower values reduce latency at the cost of smaller, less efficient batches.

This section is context for the backend comparison below, not a full configuration tutorial. Each backend has its own tuning recommendations.

## The four primary backends for Prometheus long-term storage

Each backend covered here accepts Prometheus `remote_write` but differs in storage architecture, operational footprint, query language support, and cost model. The right choice depends on your scale, team size, and what you need to do with the metrics once they are stored.

### Thanos

Thanos is a set of open-source components that add long-term storage, a global query view, and downsampling on top of existing Prometheus installations. It is a CNCF project with wide adoption in large Kubernetes environments.

The core of the Thanos architecture is the Sidecar, a process that runs alongside each Prometheus instance and uploads completed TSDB blocks to object storage (S3, GCS, or Azure Blob) as Prometheus finishes writing them. There is no separate write path: Prometheus keeps writing locally, and Thanos reads from object storage for any historical data beyond the local retention window. The Store Gateway serves queries from object storage, the Querier fans out queries across Store Gateways, and the Compactor handles downsampling and block deduplication.

The key strength of Thanos is that it requires minimal changes to how Prometheus operates. You add the Sidecar and point it at an S3 bucket. Existing scrape configurations stay the same. Native downsampling support (5-minute and 1-hour rollups over object storage data) reduces query costs on long time ranges. Multi-cloud object storage support is strong.

The limitations are operational. Querier, Store Gateway, Sidecar, and Compactor are separate processes to deploy, configure, and monitor. Query fanout latency increases with data volume, because historical queries have to scan across multiple Store Gateway instances. Object storage costs scale with both retention length and query frequency (GET request charges add up on large data sets).

Query language support is PromQL only. Multi-tenancy is supported but requires explicit configuration through Thanos Querier tenant labels.

Thanos fits teams that have existing Prometheus fleets, already use S3-compatible object storage, and want to add long-term storage without changing their scrape configuration or Prometheus write path.

### Grafana Mimir

Grafana Mimir is a horizontally scalable, multi-tenant Prometheus-compatible backend. It is the successor to Cortex. Cortex’s latest stable release is 1.20.1 (December 2025), with 1.21.0 still in release-candidate stage as of mid-2026. But active development is minimal - the Cortex maintainers themselves have migrated to Mimir. Teams currently on Cortex are generally advised to evaluate a Mimir migration.

Mimir's architecture separates every function into its own component: Distributor, Ingester, Store Gateway, Compactor, Querier, and Query Frontend. In Mimir 3.0, the write path uses Kafka-based ingestion, which enables ingester replay on failure and significantly improves write durability at scale. Object storage (S3 or GCS) is the storage backend for all persistent data.

Mimir's strengths are scale and multi-tenancy. It is designed to run Prometheus-compatible metrics for large organizations with multiple teams or tenants, and native multi-tenancy is first-class rather than bolted on. Grafana Cloud uses Mimir as its backend, so teams already on Grafana Cloud get Mimir without operating it themselves.

The operational complexity is very high. Running Mimir self-hosted is appropriate for platform engineering teams with dedicated capacity to manage a distributed system. Adding the Kafka dependency in Mimir 3.0 extends that operational surface further. For a single team or a mid-sized Prometheus deployment, Mimir is substantial overhead.

Query language support is PromQL only. Multi-tenancy is native and first-class.

Mimir fits large organizations running Prometheus at scale across multiple teams or tenants, or teams already on Grafana Cloud where Mimir is managed for them.

### VictoriaMetrics

VictoriaMetrics is a ground-up TSDB written in Go. It does not use Prometheus's storage engine: it has its own proprietary columnar storage format engineered for time-series workloads. It accepts Prometheus `remote_write` natively and exposes MetricsQL, a PromQL-compatible superset that extends PromQL with additional functions.

The single-node VictoriaMetrics binary is notable for operational simplicity. There are no external dependencies, no separate components, no object storage requirement. You run one binary. VictoriaMetrics's own benchmarks report up to 7x better storage efficiency than Prometheus TSDB, with actual ratios varying by data characteristics. VictoriaMetrics Cluster is the horizontally scalable variant, which reintroduces component separation (vminsert, vmstorage, vmselect) and corresponding operational complexity.

The limitations worth noting: MetricsQL is a superset of PromQL, not pure PromQL. Most queries work identically, but edge-case query behavior differs, and tooling that depends on strict PromQL compatibility can behave unexpectedly. Single-node VictoriaMetrics has horizontal scaling limits. Cluster mode solves this but reduces the simplicity advantage. There is no native SQL support.

Multi-tenancy is supported in cluster mode only. VictoriaMetrics, Inc. provides commercial LTS releases and support.

VictoriaMetrics fits cost-conscious teams or teams that want the simplest possible standalone metrics store. If SQL queryability is not a requirement and pure PromQL (or MetricsQL compatibility) is sufficient, single-node VictoriaMetrics offers a strong combination of storage efficiency and low operational overhead.

### PostgreSQL with TimescaleDB

TimescaleDB is an open-source PostgreSQL extension for time-series workloads. It can function as a Prometheus `remote_write` target via a remote-storage adapter, storing metrics in hypertables with full SQL queryability. Note that PromQL access depends on an adapter layer rather than a native PromQL engine — see the history note below. 

A transparency note on history: Tiger Data (formerly Timescale) operated Promscale, a unified backend for Prometheus and OpenTelemetry metrics built on TimescaleDB. Promscale was deprecated in April 2023 and is not a current option. Legacy repos like `prometheus-postgresql-adapter` and `pg_prometheus` are also deprecated. 

With Promscale deprecated, Tiger Data no longer ships a first-party Prometheus `remote_write` adapter. The underlying capability — TimescaleDB functioning as a durable Prometheus metrics store via hypertables — remains technically valid, but it now depends on a community or custom remote-storage adapter rather than a maintained, vendor-supported one. Teams whose primary requirement is native PromQL should weigh this gap, since Promscale was what previously provided that layer. 

In this architecture, Prometheus `remote_write` sends samples to an adapter that writes to a TimescaleDB hypertable (a time-partitioned PostgreSQL table). TimescaleDB's Hypercore hybrid row-columnar storage engine automatically compresses older chunks, typically achieving 90-98% storage reduction for time-series workloads. [<u>Automated data retention policies</u>](https://www.tigerdata.com/learn/what-is-data-retention-policy) via `add_retention_policy` drop old raw data on a defined schedule without manual intervention. [<u>Continuous aggregates for automated downsampling</u>](https://www.tigerdata.com/blog/how-to-proactively-manage-long-term-data-storage-with-downsampling) precompute rollups (hourly, daily) incrementally, so long-range queries stay fast without external tooling.

The query advantage over the other three options: full SQL on metrics data. You can write window functions over ingestion rate trends, join metrics with deployment event tables, correlate CPU saturation with application error rates, or build SLA compliance reports across arbitrary time windows - none of which are expressible in PromQL. This is the capability that makes the PostgreSQL path distinct, not merely competitive on PromQL features.

The PromQL query layer requires a third-party or custom adapter - this is not a native PromQL engine, and Tiger Data does not currently provide a supported one. Teams that live entirely in Grafana with PromQL datasources will need to build or source that layer themselves. PostgreSQL operational familiarity is required; this is not a good fit for teams with no existing PostgreSQL investment. It is also not the right choice for teams whose primary requirement is high-volume pure-metrics storage with no analytics need.

[<u>Tiger Cloud</u>](https://www.tigerdata.com/cloud) (Tiger Data's managed PostgreSQL and TimescaleDB service) removes the self-hosted operational burden if you want the SQL analytics capability without running PostgreSQL yourself.

Multi-tenancy is handled via PostgreSQL schema-level isolation - functional but not native metrics-layer multi-tenancy.

PostgreSQL with TimescaleDB fits teams that already run PostgreSQL in production and want to extend it to metrics storage, teams that need SQL analytics on metrics data (capacity planning, join queries with application tables, SLA reporting), or teams that want automated downsampling and retention managed by the database rather than external tooling.

## Comparison table: Prometheus long-term storage backends

| **Backend** | **Storage layer** | **Query language** | **PromQL compatible** | **SQL support** | **Multi-tenancy** | **Operational complexity** | **Managed cloud option** | **Best fit** |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| Thanos | Object storage (S3/GCS/Azure) | PromQL | Yes (native) | No | Yes (config required) | High | No (self-hosted) | Existing Prometheus fleets with S3 infrastructure |
| Grafana Mimir | Object storage + Kafka | PromQL | Yes (native) | No | Yes (native) | Very high | Yes (Grafana Cloud) | Multi-tenant SaaS-scale deployments |
| VictoriaMetrics | Proprietary columnar | MetricsQL | Yes (superset) | No | Cluster mode only | Low (single-node) / High (cluster) | Yes (Managed VictoriaMetrics) | Cost-conscious teams prioritizing simplicity |
| PostgreSQL + TimescaleDB | PostgreSQL (hypertables) | SQL + PromQL via adapter | Yes (via third-party/custom adapter) | Yes (full SQL) | Schema-level isolation | Medium | Yes (Tiger Cloud) | SQL analytics on metrics, PostgreSQL-native teams |

Note: AWS Timestream LiveAnalytics is not included in this comparison. It was closed to new customers in June 2025.

## How to configure Prometheus remote_write

The generic r`emote_write` configuration in `prometheus.yml` follows this pattern, regardless of which backend you use:

`remote_write:
  - url: "https://<your-backend-endpoint>/api/v1/write"
    queue_config:
      capacity: 10000
      max_samples_per_send: 2000
      batch_send_deadline: 5s
      max_shards: 10`

Replace `<your-backend-endpoint>` with the receiver endpoint your backend provides. Each backend publishes its own endpoint format and any additional authentication configuration.

For a PostgreSQL remote storage adapter writing to TimescaleDB, the configuration follows the same pattern but points to the adapter's ingestion endpoint:

`remote_write:
  - url: "http://<adapter-host>:<port>/write"
    queue_config:
      capacity: 10000
      max_samples_per_send: 2000
      max_shards: 8`

A remote-storage adapter translates Prometheus's protocol buffer format into SQL writes against a TimescaleDB hypertable. Because Tiger Data's first-party adapter (Promscale) is deprecated, this requires a community or self-maintained adapter; refer to that project's documentation for configuration. The[ <u>TimescaleDB documentation</u>](https://www.tigerdata.com/docs) covers hypertable setup, retention, and continuous aggregates on the storage side. The Prometheus community also maintains a list of remote storage integrations on the Prometheus integrations page - a useful reference if you are evaluating adapter options beyond the ones covered here.

Three practical points for any `remote_write` deployment:

First, reduce local retention once remote write is confirmed stable. Set `--storage.tsdb.retention.time=7d` to keep a short local buffer while the remote backend handles durable history. This significantly reduces local disk pressure.

Second, tune `max_shards` proportional to your remote backend's ingestion throughput. Too few shards create a bottleneck; too many can overwhelm the backend with concurrent connections.

Third, monitor `prometheus_remote_storage_failed_samples_total` and `prometheus_remote_storage_queue_length`. Rising queue length signals that the remote backend cannot keep up with ingest rate. Failed samples indicate persistent write failures and potential data loss.

## Decision framework: how to choose

This is a genuine decision, not a ranking. Each backend is the right choice in specific conditions.

### Choose Thanos if:

- You have an existing Prometheus fleet and need long-term storage without changing how Prometheus scrapes or writes locally.
- Your organization already uses S3-compatible object storage and wants to reuse that infrastructure.
- You need a global query view across multiple Prometheus instances in different regions or clusters.

### Choose Grafana Mimir if:

- You are running Prometheus at multi-tenant scale: multiple teams, thousands of active series per tenant, SaaS-scale deployments.
- You are already on Grafana Cloud or heavily invested in the Grafana observability stack.
- You have a dedicated platform engineering team with capacity to manage a distributed system.

### Choose VictoriaMetrics if:

- Operational simplicity is the top priority and a single-binary deployment is appealing.
- You need better storage efficiency than Prometheus TSDB and are not running PostgreSQL in production.
- PromQL or MetricsQL is sufficient - no SQL requirement on your metrics data.

### Choose PostgreSQL with TimescaleDB if:

- Your team already runs PostgreSQL in production and wants to extend it to metrics storage without adding a new system.
- You need SQL analytics on metrics: capacity planning across arbitrary time windows, joins with deployment event tables or application data, SLA compliance reports.
- You want automated downsampling and data retention managed by the database rather than external tooling.
- You want a managed cloud edition (Tiger Cloud) that removes the operational burden of self-hosting PostgreSQL for metrics.

One category to avoid: do not provision AWS Timestream LiveAnalytics. It was closed to new customers in June 2025. Timestream for InfluxDB is the surviving AWS managed metrics product, but it uses the InfluxDB protocol, not Prometheus's `remote_write`.

If you are evaluating whether to move away from Prometheus entirely rather than extending it, the [<u>Prometheus alternatives</u>](https://www.tigerdata.com/learn/prometheus-alternatives) guide covers nine options including Grafana Mimir, VictoriaMetrics, Datadog, and others in a full replacement context.

For teams managing data center infrastructure at scale, the related guide on [<u>data center telemetry database</u>](https://www.tigerdata.com/learn/data-center-telemetry-database) covers broader telemetry storage architecture decisions that complement the Prometheus-specific storage question.