---
title: "Application Observability host-hours pricing | Grafana Cloud documentation"
description: "How Application Observability counts host hours and identifies hosts for billing."
---

> For a curated documentation index, see [llms.txt](/llms.txt). For the complete documentation index, see [llms-full.txt](/llms-full.txt).

# Application Observability host-hours pricing

Grafana Cloud Application Observability bills based on **host hours** — the total number of hours per month that each host sends application telemetry to Grafana Cloud. This pricing model applies to every customer that uses Application Observability.

- Self-Serve users on Pro and Advanced plans: The pricing model was applied on September 1, 2024.
- Contracted organizations: The pricing model is applied upon contract renewal.

Starting February 13, 2026, Application Observability introduces a new pricing model:

- **All new customers**: $0.025 per host hour plus separate charges for telemetry (metrics, traces, logs, profiles) at $0.50 per 1,000 active series (metrics) and $0.50 per GB for traces, logs, and profiles. This model does not include telemetry credits.
- **Existing customers (before February 13, 2026)**: $0.04 per host hour with included telemetry credits (1.5 active series and 0.02 GB of traces per host hour). Standard pricing applies for usage exceeding included credits.

For information about pricing and billing for Application Observability, refer to these resources:

- [Grafana Cloud Pricing for Application Observability](/pricing/#application-observability)
- [Understand your Application Observability Invoice](/docs/grafana-cloud/cost-management-and-billing/understand-your-invoice/application-observability-invoice/)

> Note
> 
> For serverless environments including Container as a Service (CaaS) and Function as a Service (FaaS) platforms (such as AWS Lambda, Google Cloud Functions, Azure Functions, and others), Application Observability uses telemetry-based billing instead of host-hours. You pay only for the telemetry (metrics, traces, logs, profiles) ingested into Grafana Cloud. Contact Grafana Support to ensure your environment is correctly configured for serverless billing.

## Definition of host

Hosts can be any of the following:

- Physical Servers: Dedicated machines that run an operating system and applications.
- Virtual Machines (VMs): Instances of operating systems running on virtualized environments, such as those managed by VMware, Hyper-V, or cloud providers like AWS EC2, Azure Virtual Machines, and so on.

## What is not a host

A container is an isolated application environment running on a host system. Containers, like those managed by Docker, are not considered hosts because they do not represent a full operating system instance.

## How Application Observability identifies hosts

Application Observability identifies hosts automatically from standard OpenTelemetry resource attributes attached to your telemetry. You don’t need to send a dedicated billing metric or enable a billing connector — host detection happens in Grafana Cloud based on attributes that Grafana Alloy, the OpenTelemetry Collector, the OpenTelemetry SDKs, and Beyla emit by default for most deployment models.

For every service, Application Observability evaluates the following resource attributes in priority order and uses the **first match** as the host’s billing identifier — you only need to satisfy one tier, not all three:

Expand table

| Priority | Attributes                                 | Typical environment                                          |
|----------|--------------------------------------------|--------------------------------------------------------------|
| 1        | `k8s.node.name`                            | Kubernetes workloads                                         |
| 2        | `host.name` together with `cloud.provider` | Cloud VMs (AWS, GCP, Azure)                                  |
| 3        | `grafana.host.id`                          | Last-resort fallback — bare metal, Docker, on-premises, etc. |

Priorities 1 and 2 are emitted out of the box by most Grafana-recommended setups. Priority 3 (`grafana.host.id`) is **not** emitted automatically by any tool — it’s an explicit opt-in attribute that you set deliberately when neither priority 1 nor priority 2 is available in your environment.

If none of these attributes are present on a service’s telemetry, the service is not counted for host-hours billing and Application Observability surfaces a configuration warning. This is the safe failure mode — services without a verifiable host identifier are excluded rather than billed under an unreliable key.

### Make sure your hosts are identified

Confirm one of the priority tiers is satisfied for each environment that sends telemetry to Application Observability. Start with priority 1 if you run on Kubernetes, priority 2 if you run on cloud VMs, and only fall back to priority 3 when neither applies.

#### Priority 1: `k8s.node.name` (Kubernetes)

Run the [`k8sattributes` processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/k8sattributesprocessor) on your collector or gateway so it stamps `k8s.node.name` on incoming telemetry. The Grafana Cloud Kubernetes Monitoring Helm chart configures this for you. Beyla emits `k8s.node.name` natively on Kubernetes — no additional configuration is needed.

If you instrument applications with the OpenTelemetry SDK directly (no collector in the path), inject `k8s.node.name` via the [Downward API](https://kubernetes.io/docs/concepts/workloads/pods/downward-api/):

YAML ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```yaml
spec:
  containers:
    - name: app
      env:
        - name: K8S_NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: OTEL_RESOURCE_ATTRIBUTES
          value: "k8s.node.name=$(K8S_NODE_NAME)"
```

Without this, `host.name` resolves to the pod name and every pod is counted as a separate host.

#### Priority 2: `host.name` and `cloud.provider` (cloud VMs)

On cloud VMs (AWS, GCP, Azure), enable the cloud-specific [resource detector](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/resourcedetectionprocessor) on your collector agent. It queries the cloud Instance Metadata Service (IMDS) and sets both `host.name` and `cloud.provider`:

Grafana AlloyOpenTelemetry Collector

Grafana Alloy OpenTelemetry Collector

Alloy ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```alloy
// Substitute ec2 with gcp or azure as appropriate
otelcol.processor.resourcedetection "default" {
  detectors = ["env", "ec2"]

  ec2 {
    resource_attributes {
      host.name      { enabled = true }
      cloud.provider { enabled = true }
      cloud.platform { enabled = true }
    }
  }

  // output: wire to your next component
  output {}
}
```

YAML ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```yaml
# AWS EC2 — substitute gcp or azure as appropriate
processors:
  resourcedetection:
    detectors: [env, ec2]
    override: true
    ec2:
      resource_attributes:
        host.name: {enabled: true}
        cloud.provider: {enabled: true}
        cloud.platform: {enabled: true}
# Add resourcedetection to service.pipelines processors
```

Beyla detects these attributes natively on cloud VMs — no additional configuration is needed.

#### Priority 3: `grafana.host.id` (last-resort fallback)

`grafana.host.id` is the last-resort identifier. Only set it when neither priority 1 nor priority 2 is available — typically on bare metal, in Docker on hardware you manage, or in on-premises Kubernetes deployments where `k8sattributes` and a cloud resource detector are both absent. Unlike priorities 1 and 2, no tool emits `grafana.host.id` automatically; you must set it deliberately on your collector.

##### Bare metal

Set `grafana.host.id` on your collector agent by copying `host.name` into it. This gives the host a stable, explicit identifier.

> Note
> 
> The `host.name` value should be stable (persist across reboots), unique (different for each physical/virtual host), and meaningful (helps identify the host in your infrastructure). The system hostname typically satisfies these requirements.

Grafana AlloyOpenTelemetry Collector

Grafana Alloy OpenTelemetry Collector

Alloy ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```alloy
otelcol.processor.resourcedetection "default" {
  detectors = ["env", "system"]

  system {
    hostname_sources = ["dns", "os"]

    resource_attributes {
      host.name { enabled = true }
    }
  }

  output {
    traces  = [otelcol.processor.transform.add_host_id.input]
    metrics = [otelcol.processor.transform.add_host_id.input]
    logs    = [otelcol.processor.transform.add_host_id.input]
  }
}

otelcol.processor.transform "add_host_id" {
  error_mode = "ignore"

  trace_statements {
    context    = "resource"
    statements = [`set(attributes["grafana.host.id"], attributes["host.name"])`]
  }

  metric_statements {
    context    = "resource"
    statements = [`set(attributes["grafana.host.id"], attributes["host.name"])`]
  }

  log_statements {
    context    = "resource"
    statements = [`set(attributes["grafana.host.id"], attributes["host.name"])`]
  }

  // output: wire to your next component
  output {}
}
```

YAML ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```yaml
processors:
  resourcedetection:
    detectors: [env, system]
    system:
      hostname_sources: [dns, os]
      resource_attributes:
        host.name: {enabled: true}
  resource:
    attributes:
      - key: grafana.host.id
        from_attribute: host.name
        action: insert
# Add resourcedetection and resource to service.pipelines processors
```

##### Docker

Set `OTEL_RESOURCE_ATTRIBUTES` to inject the host identifier. Replace `my-server-hostname` with your host’s actual identifier:

DockerDocker Compose

Docker Docker Compose

Bash ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```bash
# Static value
docker run -e OTEL_RESOURCE_ATTRIBUTES="grafana.host.id=prod-web-01" ...

# Or use dynamic hostname
docker run -e OTEL_RESOURCE_ATTRIBUTES="grafana.host.id=$(hostname)" ...
```

YAML ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```yaml
services:
  collector:
    environment:
      # Replace with your host's actual identifier
      OTEL_RESOURCE_ATTRIBUTES: "grafana.host.id=prod-web-01"
```

Then configure your collector to read it:

Grafana AlloyOpenTelemetry Collector

Grafana Alloy OpenTelemetry Collector

Alloy ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```alloy
otelcol.processor.resourcedetection "default" {
  detectors = ["env"]

  // output: wire to your next component
  output {}
}
```

YAML ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```yaml
processors:
  resourcedetection:
    detectors: [env]
# Add resourcedetection to service.pipelines processors
```

### Passthrough gateway

If you run an OpenTelemetry Collector as a passthrough gateway in front of a collector agent that has already set host attributes, set `override: false` on the gateway’s `resourcedetection` processor. The default of `true` causes the gateway to silently overwrite the agent’s host attributes with its own identity, which leads to over-counting:

Grafana AlloyOpenTelemetry Collector

Grafana Alloy OpenTelemetry Collector

Alloy ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```alloy
otelcol.processor.resourcedetection "default" {
  detectors = ["env"]
  override  = false

  // output: wire to your next component
  output {}
}
```

YAML ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```yaml
processors:
  resourcedetection:
    detectors: [env]
    override: false
# Add resourcedetection to service.pipelines processors
```

## The `traces_host_info` metric

The `traces_host_info` metric is no longer required for host-hours billing. If your collectors still emit it — for example, via the `host_info` connector in Grafana Alloy or the `grafanacloud` connector in the OpenTelemetry Collector — your bill is unaffected. You can leave the connector in place or remove it at your convenience.

## Host identification notification

If Application Observability can’t identify a host for one or more of your services, the system displays a notification. To resolve it, follow the [host identification checklist](#make-sure-your-hosts-are-identified) for your environment.

If you don’t plan to use Application Observability any longer, [read how to disable it to avoid charges](#disable-application-observability-in-grafana-cloud).

## Disable Application Observability in Grafana Cloud

If you don’t want to use Application Observability in Grafana Cloud or incur billing, you can disable it.

> Caution
> 
> If you follow these steps, you lose the visibility provided by Grafana Cloud Application Observability.

1. Select **Configuration** under **Application** in the left navigation of your Grafana Cloud instance.
2. Click the **System** tab.
3. Under **Deactivate Application Observability**, click **Deactivate**.
