TL;DR #
- Priced on the same workload — 6 engineers, 8 services, 90 GB of logs a month, 25,000 metric series — hosted lands at about $161/month on Grafana Cloud Pro and self-hosting lands at about $51/month of infrastructure. The gap is $110/month.
- $110/month buys roughly 1.4 engineer-hours at an $80/hour loaded rate. That is the entire decision: can you run Loki, Prometheus and Grafana in under an hour and a half a month? One chart upgrade costs more than that.
- The gap widens with volume. At 30 GB of logs a day it is about 5 hours a month; the gap only covers a full engineer-day a month somewhere around 45-50 GB/day. The crossover for a small team sits roughly an order of magnitude above where most small teams actually are.
- Self-hosted Loki fails on documented defaults you have not read: 4 MB/s per-tenant ingest, 3 MB/s per stream, 5,000 streams, 256 KB per line, and HTTP 429 past 2,048 outstanding queries.
- Self-hosted Elasticsearch fails on heap and disk: heap capped near 26-30 GB regardless of machine size, and a read-only index block on every index on a node above 95% disk.
- Open source and self-hosted are not the same choice. Grafana Cloud and Amazon Managed Prometheus are hosted open source, and that is the answer for most teams this size.
- Prices checked 7 August 2026.
Who this is for #
You are 3-10 engineers, you already have a monitoring bill or are about to have one, and someone on the team has said “we could just run this ourselves”. This page is the arithmetic that settles that argument, plus the specific ways each side breaks.
If you do not yet know your own gigabytes per day or active series count, stop here and get them first — Observability on a budget has the commands. Every number below is meaningless without your two.
The same workload, priced both ways #
The reference workload is the one from the budget guide, unchanged so the two pages can be compared line for line: 6 engineers, 8 services on 3 managed Kubernetes nodes, ~5 million log lines a day at ~600 bytes each (3 GB/day, 90 GB/month), and ~25,000 active metric series.
Hosted #
Grafana Cloud Pro at list prices checked 7 August 2026: $19 platform fee, $4.50 to process 90 GB, $16.00 to write the 40 GB past the included 50, $97.50 for the 15,000 series past the included 10,000, and $24.00 for the three engineers past the included three users.
$161.00/month. Datadog with every log indexed comes to about $309/month for the same telemetry; with exclusion filters trimming the index to 10%, about $80. The full line-item breakdown for both is in the budget guide and is not repeated here.
Self-hosted #
Prometheus, Grafana, Loki and Alertmanager on your own hardware, with chunks in object storage.
| Line item | Rate | Reference workload | Cost |
|---|---|---|---|
| Compute | $48/month for 8 GiB / 4 vCPU (DigitalOcean) | 1 node | $48.00 |
| Block storage for Prometheus | $0.10/GiB/month (DigitalOcean Volumes) | 20 GiB | $2.00 |
| Object storage for Loki chunks | $0.015/GB-month (Cloudflare R2, egress free) | 90 GB | $1.35 |
| Total | $51.35 |
Two of those numbers deserve their working shown.
Prometheus disk. The documented formula is needed_disk_space = retention_time_seconds * ingested_samples_per_second * bytes_per_sample, with an average of 1-2 bytes per sample. 25,000 series scraped every 15 seconds is 1,667 samples/second; over 15 days of retention that is 2.16 billion samples, or roughly 4.3 GB. A 20 GiB volume is generous, and it costs $2.
Loki storage. Loki “does not index the contents of the logs, but only indexes metadata about your logs as a set of labels for each log stream”, and the log data itself is “compressed and stored in chunks in an object store”. Ninety gigabytes a month at 30-day retention is under $1.50 on R2 even before compression, and R2 charges nothing for egress. Chunk writes are Class A operations at $4.50/million; a few thousand a day sits well inside R2’s free million a month.
The single node is sized against this site’s own Kubernetes monitoring stack, where the full set of charts asks for roughly 1.3 GiB of memory requests. Eight gigabytes leaves headroom; four does not once Prometheus grows with active series.
The gap #
$161.00 hosted − $51.35 self-hosted = $109.65/month.
Now convert it into the only currency that matters:
hours_you_can_afford = monthly_gap / your_loaded_hourly_costAt a loaded $80/hour — substitute your own, this is not a benchmark — that is 1.37 hours a month. Eighty-two minutes to keep Loki, Prometheus, Grafana and Alertmanager patched, upgraded, backed up, and answering queries during an incident.
A single Loki chart upgrade that changes a default spends that budget in one afternoon. So does one Prometheus OOM. So does the first time somebody asks why a dashboard is empty.
Where the line actually sits #
The gap is not fixed. It scales with volume, because the hosted side charges per gigabyte and the self-hosted side mostly does not.
| Log volume | Grafana Cloud Pro | Self-hosted infrastructure | Monthly gap | Hours it buys at $80/h |
|---|---|---|---|---|
| 3 GB/day (90 GB/month) | $161 | $51 | $110 | 1.4 |
| 30 GB/day (900 GB/month) | $526 | $120 | $406 | 5.1 |
| 47 GB/day (1.41 TB/month) | $755 | $127 | $628 | 7.8 |
The 30 GB/day row: $19 platform + $45 processed + $340 written (850 GB past the included 50, at $0.40) + $97.50 metrics + $24 users. Self-hosted: two nodes at $48, a 100 GiB volume at $10, and 900 GB on R2 at $13.50.
The 47 GB/day row, same rates: $19 + $70.50 processed + $544 written (1,360 GB past the included 50) + $97.50 + $24. Self-hosted: the same two nodes and 100 GiB volume, with 1,410 GB on R2 at $21.15. Every figure in the table is reproducible from the two rate cards; substitute your own numbers rather than trusting these.
Read the last column. The gap only covers a full engineer-day per month somewhere around 45-50 GB of logs a day — fifteen times the reference workload. Below that, self-hosting is buying you a few hours of budget to run four stateful services in.
Three caveats that all push the line further right:
- The self-hosted column is missing the hours it needs to build, not just to run. The first month is not 1.4 hours.
- The self-hosted column has no redundancy in it. One node, one volume, one Loki. Add a replica and it moves toward the hosted column.
- The hosted column can be cut without any engineering hours at all. Exclusion filters, shorter retention and cleaner labels are configuration. Get those wrong on the self-hosted side and you buy hardware instead.
What self-hosted Loki does when you get it wrong #
Loki is the right choice for cheap log search — it indexes labels rather than log contents, so it does not need the RAM Elasticsearch needs. It is also opinionated about limits, and every one of these is a default you inherit without reading it. The values below are from Loki’s own configuration reference for v3.7.6:
| Default | Value | What it does to you |
|---|---|---|
ingestion_rate_mb |
4 MB/s per tenant | 3 GB/day averages 35 KB/s, so you never see it — until a collector reconnects and replays a buffer, and then you see nothing but 429s |
ingestion_burst_size_mb |
6 MB | The size of push request you can spike to. Bigger batches are rejected outright |
per_stream_rate_limit |
3 MB, burst 15 MB | One chatty container exceeding this has its lines dropped, not queued. The rest of the cluster looks fine |
max_global_streams_per_user |
5,000 | Every unique label combination is a stream. Add a label with unbounded values and you hit this in an afternoon |
max_label_names_per_series |
15 | Enthusiastic Kubernetes relabelling reaches this faster than you would guess |
max_line_size |
256 KB | Longer lines are truncated or discarded. A serialised request body or a deep stack trace is gone |
reject_old_samples_max_age |
1 week | Backfilling last month’s logs after fixing a collector simply fails |
max_entries_limit_per_query |
5,000 entries | The query you run during an incident silently stops short |
max_query_series |
500 | Metric queries over logs error out rather than truncate |
max_query_length |
30d1h | Queries wider than this are refused |
max_outstanding_per_tenant (query frontend) |
2,048 | “requests beyond this error with HTTP 429” — four people refreshing dashboards during an incident is how you find it |
None of these are bugs. They are a distributed system protecting itself, and every one of them is tunable. The point is that tuning them is the job you just hired yourself for, and you will be doing it at the worst possible moment — because the incident that generates the log storm is the same incident during which you need to read the logs.
Add to that the chart defaults that stop the thing from starting at all: the Loki Helm chart’s memcached tiers alone request roughly 11 GiB and leave every pod Pending on a small node. That trap and its fix are documented in the Kubernetes monitoring stack.
What self-hosted Elasticsearch does when you get it wrong #
If you want full-text search over logs rather than label-and-grep, Elasticsearch or OpenSearch is the honest answer — and it is a materially bigger operational commitment than Loki, because it indexes the content of every line instead of a handful of labels.
Three defaults account for most small-team failures:
- Heap does not scale with your machine. Elastic’s guidance is to set
XmsandXmxto “no more than 50% of the total memory available to each Elasticsearch node”, and no more than the compressed-oops threshold, where “26GB is safe on most systems and can be as large as 30GB on some systems”. A 128 GB machine does not give you a 64 GB heap. Past that point you scale out, which means a cluster, which means cluster operations. - Disk watermarks turn your log store read-only. The defaults are 85% low, 90% high, and 95% flood stage. At flood stage, Elasticsearch “enforces a read-only index block on every index that has one or more shards allocated on the node”, and the block is released only once utilisation drops back below the high watermark — not the flood stage one. Your logging system stops accepting logs and stays stopped until you free real space.
- Shard counts punish small deployments specifically. Elastic recommends aiming for “shard sizes between 10GB and 50GB”, keeping documents per shard below 200 million, and staying “fewer than 3000 indices per GB of heap on master nodes”. A small team producing 3 GB of logs a day with a daily index per service produces lots of tiny shards, which is precisely the shape the guidance warns against — the cluster spends its heap on bookkeeping rather than on your searches.
For a team of this size, running Elasticsearch for logs is a decision to have an Elasticsearch operator. If nobody on the team wants that job title, do not take it on by accident.
What SaaS does when you get it wrong #
The hosted side fails too. It just fails in a way you find out about on the invoice rather than during an outage.
- The bill follows a bug. A service crash-looping at DEBUG multiplies your ingest. The budget guide has the arithmetic; the summary is that per-event indexing pricing punishes a log storm roughly five times harder than per-gigabyte pricing.
- Queries can be billable. Datadog’s log line is “$0.10 per ingested or scanned GB”. An enthusiastic afternoon in the log search is a real cost, not a free one. Know whether your vendor charges for reads before you tell the team to go digging.
- Seats can dominate at small volumes. New Relic’s data allowance is 100 GB/month free, which covers this whole workload, while full platform users are $10 for the first and $99 for each additional one (maximum five) on Standard. At small telemetry volumes you are buying seats, not gigabytes, and headcount growth is the thing that moves the bill.
- Proprietary agents are the lock-in, not the backend. Switching backends is a configuration change if you collect with OpenTelemetry or Vector. It is a re-instrumentation project if you collected with a vendor SDK.
- Data residency is a hard constraint, not a preference. If a customer contract says the data does not leave a jurisdiction, no amount of pricing arithmetic applies. You need an in-region provider, a documented subprocessor list and a DPA — or you self-host in the required region and accept the hours.
The hybrid most teams should actually run #
Split the stack by which parts are cheap to operate and which are not.
- Self-host the collectors. OpenTelemetry Collector or Vector as a DaemonSet. Stateless, restartable, and the thing that keeps your instrumentation portable.
- Pay for the stateful parts. Log search and long-term metric storage are the storage-hungry, always-needed-during-an-incident components. Those are worth someone else’s on-call.
- Filter at the collector, not at the vendor. Drop health checks, readiness probes and 2xx access logs before they become billable, so the same config works whichever backend you point at.
This is what “hosted open source” means in practice, and it is worth saying plainly because the two get conflated constantly: open source and self-hosted are different choices. Grafana Cloud and Amazon Managed Prometheus are hosted open source. Choosing a managed backend is not giving up on open source; it is declining to be its operator.
When self-hosting is genuinely right #
Four conditions. The first three have to hold together, not as alternatives:
- Telemetry volume is high and stable. From the table above, that means tens of gigabytes of logs a day, not a few — and stable, because the self-hosted cost model does not absorb spikes gracefully either.
- Someone owns it by name. Not “the team”. A person who will do the upgrades and take the page when the log store is the thing that is down.
- Reliability requirements justify the complexity. You are adding a stateful system whose failure mode is blindness during an incident.
And one standalone condition that overrides all of them:
- Data residency or contractual isolation. If the telemetry cannot leave your infrastructure, the other three stop mattering and you self-host regardless of the arithmetic.
High log volume alone is the most common reason teams self-host and then regret it. It is condition one of three.
The “good enough” bar, either way #
Whichever side you land on, the target is the same: one place to look during an incident that holds both logs and metrics, five to ten alerts worth waking up for, deploy markers visible on the dashboards, and explicit retention and cost limits. Teams fail that bar on the alert count far more often than on the tooling choice — which is a hint about where the effort belongs.
Questions people ask #
Is self-hosted monitoring actually cheaper than SaaS? #
Priced on the same workload — 90 GB of logs a month and 25,000 metric series — Grafana Cloud Pro comes to about $161/month at list prices checked on 7 August 2026, and self-hosted Prometheus, Loki and Grafana comes to about $51/month of compute, block storage and object storage. The $110/month gap is the entire budget you have for operating four stateful services, which at an $80/hour loaded rate is under an hour and a half a month. The invoice does not disappear when you self-host; it converts into storage, compute and engineering hours, and the hours are the expensive part at small scale. Self-hosting is cheaper only once the gap grows large enough to pay for the attention it consumes.
At what log volume does self-hosting start to pay for itself? #
The gap between hosted and self-hosted grows with volume because the hosted side charges per gigabyte and the self-hosted side mostly does not. At 3 GB of logs a day the gap buys about 1.4 engineer-hours a month at an $80/hour loaded rate; at 30 GB/day it buys about 5 hours; it only covers a full engineer-day per month somewhere around 45-50 GB/day. That last figure is fifteen times the volume of a typical 3-10 engineer team, which is why the honest answer for most small teams is “not yet”. Recalculate with your own loaded hourly rate, since that input moves the crossover more than any vendor price does.
What breaks first when you self-host Loki? #
Almost always a default limit rather than the software. Loki’s shipped configuration caps per-tenant ingestion at 4 MB/s, per-stream ingestion at 3 MB/s, active streams at 5,000 per tenant, log lines at 256 KB, and query results at 5,000 entries, and the query frontend returns HTTP 429 past 2,048 outstanding requests per tenant. None of these bite at a steady 3 GB a day, but all of them bite during exactly the traffic spike or crash loop that made you open the logs in the first place. They are all tunable, and tuning them under incident pressure is the job you signed up for when you chose to operate it yourself.
Should a small team self-host Elasticsearch for log search? #
Usually not. Elasticsearch heap cannot exceed roughly 26-30 GB regardless of machine size — Elastic’s guidance is no more than 50% of node memory and no more than the compressed-oops threshold — so growth means running a cluster rather than a bigger box. Its disk watermarks default to 85%, 90% and 95%, and at the 95% flood stage it applies a read-only index block to every index with a shard on that node, releasing it only once usage drops back below 90%; that is your log store refusing writes during an incident. If you want cheap log search without that operational surface, Loki indexes labels rather than log contents and is a materially smaller commitment; if you genuinely need full-text search, budget for someone whose job includes shard sizing.
What are the pros and cons of open source observability versus SaaS? #
SaaS gives you working dashboards, alerting and retention on day one, priced per volume, and the cost is predictable only if your telemetry is. Self-hosting removes the per-gigabyte invoice and gives you control over data locality, at the price of someone owning upgrades, storage and the on-call for the monitoring system itself — and the storage cost does not vanish, it moves onto your own bill. Note too that open source and self-hosted are not the same choice: Grafana Cloud and Amazon Managed Prometheus are hosted open source, and the hybrid most small teams should run is open source that you pay per gigabyte for. The asymmetry that decides it: when SaaS gets expensive you get an invoice, and when self-hosted monitoring breaks you find out during an incident, while blind.
When does self-hosted monitoring make sense? #
When telemetry volume is high and stable, and someone owns the system by name, and your reliability requirements justify adding a stateful service whose failure mode is blindness. Those three are conditions to satisfy together rather than alternatives, and high log volume alone is the most common reason teams self-host and then regret it. Data residency is the one standalone reason: if the telemetry cannot legally or contractually leave your infrastructure, the cost arithmetic stops applying and you self-host in the required region. Everything else is a calculation, and at 3-10 engineers that calculation usually says pay someone.
Related reads #
- Observability on a budget — how to measure your own gigabytes per day and active series, plus the four levers that cut a hosted bill
- Kubernetes monitoring stack — the actual Helm values if you decide to self-host it
- Open source DevOps tools — the wider shortlist and the same open-source-versus-self-hosted distinction
- Minimal DevOps stack — where monitoring fits among everything else a small team runs
- Incident response for small teams — the on-call rotation that either side of this choice hands you