How much disk does Prometheus actually need?

Prometheus's own documentation gives an exact formula for this — retention time, times ingestion rate, times bytes per sample — but two of those three numbers depend entirely on metrics and label cardinality only you know, and the third, bytes-per-sample, is a cited range rather than a constant. Fill in your own numbers below to work through it.

Prometheus's storage docs cite roughly 1–2 bytes per sample compressed. 1.3 is this tool's default midpoint — change it, it is not a constant.

An order-of-magnitude placeholder for index overhead per series, additional to the official sample-storage formula.

1 = no churn assumed. Raise it if instances restart often within your retention window.

Active series 0
Samples / sec 0/s
Total samples (retention) 0
Estimated disk 0 B

The working

  1. Active series — sum of every metric's label-product × its targets
  2. Samples per second
  3. Total samples over the retention window
  4. Sample bytes
  5. Index bytes (churn-adjusted)
  6. Estimated disk = sample bytes + index bytes

Per-metric breakdown

The formula, and where it comes from

Prometheus's own storage documentation gives capacity planning as one line:

needed_disk_space = retention_time_seconds * ingested_samples_per_second * bytes_per_sample

Two of those three terms are entirely about your own instrumentation, not about Prometheus itself. ingested_samples_per_second is active series divided by scrape interval — and active series is the product of every metric's label cardinalities, multiplied by however many targets expose it, summed across every metric you run. There is no way to look that number up for “a typical Prometheus deployment,” because it does not exist independent of what you have chosen to instrument. The calculator above exists because this half of the formula has to be computed from your specific metrics, not looked up.

The third term, bytes_per_sample, is the one genuinely general figure in the formula, and Prometheus states it directly: “Prometheus stores an average of only 1-2 bytes per sample.” That range comes from Gorilla-style delta-of-delta compression on chunks of slowly-changing values, which is genuinely effective for typical metrics — counters that increase steadily, gauges that drift gently — but is an average under favourable conditions, not a constant. Highly volatile values compress worse. That is why this tool keeps it as an input with a cited default of 1.3 rather than hard-coding either end of the range as fact.

The term the official formula doesn't itemise: the index

Sample bytes are not the whole disk picture. Every series, however few samples it has contributed, needs an entry in the index that maps its label combination to the chunks holding its data. Prometheus's capacity-planning formula is specifically about sample storage and does not break the index out as a separate line, but the cost is real, and it scales with how many distinct series have existed over the retention window — including ones that stopped being active partway through, a phenomenon usually called churn — rather than with how many samples those series produced.

This matters most exactly when it is least visible: a Kubernetes deployment with autoscaling or frequent rolling restarts can have a modest, stable active series count at any given moment while still accumulating a much larger number of distinct series over a 30-day retention window, each contributing its own index entry that outlives the series itself until compaction eventually reclaims it. This tool models that with a churn multiplier: a value of 3 treats the index as if three times as many distinct series existed as are active at any one instant, while leaving the sample-bytes calculation (which depends on ingestion rate, not on distinct-series-ever-seen) untouched. That is why index bytes and sample bytes are shown as two separate numbers above rather than combined into one — they respond to different things, and collapsing them would hide which one is actually driving your disk usage.

How Prometheus actually writes these bytes to disk

The formula above gives a total, but the way Prometheus reaches that total on disk explains a few things that a single number can't. Ingested samples are grouped into two-hour blocks; each block is a directory holding a chunks subdirectory with the compressed sample data, an index file, and metadata — this is the unit the bytes_per_sample figure describes. The current, not-yet-complete block lives in memory, which is why Prometheus also maintains a write-ahead log (WAL): uncompacted, unsorted data written in 128 MB segments, kept so that a crash before a block is finalised doesn't lose the data it holds. Prometheus's own documentation notes it keeps a minimum of three WAL segments, with busier servers retaining more to cover at least two hours of raw data — and because this data is uncompacted, the WAL directory is typically far larger, byte for byte, than the compacted blocks holding the same time range.

Those two-hour blocks don't stay two hours forever. A background compaction process merges them into progressively larger blocks, and Prometheus states the limit directly: compaction “will create larger blocks containing data spanning up to 10% of the retention time, or 31 days, whichever is smaller.” This is why the disk usage of a fresh Prometheus instance and one that has been running for months at the same series count can look different even at an identical sample volume — compaction is still catching up on the newer one.

Retention itself has a second configuration path beyond the time-based --storage.tsdb.retention.time flag this whole page assumes: --storage.tsdb.retention.size caps total storage by bytes instead of by age, deleting the oldest blocks first once the cap is reached, and whichever limit is hit first wins if both are set. Prometheus's own recommendation is to set that size cap to at most 80–85% of the disk actually allocated to leave headroom for the current in-progress block and WAL, which are not counted against the size limit the same way completed blocks are. If you know your disk size before you know your retention period, sizing by retention.size rather than retention.time is often the more direct way to stay within it.

