all posts

Top 8 Prometheus Hosting Platforms in 2026

Ajay Kumar··10 min read

Prometheus is a single-node time-series database with a local disk and a scrape loop. That is not a criticism, it is the design, and it is why the thing is so reliable: no clustering, no consensus, no external dependency that can take your monitoring down at the same moment as the thing you are monitoring. But it means retention is bounded by whatever disk you gave it, a host reboot is a monitoring gap, and there is no built-in way to query across two Prometheis at once. Every product on this list exists because of those three facts.

I'm Ajay, I build PandaStack. We run Prometheus on our own hosts and we host other people's Prometheus instances as ordinary apps, so I have an interest in you self-hosting — which is exactly why I want to be blunt about where self-hosting on one VM stops being the right answer. This is a comparison of shapes and trade-offs, not a price sheet. Vendor pricing in this category changes constantly and is billed on units (active series, samples ingested, query volume) that are hard to predict before you measure them, so verify everything against current docs.

The single-node ceiling, stated plainly

Vanilla Prometheus keeps a local TSDB, writes two-hour blocks, compacts them, and drops whatever falls outside its retention window. It is not highly available on its own. The community answer to HA has always been to run two identical Prometheis scraping the same targets, which gets you redundancy of collection but not a single coherent view — the two copies disagree on sample timestamps, and deduplicating them is the job of a layer above.

There are three ways past the ceiling, and they are worth naming because vendors blur them. Federation, where one Prometheus scrapes a subset of another's series, works and is old and does not scale much past a couple of tiers. Sidecar-and-object-store, which is Thanos, leaves the local Prometheus alone and uploads its blocks to S3 for long-term query. And remote_write, where Prometheus streams every sample it collects to something else in real time, which is what almost every managed offering plugs into.

remote_write is the seam. Once you know that, the shopping decision gets much simpler: you keep running a local Prometheus for scraping and alerting, and you choose which remote store receives the stream. Switching stores later is a config block, not a migration. That is unusually good portability for an infrastructure decision, and you should use it as leverage.

# prometheus.yml -- scrape locally, ship everything to a long-term store.
global:
  scrape_interval: 30s
  evaluation_interval: 30s
  external_labels:
    cluster: prod-eu
    # Distinguishes the two HA replicas so the remote store can dedupe them.
    replica: a

