Do not tune every metric: start with a 60-second scrape interval
By Nicolas Narbais
A practical 60-second metric collection default, with the alerting, query, source-load, and billing checks needed for justified exceptions.
Use a 60-second collection interval for normal metrics. Change it when you have a clear reason: an alert needs a faster signal, a collector puts load on a database, or your provider charges for each point.
At 15 seconds, one scalar time series sends four points per minute. At 60 seconds, it sends one. Over 30 days, that is 175,200 points versus 43,800. The lower rate can cut sample-priced ingestion by 75%. A slower rate can also miss a short spike. Side note, an active-series pricing may leave the bill unchanged.
The collection interval affects the whole metric path. It affects the source, the bill, the dashboard query, and the alert. To keep things simpler across board use one shared default interval as much as possible.
Keep one default for normal metrics
Prometheus lets you override the global scrape_interval for a scrape job. OpenTelemetry lets you run readers and exporters at different rates. The Collector Host Metrics receiver even shows one split: CPU and memory at 30 seconds, disk and filesystem at one minute. Prometheus documents job-level overrides. The Host Metrics receiver documents the split.
Use those controls for a clear need. Avoid using them as a preference field for each metric. The team that changes a scrape interval also changes the assumptions in dashboards and alerts.
Consider a dashboard for requests_total:
- An API service is scraped every 15 seconds.
rate(requests_total[1m])has several samples to use. - A batch service is scraped every 60 seconds. The same one-minute range can contain one sample, so Prometheus cannot calculate a rate.
You need at least two samples for a derivative.
With a shared scraping cadence, dashboard users use one rate-window rule. Alert reviewers use one observation budget… Everything becomes simpler.
Check how the provider bills metrics
“Datapoint” can mean different things on different bills. Check the provider’s meter before changing the interval.
| Provider charges for | A 60-second interval can do | You still need to check |
|---|---|---|
| Samples or data points | Send one quarter as many scalar points as a 15-second interval | Labels and histogram buckets |
| Bytes ingested | Reduce the number of metric writes | Metric type and encoding |
| Active series | Leave the series count unchanged | Cardinality remains the cost driver |
| Active series plus DPM | Reduce DPM | Active series can still set the bill |
Google Cloud pricing is impacted by the frequency. Its Managed Service for Prometheus guide says that the change can save 75% of sample cost between 15-second and 60-second scraping intervals. The pricing example and the cost guide describe Google’s model.
On the other side, Datadog’s custom-metric billing documentation measures distinct metric-name and tag-value combinations over time. Sending each series less often can leave that count unchanged.
Grafana Cloud tracks active series and data points per minute. A lower data-point rate can reduce DPM while active series remain the billable limit.
In the case of Datadog or Grafana, count labels before you estimate the saving. Each label combination is another time series. Google’s sample accounting counts an explicit histogram as two samples plus its non-empty buckets.
So if you plan to save costs, make sure you understand your billing model in depth so you can estimate savings.
Use one minute when the alert can wait
Prometheus defaults scrape_interval and evaluation_interval to one minute. OpenTelemetry’s periodic MetricReader defaults to 60,000 ms. The Host Metrics receiver defaults to one minute. Prometheus, the OpenTelemetry metrics specification, and the receiver documentation support one minute as a baseline.
AWS uses the same schedule in its Managed Grafana JVM monitoring solution, with dashboards at one minute, five minutes, or longer. AWS documents that configuration. This is one reference configuration, not a survey of all production systems.
Use 60 seconds for host capacity, service throughput, request errors, common latency distributions, and other metrics where an operator does not need a sub-minute response.
Now to understand if this is a good choice, start to calculate the alert timeline. A failure starts one second after a scrape. Prometheus sees it at the next scrape, close to 60 seconds later. The next rule evaluation can add close to another minute. A five-minute for period then adds five minutes before the alert fires. Notification delivery adds its own delay.
Use this as the review model:
wait for scrape + wait for evaluation + for period + notification delay
A human response that must start inside two minutes may need a faster collection path. A capacity alert with for: 10m has room for a 60-second collection interval.
Use a longer query window than the scrape interval
At a one-minute cadence, start rate() and increase() queries with a four-minute range. Google Managed Service for Prometheus recommends at least four scrape intervals for sparse data. Google documents the rule of thumb.
For example, use rate(requests_total[4m]) (or more e.g. 5m) for a service scraped once a minute. A one-minute range can produce no result. Test the range in the dashboard and alert that use it.
Give exceptions a job
Use a faster cadence for a named fast-page or automation need. For example, a service owner may need an alert to react inside two minutes. They can choose 30 seconds after they check the scrape time, rule interval, for period, and notification delay.
Use a slower cadence for expensive or inventory-like collection. The OpenTelemetry SQL Server receiver separates its 10-second overall metric collection from optional top-query collection at 60 seconds. Its documentation shows a separate path for a more expensive query.
Choose a different signal when a scrape cannot capture the event. A requests_per_second gauge can rise from 0 to 1,000 and return to 0 between two scrapes. Prometheus stores two zeroes and misses the peak. The requests_total counter still increases during that minute. rate(requests_total[4m]) shows the added request volume, though it cannot show the exact peak rate. So check if you should send/user a counter or a gauge in those situations.
For each exception request, make sure you get the information on those 4 items. It will then be easier to justify the changes.
- The alert, automation, or diagnostic question that needs the interval.
- The expected time from failure to alert.
- The dashboard and query changes that use the new cadence.
- The effect on points, source load, or collection cost.
Review a 60-second default with five checks
- The scrape, rule evaluation,
forperiod, and notification path fit the response budget. - Dashboards and alerts use a tested
rate()orincrease()window. Start at (at least) four minutes for sparse one-minute data. - The scrape timeout stays below 60 seconds, and the source has margin under that timeout during load.
- The billing model rewards fewer samples or bytes. If active series drive the bill, present the change as an operating policy rather than a cost saving.
- Each exception records its owner, reason, cost, and consuming queries.
A 60-second default gives the platform one documented starting point. Keep each exception with its alert and dashboard changes.
Written by Nicolas Narbais
I work at Tsuga and write about observability, OpenTelemetry, and the practical work of making monitoring useful for engineering teams. Earlier Datadog experience also informs the guidance shared here. I am also running Olatuak to help teams reduce telemetry waste and improve observability outcomes.
Building an OpenTelemetry pipeline?
Explore more implementation guides and collector patterns for teams standardizing telemetry without adding unnecessary noise.