Grafana Loki 3.7.8 shipped on September 17, 2026, the latest patch on the 3.7 branch that Grafana’s own docs describe as a major feature release. If your Kubernetes clusters are still shipping logs to Elasticsearch or a per-pod log file nobody reads until an incident, this is a good week to change that. This tutorial walks through a full Loki 3.7 deployment: picking a deployment mode, installing the current Helm chart, wiring up log shipping from your cluster, connecting Grafana for queries, and building alerting on top of log data instead of just metrics. Budget around 90 minutes for a working single-cluster setup, more if you’re running the scalable deployment mode across multiple environments.
Loki’s pitch has always been cost. Instead of indexing full log text the way Elasticsearch does, Loki indexes only metadata labels and stores compressed log content in cheap object storage, which is why teams running it on S3 or GCS typically see a fraction of the storage bill of a comparable ELK stack. That tradeoff means Loki queries work best when you know roughly what labels you’re filtering on, which is a different mental model than free-text search. This guide covers both the mechanics of installing Loki 3.7 and the label design decisions that determine whether your setup stays cheap and fast or turns into a slow, expensive mess six months in.
Don't miss new tech stories on Google
Add Tech Insider once in the Google app and our stories appear in your news suggestions.
What’s New in Grafana Loki 3.7
Loki 3.7 launched on March 26, 2026 as Grafana Labs’ newest major generation, and 3.7.8, released September 17, 2026, is the current patch on that branch. The lineage behind it matters for upgrade planning: Loki 3.5 shipped April 17, 2025 and had its security support retired on March 26, 2026, the same day 3.7 arrived, while Loki 3.6, released November 17, 2025, added a horizontally scalable compactor according to Grafana Labs’ 2026 release summary and remains maintained in parallel, with 3.6.17 released September 9, 2026. So if you’re on 3.6 today you’re not on an abandoned line, but 3.7 is where new work lands first. Grafana’s release notes for 3.7 point to it as a substantial feature release rather than a routine patch train, which matters if you’re deciding whether to jump straight to 3.7 or wait a cycle.
The most disruptive change for existing installs isn’t a Loki feature at all, it’s a packaging change. Effective March 16, 2026, the community-maintained Loki Helm chart moved to the grafana-community/helm-charts repository. Grafana continues to maintain a separate chart specifically for Grafana Enterprise Logs, but the open-source community chart now lives under a different maintainer umbrella. As of mid-October 2026, Artifact Hub lists the current community chart at version 18.14.0, published October 7, 2026. If your existing Helm repo reference still points at the old Grafana-hosted chart location, update it before you try to pull the latest chart version, since stale repo references are a common source of confusion when the expected new version doesn’t show up during upgrades.
One more packaging note worth flagging early: Grafana’s Enterprise Logs upgrade documentation states that the built-in MinIO subchart is deprecated and scheduled for removal on October 31, 2026. If you’re using the bundled MinIO for object storage in a test or small production deployment, plan a migration to an external S3-compatible store before that date rather than after your chart upgrade breaks it.
Prerequisites and Version Requirements
Confirm the following before starting. Loki deploys cleanly on any Kubernetes distribution, but this guide assumes a standard cloud-managed cluster (EKS, AKS, or GKE) with Helm already configured.
- A running Kubernetes cluster on version 1.28 or newer, with
kubectlconfigured and cluster-admin access - Helm 3.14 or newer
- Object storage bucket: Amazon S3, Google Cloud Storage, or Azure Blob Storage, with credentials your cluster can assume (IAM role, workload identity, or a service account key)
- An existing Grafana instance, version 11 or newer, either self-hosted or Grafana Cloud, to query and visualize the logs
- At least 4 vCPUs and 8 GB RAM of spare cluster capacity for a small simple-scalable deployment. Monolithic mode can run on less
- Promtail or the Grafana Alloy collector for shipping logs from nodes (this guide uses Alloy, since Promtail is in long-term maintenance mode)
- A rough estimate of your current daily log volume, since this determines which deployment mode and storage tier makes sense
Check the deployment mode documentation before picking a chart configuration. The three supported modes (monolithic, simple scalable, and microservices) trade operational simplicity for horizontal scalability, and switching between them later means a real migration, not a config flag flip. Full details live on the official Loki deployment modes page.
| Deployment Mode | Best For | Scaling Model | Operational Complexity |
|---|---|---|---|
| Monolithic | Dev, staging, small production (under ~100GB/day) | Vertical only, single binary | Low |
| Simple scalable | Mid-size production clusters | Separate read and write paths, horizontal | Medium |
| Microservices | Large multi-tenant, high-volume logging | Every component scales independently | High |
Step 1: Audit Your Current Logging Setup
Before installing anything, get a real number for your current log volume. This drives both the deployment mode choice and your object storage cost estimate. If you’re running any centralized logging already, pull the raw ingest rate from it. If you’re not, estimate from container stdout volume across your busiest namespaces.
kubectl get namespaces -o name | while read ns; do
ns_name=$(echo $ns | cut -d/ -f2)
count=$(kubectl get pods -n "$ns_name" --no-headers 2>/dev/null | wc -l)
echo "$ns_name: $count pods"
done
Namespaces with high pod counts and chatty applications (proxies, API gateways, anything logging at debug level in production) are usually where log volume concentrates. Note them now, since you’ll want tighter label design and possibly separate retention policies for those workloads later. It’s worth doing this audit even if you already run some form of logging today, since a migration to Loki is a good forcing function to ask whether every service actually needs the log verbosity it currently produces. A surprising amount of production log volume, once you look closely, turns out to be debug-level output nobody remembers turning on and nobody actively reads.
Step 2: Add the Loki Helm Repository
Point Helm at the current community chart repository rather than any older bookmarked URL, since the chart moved location in March 2026.
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
helm search repo grafana/loki --versions | head -5
Confirm the version returned matches or is close to 18.14.0, the chart version published October 7, 2026 on Artifact Hub. If Helm returns a much older chart version, your local repo cache is stale. Rerun helm repo update or check the Loki chart listing on Artifact Hub directly to confirm the current published version.
Step 3: Configure Object Storage
Create a values file that points Loki at your object storage bucket. The example below uses Amazon S3, and you can swap the storage block for GCS or Azure Blob Storage if you’re on a different cloud. This is also the point where you decide against relying on the bundled MinIO subchart, given its scheduled removal on October 31, 2026.
# loki-values.yaml
loki:
auth_enabled: false
storage:
type: s3
s3:
region: us-east-1
bucketnames: my-org-loki-logs
s3ForcePathStyle: false
schemaConfig:
configs:
- from: "2026-01-01"
store: tsdb
object_store: s3
schema: v13
index:
prefix: loki_index_
period: 24h
deploymentMode: SimpleScalable
write:
replicas: 3
read:
replicas: 3
backend:
replicas: 3
Grant your cluster’s service account the necessary S3 permissions through IAM roles for service accounts on EKS, workload identity on GKE, or a managed identity on AKS. Avoid long-lived static access keys mounted as Kubernetes secrets. Every major cloud has a workload-identity mechanism at this point, and it removes an entire class of credential-leak risk from your logging pipeline.
Scope the IAM policy narrowly to the specific bucket and prefix Loki writes to, rather than granting broad S3 access to the service account. Loki’s write and compactor components need read, write, and delete permissions on the bucket, but there’s no reason that identity should have access to unrelated buckets in the same account. A scoped policy also makes it far easier to reason about blast radius later if a component’s credentials or configuration are ever compromised.
Step 4: Install Loki 3.7 With Helm
With the values file in place, install the chart into a dedicated namespace.
kubectl create namespace loki
helm install loki grafana/loki \
--namespace loki \
--values loki-values.yaml \
--version 18.13.5
kubectl get pods -n loki -w
Expect output similar to this once every component is running, for a simple-scalable deployment with three replicas per path:
NAME READY STATUS RESTARTS AGE
loki-write-0 1/1 Running 0 2m
loki-write-1 1/1 Running 0 2m
loki-write-2 1/1 Running 0 2m
loki-read-0 1/1 Running 0 2m
loki-read-1 1/1 Running 0 2m
loki-read-2 1/1 Running 0 2m
loki-backend-0 1/1 Running 0 2m
loki-backend-1 1/1 Running 0 2m
loki-backend-2 1/1 Running 0 2m
loki-gateway-7f8b9c-x 1/1 Running 0 2m
If pods stay in Pending, check node capacity first. The simple-scalable mode’s default replica counts assume real headroom across multiple nodes, and a small test cluster may need the replica counts reduced before anything schedules. Once every component reports Running, check the write path’s own ingestion metrics before moving on, rather than assuming a healthy pod status means logs are actually flowing correctly through the pipeline.
kubectl exec -n loki loki-write-0 -- wget -qO- localhost:3100/metrics | grep loki_distributor_lines_received_total
Step 5: Deploy Grafana Alloy for Log Collection
Loki stores and queries logs, but something has to ship them from your nodes. Grafana Alloy is the current recommended collector. It’s a superset of Promtail’s functionality and the direction Grafana is actively developing, so new installs should start there rather than on Promtail.
helm repo add grafana-alloy https://grafana.github.io/helm-charts
helm repo update
helm install alloy grafana-alloy/alloy \
--namespace loki \
--set alloy.mounts.varlog=true \
--set alloy.extraPorts[0].name=loki-write \
--set global.image.registry=docker.io
Alloy runs as a DaemonSet by default, tailing container logs on every node and forwarding them to the Loki write path with the labels you configure. At minimum, attach namespace, pod, and container name labels, and resist the urge to attach anything with high cardinality, like a request ID or a timestamp, as a label rather than as log content. That single mistake is responsible for more blown-up Loki index sizes than anything else in this guide.
Step 6: Connect Grafana as a Loki Data Source
In your Grafana instance, add Loki as a new data source pointing at the in-cluster gateway service. Make sure the bundled Loki data source plugin itself is current before wiring this up: Grafana’s Loki plugin reached version 13.2.2 in October 2026, the result of 8 releases over the year ending that month, so an instance that hasn’t been updated recently may be missing query or visualization fixes those releases shipped.
curl -X POST http://admin:[email protected]/api/datasources \
-H "Content-Type: application/json" \
-d '{
"name": "Loki",
"type": "loki",
"url": "http://loki-gateway.loki.svc.cluster.local",
"access": "proxy",
"isDefault": false
}'
If your Grafana instance runs outside the cluster, either expose the Loki gateway through an ingress with authentication in front of it, or run Grafana in-cluster as well and keep the connection internal. Exposing Loki’s query API directly to the internet without an auth layer in front is a common misconfiguration worth avoiding from day one.
Step 7: Write Your First LogQL Queries
LogQL is Loki’s query language, documented in full on the LogQL reference page, and it splits into two parts: a label selector that narrows which log streams you’re looking at, and an optional filter or parser expression applied to the matched lines. Start narrow with labels, then filter. The label selector is what makes Loki fast, since it determines which index entries get scanned before any text matching happens at all. A query with a tight label selector and a broad text filter is fast. A query with a broad label selector, like matching an entire namespace with dozens of workloads, and a narrow text filter is slow, because Loki has to pull and scan far more log content before the filter narrows anything down.
{namespace="payments", container="api"} |= "error"
{namespace="payments"} | json | status_code >= 500
sum(rate({namespace="payments"} |= "error" [5m])) by (pod)
The first query pulls raw lines containing “error” from the payments namespace’s API container. The second parses JSON-structured logs and filters on a status code field. The third turns log matching into a metric, counting error-line rate per pod over a five-minute window, which is the foundation for log-based alerting in the next step.
Get comfortable with the difference between a log query and a metric query early, since they solve different problems. A log query returns matching lines for you to read. A metric query, built by wrapping a log query in an aggregation function like rate(), count_over_time(), or sum(), returns a number or time series you can graph and alert on. Most teams start by only writing log queries to look at raw output during incidents, then gradually shift toward metric queries once they realize the same LogQL expressions can feed dashboards and alerts, not just ad-hoc searches.
| Label Design Choice | Good Practice | Common Mistake |
|---|---|---|
| Namespace / service name | Always label, low cardinality, core filter | Rarely misused |
| Pod name | Label, bounded cardinality per deployment | Fine in most setups, watch for very large fleets |
| Request ID / trace ID | Keep in log content or structured metadata | Attaching as a label explodes the index |
| HTTP status code | Parse at query time with a JSON or logfmt parser | Adding a label per status code value |
| Timestamp-derived fields | Never label, Loki already indexes by time | Custom time-bucket labels duplicating built-in indexing |
Step 8: Build Log-Based Alerts
Loki’s ruler component evaluates LogQL queries on a schedule and fires alerts through the same Alertmanager pipeline you’d use for Prometheus metrics. This is where log data stops being something you only check after an incident and starts catching problems as they happen.
# loki-alert-rules.yaml
groups:
- name: payment-errors
rules:
- alert: HighErrorRate
expr: |
sum(rate({namespace="payments"} |= "error" [5m])) by (pod) > 10
for: 5m
labels:
severity: warning
annotations:
summary: "High error log rate in {{ $labels.pod }}"
Apply this through the ruler’s configured storage backend (object storage, same as your log chunks) and confirm it’s loaded correctly before relying on it. A ruler misconfiguration fails silently more often than it throws a visible error, so check the ruler’s own logs after applying new rules rather than assuming they took effect.
Log-based alerts work best as a complement to metric-based ones, not a replacement. Metrics catch the things you thought to instrument: request latency, error rates exposed through a counter, resource saturation. Log-based alerts catch the things you didn’t think to instrument ahead of time, like a specific exception message, a dependency timeout string, or a security-relevant log line that never had a dedicated metric built around it. Teams that lean entirely on one or the other tend to have blind spots the other approach would have caught.
Step 9: Set Retention and Compaction Policy
Retention is where Loki’s cost advantage either holds up or evaporates. Set an explicit retention period rather than relying on defaults, and let the compactor enforce it against your object storage bucket.
limits_config:
retention_period: 30d
compactor:
retention_enabled: true
retention_delete_delay: 2h
delete_request_store: s3
Thirty days is a reasonable default for general application logs, but audit and compliance logs may need longer, and high-volume debug logs from noisy services may not need more than a week. Consider per-tenant or per-stream retention overrides if your compliance requirements differ across teams, rather than setting one global number and hoping it fits everyone. Full retention configuration options, including per-tenant overrides, are documented on the Loki retention page.
Set the retention_delete_delay value with some care too. A short delay means storage savings kick in faster, but it also means less time to catch and reverse an accidental retention policy change before data is actually gone. A two-hour delay is a reasonable middle ground for most teams: long enough to catch an obviously wrong config change, short enough not to meaningfully affect your storage bill.
Step 10: Configure Multi-Tenancy for Shared Clusters
If multiple teams share a cluster, enable Loki’s multi-tenancy so each team’s logs are isolated at query time, not just organized by label convention. This matters more than it sounds like it should, since label-based isolation without real tenancy means any team with query access can see every other team’s logs.
loki:
auth_enabled: true
With auth_enabled set to true, every request to Loki needs an X-Scope-OrgID header identifying the tenant. Configure Alloy to inject this header per source, and configure Grafana data sources per team with the matching tenant ID, so each team’s Grafana view only ever queries its own tenant’s logs.
Per-tenant limits are worth setting alongside tenant isolation, not just as a follow-up task. Without them, one team’s traffic spike or misconfigured debug-logging rollout can consume enough shared ingester and query capacity to degrade every other team’s experience on the same cluster, even though each team’s logs are otherwise correctly isolated. Set per-tenant ingestion rate limits and query concurrency caps in the limits config so a single noisy tenant can’t silently become everyone else’s incident.
Step 11: Validate the Full Pipeline
Generate a test log line, confirm it lands in Loki, and confirm you can query it back through Grafana before calling the setup done.
kubectl run log-test --image=busybox --restart=Never -- \
sh -c 'echo "loki-pipeline-test-marker" && sleep 30'
# Then query from Grafana or directly against the Loki API
curl -G -s "http://loki-gateway.loki.svc.cluster.local/loki/api/v1/query_range" \
--data-urlencode 'query={namespace="default"} |= "loki-pipeline-test-marker"'
If the test line doesn’t show up within a minute or two, work backward through the pipeline: check Alloy’s own logs for shipping errors first, then check the Loki write path’s ingestion metrics, then check that your object storage credentials are actually valid and not just present.
Common Pitfalls When Setting Up Grafana Loki
Most Loki deployments that turn slow or expensive trace back to one of these decisions made in the first week, usually before anyone realizes the setup phase is where the real cost and performance ceiling gets set for months to come.
- Using high-cardinality values as labels. Request IDs, user IDs, timestamps, or anything close to unique-per-line as a label explodes Loki’s index and tanks query performance. Keep those in the log content, filtered with LogQL, not in labels.
- Pointing Helm at a stale chart repository. Since the community chart moved to a new repository location in March 2026, teams following an old bookmarked install guide sometimes pull an outdated chart version without realizing it.
- Relying on the bundled MinIO subchart for production. It’s deprecated and scheduled for removal on October 31, 2026. Treat it as a demo-only option, not a production storage backend.
- Skipping an explicit retention policy. Without one, log volume grows indefinitely against your object storage bill, quietly, until someone notices the invoice.
- Exposing the query API without authentication. Loki’s gateway has no built-in access control beyond what you put in front of it. An unauthenticated ingress is an open door to your logs.
- Choosing microservices mode before you need it. The operational overhead of running every Loki component as an independently scaled deployment isn’t worth it below real production log volume. Start with simple scalable and graduate later if you actually hit its limits.
Troubleshooting Grafana Loki Issues
Here’s what actually goes wrong during and after a Loki setup, and how to fix each one. Most of these show up either in the first hour after installation, while the pipeline is still being wired together, or weeks later once real production log volume starts hitting the cluster for the first time.
- Pods stuck in Pending after Helm install. Check node capacity against the chart’s default replica counts. Simple-scalable mode assumes meaningful headroom, and small clusters often need replica counts reduced in the values file.
- “context deadline exceeded” errors from Alloy. Usually a network policy or firewall blocking traffic from the collector DaemonSet to the Loki write path’s service address. Confirm the gateway service is reachable from a debug pod on the same node.
- Logs ingest but queries return nothing. Check the time range in Grafana first. Loki is strict about query time bounds, and a query outside the ingested window returns an empty result with no error.
- “too many outstanding requests” errors on queries. This usually means a query is scanning too many chunks because of an overly broad label selector. Narrow the label match before adding line filters.
- Compactor not deleting old data despite retention_enabled. Confirm the compactor has write access to the same object storage bucket the write path uses. A permissions mismatch between components is a common cause.
- Helm install fails with a chart not found error. Your local Helm repo cache is likely pointing at the old chart location. Run
helm repo remove grafanathen re-add it and runhelm repo updatebefore retrying. - Ruler alerts silently never fire. Check the ruler’s own log output specifically. A malformed rule file often loads without a visible top-level error and simply never evaluates.
- Storage costs climbing faster than log volume. Check for label cardinality creep first. A new deploy that added a high-cardinality label is the most common cause of a sudden index size jump.
- Multi-tenant queries returning cross-tenant data. Confirm
auth_enabledis actually set to true and that every ingestion path, including any test scripts, sends a validX-Scope-OrgIDheader. A missing header on one collector defeats tenant isolation for that source. - Gateway returns 502 errors under load. Check read-path replica count against actual query concurrency. Under-provisioned read replicas are a common bottleneck once real dashboards start hitting the cluster.
Advanced Tips: Scaling and Cost Control
Once the base setup works, a few adjustments make a real difference at scale. First, tune chunk size and target chunk age in the schema config. Larger chunks compress more efficiently in object storage but delay how quickly recent logs become queryable, so there’s a real tradeoff between storage cost and query freshness. Second, set up structured metadata for fields you query often but don’t want as full labels, a middle ground Loki added specifically to avoid the old choice between “label” and “buried in unstructured text.”
limits_config:
allow_structured_metadata: true
max_structured_metadata_size: 64KB
Third, if you’re running Loki alongside Prometheus for full observability, consider whether native histogram metrics from your Kubernetes control plane belong in the same Grafana dashboards as your Loki-derived log metrics. Correlating a spike in error-log rate with a specific latency histogram bucket is often faster than jumping between two separate query languages during an incident. If you haven’t set up trace and metric collection yet, pairing this Loki install with an OpenTelemetry collector deployment gives you all three observability pillars feeding the same Grafana instance rather than three disconnected tools.
Finally, if cost visibility across your whole cluster matters as much as log cost specifically, a tool like Kubecost can attribute the compute and storage cost of your Loki deployment itself back to the teams generating the log volume, which turns “our logging bill went up” into “team X’s debug-level logging in namespace Y went up,” a much more actionable finding.
Complete Working Project: A Production Logging Stack
Tie every step above into a single deployable project: a Helm-based logging stack with Loki, Alloy, retention, and alerting configured together, meant to be checked into your infrastructure repository rather than run by hand each time.
#!/usr/bin/env bash
set -euo pipefail
NAMESPACE=loki
BUCKET=$1
REGION=${2:-us-east-1}
echo "== Step 1: Namespace and repos =="
kubectl create namespace "$NAMESPACE" --dry-run=client -o yaml | kubectl apply -f -
helm repo add grafana https://grafana.github.io/helm-charts
helm repo add grafana-alloy https://grafana.github.io/helm-charts
helm repo update
echo "== Step 2: Render values and install Loki =="
cat < /tmp/loki-values.yaml
loki:
auth_enabled: true
storage:
type: s3
s3:
region: $REGION
bucketnames: $BUCKET
limits_config:
retention_period: 30d
allow_structured_metadata: true
deploymentMode: SimpleScalable
compactor:
retention_enabled: true
delete_request_store: s3
write:
replicas: 3
read:
replicas: 3
backend:
replicas: 3
EOF
helm upgrade --install loki grafana/loki \
--namespace "$NAMESPACE" \
--values /tmp/loki-values.yaml \
--version 18.13.5 \
--wait --timeout 10m
echo "== Step 3: Install Alloy collector =="
helm upgrade --install alloy grafana-alloy/alloy \
--namespace "$NAMESPACE" \
--wait --timeout 5m
echo "== Step 4: Apply alert rules =="
kubectl apply -f loki-alert-rules.yaml -n "$NAMESPACE"
echo "== Step 5: Validate =="
kubectl get pods -n "$NAMESPACE"
echo "Loki 3.7 logging stack deployed to namespace $NAMESPACE"
This same skeleton extends naturally if you’re already running a broader observability or service-mesh stack. Teams running Kubernetes secrets management alongside Loki should route the object storage credentials through the same secrets pipeline rather than a separate one-off, and clusters spread across EKS, AKS, or GKE can reuse this script with only the storage backend block and IAM binding swapped per cloud.
Migrating an Existing Promtail Deployment to Alloy
If you already run Loki with Promtail as the collector, you don’t have to rip it out overnight, but you should have a migration plan given where Grafana is putting its development effort. Promtail keeps working and keeps shipping logs. It just isn’t where new collector features land first anymore. The practical migration path is to run Alloy alongside Promtail on a subset of nodes first, confirm log delivery and label output match what Promtail was producing, then cut over node by node rather than all at once.
# Check existing Promtail config for scrape configs to port over
kubectl get configmap promtail-config -n loki -o yaml > promtail-config-backup.yaml
# Deploy Alloy to a labeled subset of nodes first
kubectl label nodes -l node-role.kubernetes.io/canary=true alloy-migration=true
helm upgrade --install alloy grafana-alloy/alloy \
--namespace loki \
--set alloy.nodeSelector.alloy-migration=true
Compare the label sets Alloy produces against what Promtail was sending for the same pods before rolling it out cluster-wide. Alloy’s configuration language, River (and its newer Alloy-native syntax), differs from Promtail’s YAML scrape config format, so a line-by-line config port rarely works cleanly. Treat the migration as rebuilding your collection config against Alloy’s model rather than translating Promtail’s config file directly, and validate output against a known-good set of test log lines before trusting it in production. Full configuration reference lives on the Grafana Alloy documentation.
Loki vs Other Log Aggregation Approaches
Loki isn’t the only option, and it’s worth being honest about where it fits. Against Elasticsearch and the broader ELK stack, Loki generally costs less to run at scale because it skips full-text indexing, but it also can’t do the kind of free-text, no-label-required search Elasticsearch handles natively. If your team’s actual workflow is “search for this arbitrary string across everything” more often than “filter by namespace and pod, then look at the content,” Elasticsearch’s indexing model may fit your usage pattern better despite the higher storage cost.
Against a managed SaaS logging product, self-hosted Loki trades a monthly subscription for engineering time spent on exactly the setup and tuning covered in this guide. That’s a reasonable trade for teams already running Kubernetes infrastructure and comfortable owning another Helm-deployed service, and a worse one for small teams without spare platform engineering capacity. There’s no universally correct choice here, only a tradeoff between operational ownership and monthly cost that depends on your team’s size and existing Kubernetes maturity.
| Approach | Indexing Model | Typical Cost Driver | Best Fit |
|---|---|---|---|
| Self-hosted Loki | Label metadata only, content in object storage | Object storage volume, engineering time | Kubernetes-native teams with label-friendly query patterns |
| Self-hosted Elasticsearch / ELK | Full-text index of every field | Compute and memory for indexing | Teams needing broad free-text search across fields |
| Managed SaaS logging | Varies by vendor, usually full-text | Per-GB or per-seat subscription | Teams without spare platform engineering capacity |
Sizing Your Loki Deployment for Real Log Volume
The deployment mode table earlier in this guide gives rough guidance, but real sizing depends on write throughput as much as total daily volume. A cluster producing 50GB a day spread evenly across 24 hours behaves very differently from one producing the same 50GB in a two-hour traffic spike. If your traffic is bursty, size the write path for peak ingestion rate, not the daily average, since a write path that’s only provisioned for the average will fall behind and start dropping or queuing during every spike.
Watch three metrics once you’re running real traffic: the distributor’s received-lines rate, the ingester’s chunk flush rate, and query latency on your busiest dashboards. If ingestion metrics look healthy but dashboard queries feel slow, the read path is usually under-provisioned relative to query concurrency, not the write path. If ingestion itself is falling behind, that’s a write-path or distributor capacity problem, and adding read replicas won’t fix it. Diagnosing which side of the read/write split is actually the bottleneck before scaling either one saves both compute cost and the time spent scaling the wrong component.
Frequently Asked Questions
What is the latest version of Grafana Loki?
Loki 3.7.8 is the current release as of late September 2026, published September 17, 2026, on the 3.7 branch. The 3.6 branch remains maintained in parallel, with 3.6.17 released September 9, 2026.
Which Helm chart repository should I use for Loki now?
Use the community chart, which moved to the grafana-community/helm-charts repository as of March 16, 2026. As of October 7, 2026, Artifact Hub lists the current version as 18.14.0. Grafana separately maintains a chart specifically for Grafana Enterprise Logs, which is a different product track.
Should I use Promtail or Grafana Alloy to ship logs?
Use Grafana Alloy for new installs. It’s a superset of Promtail’s log-shipping functionality and the collector Grafana is actively developing, while Promtail is in long-term maintenance mode rather than active feature development.
Which Loki deployment mode should I start with?
For anything beyond a dev or staging environment, simple scalable mode is the reasonable default: it separates read and write paths for horizontal scaling without the full operational overhead of microservices mode. Reserve microservices mode for genuinely high-volume, multi-tenant deployments where you’ve confirmed simple scalable mode’s limits are a real bottleneck, not a hypothetical one.
Is the bundled MinIO storage option safe to use in production?
No. The built-in MinIO subchart used in some Loki Helm chart configurations is deprecated and scheduled for removal on October 31, 2026, according to Grafana’s Enterprise Logs upgrade documentation. Use an external S3-compatible object store for anything beyond local testing.
Why do my Loki queries get slower over time?
The most common cause is label cardinality creep: a new deploy or workload accidentally attaching a high-cardinality value, like a request ID or timestamp, as a label rather than log content. This bloats the index Loki has to scan for every query matching that label set. Audit your label schema periodically and keep unique-per-line values out of labels entirely.
How does Loki keep storage costs lower than Elasticsearch?
Loki indexes only metadata labels rather than full log text, storing the compressed log content itself in cheap object storage like S3 or GCS. Elasticsearch indexes full text by default, which enables broader free-text search but costs significantly more in both storage and compute at comparable log volumes.
Can I run Loki without Grafana?
Loki’s query API works independently and can be queried directly with LogQL through its HTTP API, as shown in the pipeline validation step above. In practice almost every team pairs it with Grafana for dashboards and the ruler-based alerting pipeline, but nothing about Loki itself requires Grafana as a query interface.