rule_files:
  - /etc/prometheus/rules/*.yml

alerting:
  alertmanagers:
    - static_configs:
        - targets: ["alertmanager.internal:9093"]

scrape_configs:
  - job_name: node
    static_configs:
      - targets: ["10.0.1.11:9100", "10.0.1.12:9100"]

  - job_name: pandastack-agent
    static_configs:
      - targets: ["10.0.1.11:9100"]
    metric_relabel_configs:
      # Drop a metric you know is a cardinality hazard before it is stored.
      - source_labels: [__name__]
        regex: "go_gc_heap_.*"
        action: drop

remote_write:
  - url: https://metrics.example.com/api/v1/write
    # Almost every managed backend speaks this. Auth differs; the shape doesn't.
    basic_auth:
      username: "12345"
      password_file: /etc/prometheus/remote-write-token
    queue_config:
      # Raise this before you raise capacity: a backed-up queue shows up as
      # prometheus_remote_storage_samples_pending, and dropped samples are silent.
      max_samples_per_send: 2000
      capacity: 10000
      max_shards: 200
    write_relabel_configs:
      # Ship less than you scrape. This is the cheapest lever you have.
      - source_labels: [__name__]
        regex: "(apiserver_request_duration_seconds_bucket|etcd_request_.*)"
        action: drop

Cardinality is the bill, and the stability risk

A Prometheus series is a metric name plus its exact label set. Every distinct combination is a separate series with its own index entry and its own chunk in memory. Add a label whose values are unbounded — a user id, a request id, a full URL path, a container id that changes every deploy — and you have not added one series, you have multiplied your existing ones. This is the single mechanism behind most Prometheus outages and most surprising observability invoices.

It is worth being concrete, because I did this to myself recently. Our per-host agent exports a latency histogram labelled by HTTP route. The normalisation function collapsed the sandbox id but passed the rest of the path through verbatim — and one of those routes is a reverse proxy into a customer's app, so the label value was whatever URL that customer's app happened to serve. On one production host, six days of uptime: 2,743 distinct route labels, 50,496 metric lines, 7.2 MiB per scrape, growing about 415 permanent series a day and never evicted. A single media tenant emitting unique HLS segment ids accounted for 43,680 of those lines, against 90 each for the exec and filesystem routes.

The memory cost was not yet the problem — the agent was sitting at 41 MiB RSS. The problem was that the histogram had become useless. Proxy latency was shattered across thousands of one-hit label values, so the one question the metric existed to answer, how slow is the proxy path, could not be asked. We collapsed everything under the proxy route to a single label and left every other route alone. The fix was eight lines. Finding it took a lot longer than that.

The general rule: never let a label value come from something a user controls. URL paths, email addresses, tenant-supplied identifiers, error message text. If you need that granularity, it belongs in logs or traces, which are built for high-cardinality lookup. Metrics are built for aggregation over bounded dimensions.

Before you shop for a host, measure. These two queries take ten seconds and will change what you buy.

# Which metric names own the most series? Your top offenders, ranked.
topk(10, count by (__name__)({__name__=~".+"}))

# Total active series -- this is the number vendors price on.
count({__name__=~".+"})

# For one suspicious metric, which label is doing the damage?
# (Run per candidate label; the one that returns thousands is your bug.)
count(count by (route) (pandastack_agent_http_request_duration_seconds_bucket))

# TSDB's own view, cheaper than the above on a large instance:
# visit /status/tsdb in the Prometheus UI, or scrape these.
prometheus_tsdb_head_series
rate(prometheus_tsdb_head_series_created_total[5m])

# Churn: series created per second that will never be seen again.
# High churn with flat total series means labels tied to short-lived things.
sum(rate(prometheus_tsdb_head_series_created_total[1h]))

Write down the total active series number and the daily sample rate. Every option below is priced or sized off those two figures, and a team that has not measured them is negotiating blind.

The eight options

1. Self-hosted Prometheus on a VM

One binary, one config file, one data directory. For a fleet in the low hundreds of targets with a retention window measured in weeks rather than years, this is genuinely fine and people talk themselves out of it too quickly. It has no external dependencies, which means it keeps working during exactly the incidents where your fancier stack might not.

Where it stops being fine: when you need more than one node's worth of retention, when a reboot creating a monitoring gap is unacceptable, or when you need to query across regions. Run two replicas for collection redundancy, put the data directory on a volume you actually back up, and understand that you are one disk away from losing history.

2. Grafana Cloud (Mimir)

Mimir is the horizontally scalable, object-store-backed Prometheus-compatible backend that Grafana Labs runs as Grafana Cloud's metrics tier. You keep local Prometheus (or Grafana Alloy) for scraping, remote_write to their endpoint, and query through Grafana with PromQL that behaves the way you expect. It is the most complete single-vendor story if you also want Loki for logs and Tempo for traces in the same place.

Pick it when you want one vendor for the whole observability stack and your telemetry is allowed to leave your infrastructure. The variable to model is active series, because that is what the bill is indexed to — see the cardinality section above, and do the measuring before the trial ends rather than after. Mimir is also Apache-licensed and self-hostable if you would rather run it yourself, which is a real option for teams with object storage and Kubernetes already in place.

3. Amazon Managed Service for Prometheus

AWS runs a Cortex-derived, PromQL-compatible workspace for you. The pitch is integration rather than novelty: SigV4 auth so you use IAM roles instead of long-lived tokens, a managed collector for EKS, and a query surface that Amazon Managed Grafana wires up natively. Ingest is remote_write like everything else, and alerting can either stay in your own Prometheus or run in the service's managed rule groups with Alertmanager.

It is the obvious pick when your workloads, identity and dashboards are already AWS-shaped, and an odd one when they are not — the SigV4 signing step is a small but real friction from outside AWS. Check the current quotas on active series per workspace and ingestion rate against AWS docs, because those are soft limits you can hit sooner than you expect and raising them is a support ticket, not a slider.

4. Google Cloud Managed Service for Prometheus

Google's version is architecturally the most distinct on this list: it stores your Prometheus data in Monarch, the same planet-scale system behind Cloud Monitoring, and exposes it through a PromQL-compatible query interface. You can feed it either with their drop-in managed collector for GKE, with self-deployed collection, or with plain remote_write from an existing Prometheus.

The advantage is that your Prometheus metrics and your GCP infrastructure metrics end up queryable in one place, which matters more than it sounds if you are already living in Cloud Monitoring. The thing to verify is billing shape — Google prices this on samples ingested rather than active series, which is a genuinely different model and rewards a longer scrape interval in a way series-based pricing does not. Work out which shape your workload is cheaper under before assuming any vendor is the expensive one.

5. VictoriaMetrics (self-hosted or cloud)

The efficiency play. VictoriaMetrics is a Prometheus-compatible store that accepts remote_write, speaks PromQL through its MetricsQL superset, and is known for using notably less RAM and disk than the alternatives for the same data. The single-node binary handles a genuinely large workload before you need the clustered version, which makes it the least ceremonious upgrade path from a single Prometheus: point remote_write at it, keep everything else.

It also ships vmagent, which can replace Prometheus for scraping and do relabelling and buffering before shipping. There is a managed VictoriaMetrics Cloud if you want the same engine without operating it. The trade-offs to know: MetricsQL is a superset, so queries written against it are not always portable back to strict PromQL, and the clustered version is a real distributed system with the operational weight that implies. Read the licensing terms for the components you plan to use.

6. Thanos

Thanos takes the opposite approach to remote_write: leave your Prometheus instances exactly as they are, attach a sidecar that uploads completed TSDB blocks to object storage, and put a query layer in front that fans out across sidecars and the store gateway, deduplicating HA replicas as it goes. A compactor downsamples old blocks so year-long queries do not read raw samples.

It is the right answer when you already have many Prometheus servers you do not want to change and you need a global query view plus cheap long-term retention on S3. It is the wrong answer if you were hoping for one thing to deploy — Thanos is several components with distinct scaling behaviours, and the store gateway's index cache in particular is something you will end up tuning. Fully open source, no vendor, and a large operational surface. That is the trade.

7. Purpose-built observability vendors (Chronosphere, Levitate, and similar)

A category rather than one product: vendors whose entire pitch is that cardinality is the problem and their control plane is the answer. Chronosphere grew out of M3 and is built around shaping, aggregating and dropping metrics at ingest so you spend on the series that answer questions and not on the ones nobody queries. Last9's Levitate sits in similar territory. The common thread is a cardinality governance layer, streaming aggregation rules, and per-team quotas that make the bill legible to the people generating the data.

These are for organisations where metrics spend has become a line item someone senior asks about, and where the failure mode is a hundred teams each adding a well-meaning label. If your active series count is in the low millions and one person owns the config, this tier is more machinery than you need. If it is in the hundreds of millions and nobody owns it, this is the category that exists for you. Talk to them with your measured series count in hand.

8. PandaStack

Being direct, since this is my company: we do not sell a managed metrics backend. There is no PandaStack remote_write endpoint, no hosted Mimir, nothing that competes with the six options above on storing your time series. If that is what you came for, one of them is your answer.

What we do is run a real Linux machine from a git repo. A PandaStack app is a full Ubuntu userspace inside a Firecracker microVM with hardware isolation, so running prometheus or victoria-metrics as a normal process with a durable volume for the data directory is unremarkable — it is just a Linux service with a config file, which is exactly what Prometheus wants to be. Instances restore from a snapshot with a p50 of 179ms. Because it is a real VM and not a container runtime with one entrypoint, you can run Prometheus and Alertmanager and an exporter in the same sandbox, apt-install what you need, and open the ports you want.

The natural pairing is with the Grafana side of this: managed Postgres 16 for Grafana's own state, one dedicated microVM per database with a durable volume, TLS connection string, point-in-time restore. So the honest shape of PandaStack in a metrics stack is the dashboard host and the small self-hosted Prometheus, with a purpose-built store behind it when you outgrow one node.

And you will outgrow it. A single Prometheus on a single VM is a reasonable setup for a small fleet and a bad idea as a long-term store for a large one, regardless of whose VM it is. We are not going to pretend a microVM changes the physics of a single-node TSDB. Pricing is one rate card, $0.054 per vCPU-hour and $0.0162 per GiB-hour with no per-request charge, which suits a Prometheus that runs continuously about as well as any hourly model does — the point is that the compute is cheap and the decision that matters is still where the long-term data lives.

Side by side

  • Self-hosted Prometheus on a VM — Model: one binary, local TSDB, retention bounded by disk. Ops: low but you own HA, backups and the disk. Best for: small fleets, weeks of retention, teams who value zero external dependencies.
  • Grafana Cloud / Mimir — Model: managed horizontally scalable backend fed by remote_write, priced mainly on active series. Ops: none managed, meaningful if you self-host Mimir. Best for: one vendor for metrics, logs and traces together.
  • Amazon Managed Service for Prometheus — Model: managed PromQL workspace with SigV4 auth and native EKS and Amazon Managed Grafana integration. Ops: low inside AWS, awkward outside. Best for: AWS-native shops. Check workspace quotas.
  • Google Cloud Managed Service for Prometheus — Model: Prometheus data in Monarch, priced on samples ingested rather than active series. Ops: low, lowest on GKE. Best for: GCP shops who want Prometheus and Cloud Monitoring in one query surface.
  • VictoriaMetrics — Model: efficient Prometheus-compatible store, single-node or clustered, self-hosted or their cloud. Ops: the gentlest self-hosted upgrade from one Prometheus. Best for: teams who want long retention without a fleet of components.
  • Thanos — Model: sidecars upload TSDB blocks to object storage, a query layer fans out and dedupes. Ops: several components, real tuning. Best for: many existing Prometheus servers needing a global view and cheap S3 retention.
  • Chronosphere, Levitate and similar — Model: managed backend built around cardinality control, streaming aggregation and per-team quotas. Ops: none, plus a governance workflow. Best for: large organisations where metrics spend is a recurring finance conversation.
  • PandaStack — Model: not a metrics backend; a microVM that runs your Prometheus or VictoriaMetrics as an app with a durable volume, plus managed Postgres for a paired Grafana. Ops: yours, but it is one Linux service. Best for: small self-hosted setups and the dashboard tier, not petabyte retention.
Because everything here plugs into remote_write, this decision is far more reversible than most infrastructure choices. Start with the cheapest option that clears your retention requirement, measure your active series honestly, and move when the numbers say to. Do not buy a distributed system in advance of needing one.

How to choose in ten minutes

  1. Run the topk cardinality query above and write down your total active series and daily sample rate. Nothing else on this list can be evaluated without those two numbers.
  2. Decide your retention requirement out loud, and separate it from your query requirement. Thirteen months of downsampled data for capacity planning is a different product from thirty days of raw data for incident response.
  3. Decide whether alert evaluation stays in your own Prometheus and Alertmanager. Keeping it local means an outage at the remote store degrades your dashboards but not your paging, which is usually what you want.
  4. Check where your identity already lives. SigV4 versus a bearer token sounds trivial and is the kind of trivial that adds a week.
  5. Only then pick a store, and pick it knowing that remote_write means switching later costs you a config block and a backfill decision, not a rewrite.

The short version

Run Prometheus for scraping and alerting no matter what — it is the reliable, dependency-free part and nothing has replaced it. Then choose the store behind it: Grafana Cloud if you want one vendor for the whole stack, Amazon or Google's managed service if your cloud and identity are already there, VictoriaMetrics if you want efficiency and the least operational ceremony, Thanos if you already have many Prometheus servers and object storage, and a cardinality-control vendor if metrics spend has become a governance problem rather than a technical one.

And whichever you pick, the thing that will actually determine your bill and your stability is not on the vendor's comparison page. It is whether someone on your team puts a user-controlled value into a label. Ours did. It was me.

Frequently asked questions

Is Prometheus highly available on its own?

No. Prometheus is a single-node design with a local TSDB, and there is no clustering or replication built in. The standard pattern for redundancy is running two identical instances scraping the same targets with a distinguishing external label such as replica, which gives you collection redundancy but not one coherent view — the two copies disagree on sample timestamps. Deduplicating them is the job of a layer above, which is what Thanos Query, Mimir and the managed services all do. If a monitoring gap during a host reboot is unacceptable, you need that layer.

What is remote_write and why does it matter when choosing a host?

remote_write is the Prometheus config block that streams every sample it collects to an external endpoint in real time. It matters because it is the common seam that almost every managed metrics backend plugs into — Grafana Cloud, Amazon Managed Service for Prometheus, Google Cloud Managed Service for Prometheus and VictoriaMetrics all accept it. That makes the store a far more reversible decision than most infrastructure choices: you keep your local Prometheus for scraping and alerting, and switching backends is a config change plus a decision about historical data, not a rewrite.

How do I find high-cardinality metrics in Prometheus?

Start with topk(10, count by (__name__)({__name__=~".+"})) to rank metric names by series count, and count({__name__=~".+"}) for your total active series, which is the number most vendors price on. The /status/tsdb page in the Prometheus UI shows the same breakdown more cheaply on a large instance. Then check churn with rate on prometheus_tsdb_head_series_created_total — high churn with a flat total means labels tied to short-lived things. Once you find the metric, test each candidate label with count(count by (label) (metric)) until one returns thousands.

What causes a cardinality explosion?

A label whose values are unbounded. User ids, request ids, full URL paths, error message text, session tokens, container ids that change on every deploy. Each distinct label combination is a separate series with its own index entry and memory, so adding one such label multiplies your existing series rather than adding one. We hit this on our own agent: a proxy route label carried whatever URL a tenant's app served, producing 2,743 distinct label values and 50,496 metric lines on one host in six days. High-cardinality identifiers belong in logs and traces, which are designed for that lookup pattern.

Can I run Prometheus on PandaStack?

Yes, as a self-hosted app — but we do not sell a managed metrics backend, so be clear about what you are getting. A PandaStack app is a full Ubuntu userspace in a Firecracker microVM deployed from git, so you install prometheus or victoria-metrics, point the data directory at a durable volume, and run Alertmanager and exporters alongside it in the same sandbox because it is a real VM with root, not a single-entrypoint container. Managed Postgres 16 is available for a paired Grafana's state. At real scale you want a purpose-built long-term store, not a single Prometheus on one VM.

Should I use Thanos or Mimir or VictoriaMetrics?

They solve the same problem with different shapes. Thanos leaves your existing Prometheus servers untouched and uploads their TSDB blocks to object storage, which suits fleets you do not want to reconfigure, at the cost of several components to operate. Mimir is a horizontally scalable remote_write target, self-hostable or managed as Grafana Cloud. VictoriaMetrics is the efficiency-focused option whose single-node binary handles a surprisingly large workload before you need the cluster, making it the gentlest upgrade from one Prometheus. Pick based on your operational appetite and whether you already have object storage.

Keep reading

Run code in a microVM in one API call.

49ms p50 cold start. Fork, snapshot, and scale to zero.

Start free
Written by Ajay Kumar, Founder, PandaStack.