One more detail worth knowing if a number here doesn't match what du reports on a real server: deleting series through the API doesn't reclaim space immediately. Deletions are recorded as tombstones rather than rewriting chunk files in place, and expired-block cleanup runs in the background and can take up to two hours to actually remove a block once it has fully expired. A Prometheus instance can legitimately be holding slightly more on disk than its retention setting implies for a short window, and that is expected behaviour, not a leak.

Retention and scrape interval, worked through

Two levers are entirely within an operator's control without touching instrumentation at all:

Retention period

A direct multiplier on total samples and sample bytes: doubling retention from 15 to 30 days doubles both, with active series and samples-per-second completely unchanged. Retention is usually the first lever operators reach for when disk runs short, and it is the most predictable one — the relationship is exact, not approximate, so halving retention to recover disk headroom has a fully calculable effect before you make the change.

Scrape interval

Doubling the scrape interval (scraping half as often) halves samples per second and, proportionally, halves total samples and sample bytes over the same retention window. It does nothing to active series or index bytes, since those count distinct series, not how frequently each is sampled. The real cost is resolution: a 60-second interval will not capture a 10-second spike the way a 15-second interval would, which matters enormously for some alerting use cases and not at all for others. This is a trade-off to make with the specific metric's purpose in mind, not a default to change blindly for disk savings.

A worked comparison

Using the estimator's default 1.3 bytes/sample and 100 index-bytes/series, holding 19,260 active series constant (the small healthy-cluster example from the main tool page) and varying only retention and scrape interval:

ScenarioScrape intervalRetentionSamples/secEstimated disk
Baseline15s15d1,2842.17 GB
Double the retention15s30d1,2844.33 GB
Double the scrape interval30s15d6421.08 GB

Doubling retention roughly doubles disk; doubling the scrape interval roughly halves it — both exactly what the formula predicts, and both leaving active series (and therefore memory and query cost) completely unaffected, because neither lever touches how many distinct series exist.

Beyond a single instance

Prometheus's storage model, and the formula above, describe one server writing to its own local disk, with no built-in replication and retention bounded by how much of that disk it can use. For requirements beyond that — multi-year retention, durability across node loss, a single query surface across many Prometheus servers — the standard pattern is remote_write to a long-term storage backend designed for exactly that, with the local instance keeping only a short buffer window on fast local disk. That is a deliberate architectural decision with its own operational trade-offs, not a configuration flag, and sits outside what a single-instance calculator like this one can estimate.

Frequently asked questions

What is Prometheus's own formula for disk space?

Prometheus's storage documentation gives it directly: needed_disk_space = retention_time_seconds * ingested_samples_per_second * bytes_per_sample. This tool's first two steps — active series divided by scrape interval, then multiplied by retention — compute exactly the retention_time_seconds * ingested_samples_per_second half of that formula, then multiply by an adjustable bytes-per-sample and add a separate index-overhead term the official formula does not itemise on its own.

Does doubling retention double my disk usage?

For the sample-bytes portion, yes, exactly — it is a direct multiplication in the formula, so twice the retention time with everything else held constant is twice the samples, and twice the sample bytes. Index bytes behave differently: they scale with the number of distinct series that have existed over the window (including churned ones), which grows with retention too, but not necessarily in exact proportion, since a longer window captures more distinct churned series without those adding proportionally more index cost per series.

Should I lower my scrape interval to save disk?

Increasing the scrape interval (scraping less often) does reduce samples per second and therefore total samples and sample bytes proportionally — doubling the interval halves both. It does not reduce active series or index bytes at all, since those depend on how many distinct series exist, not how often each is sampled. The trade-off is resolution: a longer interval means less granular data, which can hide short-lived spikes that a shorter interval would have captured. This is a genuine trade-off to make deliberately, not a free optimisation.

What happens when local disk isn't enough?

Prometheus's own model assumes local disk on the same node running the server, which does not scale indefinitely and has no built-in replication. For retention beyond what local disk can hold, or for durability across node failure, the common pattern is remote_write to a long-term storage backend built for that purpose, with the local Prometheus instance keeping only a short buffer window. That is a deliberate architectural change, not a setting to flip, and is outside the single-instance model this calculator estimates.

Why does this tool add an index-bytes term the official formula doesn't mention?

Prometheus's own capacity-planning formula is explicitly about sample storage, and its bytes-per-sample figure describes chunk-compressed sample data specifically. It does not itemise the separate cost of the index that maps label combinations to those chunks. That index cost is real and, under heavy series churn, can be a meaningful fraction of total disk — so this tool adds it back as an explicit, separately-labelled second term rather than silently folding it into bytes-per-sample and quietly overstating how solid that cited figure is.

More on this topic

Related tools

See all the tools on this site →