CodeWorlds
Back to collections
Guide18 min readCodeWorlds Team

Grafana, dashboards over data from other systems

Grafana draws dashboards over data it never stores. Release 13.2.0, an AGPL licence with Apache 2.0 directories, and a worked Grafana Cloud bill.

Grafana, dashboards over data from other systems

Grafana is a presentation layer: it queries other people's databases and draws panels, tables and alerts from the answers. It neither collects nor stores metrics, logs or traces itself. The current release is 13.2.0, the archive on the download server is dated 18 August 2026, and the server code is licensed under AGPL-3.0-only with an enumerated list of directories under Apache 2.0.

What Grafana draws and what it does not collect

Grafana is not a database. It is a server that sends a query to an external source every time you open a panel and draws the answer. Grafana's own database, an SQLite file in the data/ directory by default, optionally MySQL or PostgreSQL, holds dashboard definitions, accounts, permissions, alert rules and their state history. Time series and log lines never land in it.

Two consequences follow, and both save a lot of confusion in practice. First: you do not set data retention in Grafana. If Prometheus keeps data for fifteen days, a chart with a three month range will be empty no matter what the panel settings say. Second: a slow dashboard almost always means a slow query in the source or too wide a time range, not a problem with Grafana itself.

Starting from the archive looks like this:

Code
Bash
curl -LO https://dl.grafana.com/oss/release/grafana-13.2.0.linux-amd64.tar.gz
tar -xzf grafana-13.2.0.linux-amd64.tar.gz
cd grafana-13.2.0
./bin/grafana server

The unpacked directory holds bin/, conf/ with a defaults.ini file, data/, docs/, packaging/, plugins-bundled/, public/, tools/, and at the root LICENSE, NOTICE.md and VERSION. The rest of the stack, meaning everything that actually collects data, ships separately. The packaging/wrappers/grafana-server script is still in the archive, but it prints a warning that the grafana-server name is deprecated and will be removed in a future release, then calls bin/grafana server anyway.

The documentation for release 13.2.0 lists nineteen built-in data sources, grouped by use case. Metrics: AWS CloudWatch, Azure Monitor, Google Cloud Monitoring, Graphite, InfluxDB, OpenTSDB, Prometheus. Logs: Elasticsearch, Loki. Traces: Jaeger, Tempo, Zipkin. Profiles: Parca, Pyroscope. SQL databases: Microsoft SQL Server, MySQL, PostgreSQL. Alerting: Alertmanager. Testing: TestData. On top of that come three special sources that are not counted among the above: Grafana (random walk data and files from the installation), Mixed (several sources in one panel) and Dashboard (the result set of another panel on the same dashboard). That makes twenty two entries in the picker.

Anything missing from that list has to be installed as a plugin. ClickHouse needs the grafana-clickhouse-datasource plugin, while MongoDB and Snowflake are Enterprise plugins, available in Grafana Cloud and requiring an Enterprise licence on a self-managed instance. PostgreSQL is built in, so a panel over an application table needs nothing beyond credentials.

A full observability stack still needs at least two more pieces: something that collects data on the machine (an agent or a collector) and something that stores it (a time series database or a log store). Grafana is the third piece, not the only one.

The licence checked against three sources

Grafana's licence is the most commonly misread thing about this project, because the repository holds two licence files and the npm packages say something different from the server. The check goes like this:

Code
Bash
# 1. licence files under the release tag, not from the main branch
curl -s https://raw.githubusercontent.com/grafana/grafana/v13.2.0/LICENSE | head -2
curl -s https://raw.githubusercontent.com/grafana/grafana/v13.2.0/LICENSING.md

# 2. the license field in the package registry for the frontend libraries
curl -s https://registry.npmjs.org/@grafana/data | grep -o '"license":"[^"]*"' | head -1

# 3. the contents of the published artefact
curl -sO https://registry.npmjs.org/@grafana/data/-/data-13.2.0.tgz
tar -tzf data-13.2.0.tgz | grep -i licen

Source one. The LICENSE file under tag v13.2.0 contains the full text of the GNU Affero General Public License version 3 dated 19 November 2007 and is 34,523 bytes long. Next to it sits LICENSING.md, which opens by stating that the project's default licence is AGPL-3.0-only and then lists the directories covered by Apache 2.0: packages/grafana-data/, packages/grafana-e2e-selectors/, packages/grafana-runtime/, packages/grafana-ui/, packaging/, kinds/, pkg/kinds/, pkg/kindsys/, pkg/registry/schemas/, grafana-mixin/, public/app/features/explore/TraceView/components, public/img/icons/solid/ and public/img/icons/unicons/. The public/vendor/ directory stays under its original upstream licences, and one helper file in .github/workflows/ is MIT.

Source two. The Grafana server is a Go program and is not present in any package registry, so there is no license field for it at all. What npm does carry are the libraries that plugins compile against: @grafana/data, @grafana/ui and @grafana/runtime at version 13.2.0, all published on 18 August 2026 with a license field of Apache-2.0. That matches the list in LICENSING.md.

Source three. The @grafana/data package at version 13.2.0 weighs 1.2 MB and contains a LICENSE_APACHE2 file with the Apache 2.0 text plus the dist/cjs, dist/esm and dist/types directories, meaning actual code rather than a description of it. The server archive from dl.grafana.com carries LICENSE with the AGPL text at its root along with NOTICE.md, which opens with a Grafana Labs copyright line covering 2014 to 2021 and a note that the software derives from Kibana. The full file listing of that archive runs to 15,031 entries and holds only LICENSE, NOTICE.md, VERSION, Dockerfile and README.md at the root. There is no LICENSING.md in it at all, and no packages/ directory either, because the frontend ships already compiled in public/build. The list of Apache 2.0 exceptions is therefore available only in the repository, not in the artefact you deploy.

The licence change has a specific date. The LICENSE file under tag v7.5.7 contains Apache License 2.0, and under tag v8.0.0 it already contains AGPL. A Grafana Labs blog post dated 21 April 2021, signed by Raj Dutt, announces moving Grafana, Loki and Tempo from Apache 2.0 to AGPLv3 and states that plugins, agents and certain libraries stay on Apache. The date is 2021, not the moment when someone today describes the project as "open source under Apache"; that description is simply five years out of date.

What AGPL changes in three situations

AGPL differs from GPL by one clause, the thirteenth, which adds an obligation to make source available to users who interact with the program over a network. Splitting that into three cases answers most questions.

Case one: you use Grafana unchanged. You stand up the image or the archive, configure sources, build dashboards. You do not modify the code, so you have nothing to make available. Dashboards, alert rules and provisioning files are yours: they are input to the program, not a work derived from its code. This case covers the vast majority of deployments and carries no practical obligation.

Case two: you modify Grafana for your own needs. You add a patch, change panel behaviour, build your own image with a fix. As long as the modified version runs inside your network and your own people use it, clause thirteen requires you to offer them the source of the modified version. In practice that means the company should be able to point at the repository holding that patch. The obligation is not publication on the internet, it is availability to those who use the program.

Case three: you offer Grafana as a service to people outside your organisation. Here AGPL genuinely bites. If you host a modified Grafana for customers, you have to offer them the complete source of your version under AGPL terms, so that they can modify and redistribute it further. If you host an unmodified version, clause thirteen adds no new obligation, but distributing binaries still carries the requirement to pass on the licence and provide access to the source. This is the boundary you cannot sidestep by bolting on your own login layer: a login layer inside Grafana's code is a modification.

Plugins are a separate matter. Backend plugins run as separate processes talking to the server, and frontend plugins compile against @grafana/data, @grafana/ui and @grafana/runtime, which are exactly the directories LICENSING.md carves out of AGPL and places under Apache 2.0. That split makes closed source plugins possible. The overlap between the directory list and the list of packages plugin authors use is obvious, but the licensing document does not explain the motivation, so treat this as my reading of the arrangement rather than a quotation. It is not legal advice.

Enterprise and the rest of the Grafana Labs stack

Grafana Enterprise is a commercial edition of the same server, shipped as a separate artefact. The address dl.grafana.com/enterprise/release/grafana-enterprise-13.2.0.linux-amd64.tar.gz responds correctly, whereas fetching a LICENSE file from the grafana/grafana-enterprise repository returns 404, so the code of that edition is not public on the same terms as the OSS one.

The documentation lists what Enterprise adds: SAML authentication, team synchronisation with the identity provider, enhanced LDAP integration, roles protected from conversion when auth providers change, role-based access control, data source permissions, query and resource caching, PDF reports from a dashboard with a delivery schedule, custom branding and logo, usage insights, recorded queries, Vault integration, an audit log of instance changes, and a set of Enterprise data source plugins. Support runs 24x7x365.

The rest of the stack published by Grafana Labs also carries mixed licences, and this is where mistakes are easiest.

ProjectLicenceRole in the stack
Grafana 13.2.0AGPL-3.0-onlydashboards, alerting, exploration
LokiAGPL-3.0log store
TempoAGPL-3.0trace store
MimirAGPL-3.0metric store
PyroscopeAGPL-3.0profile store
k6AGPL-3.0 (LICENSE.md file)load testing
AlloyApache 2.0collecting and shipping data
@grafana/data, @grafana/ui, @grafana/runtimeApache 2.0libraries for plugins

Alloy is the exception here and the exception is logical: an agent gets installed on other people's machines, and a copyleft licence on the agent would put users off. Note the small detail around k6: the file is called LICENSE.md, not LICENSE, so an audit script looking for a single name will report a missing licence.

Configuration as code

Grafana reads the conf/provisioning/ directory at startup and creates the objects described there. The sample file for data sources spells the fields out:

Code
YAML
apiVersion: 1

datasources:
  - name: Prometheus
    type: prometheus
    access: proxy
    orgId: 1
    uid: prom_main
    url: http://prometheus:9090
    isDefault: true
    basicAuth: true
    basicAuthUser: grafana
    withCredentials: false
    jsonData:
      tlsAuth: false
      tlsAuthWithCACert: false
    secureJsonData:
      tlsCACert: '...'
      tlsClientCert: '...'

The name, type and access fields are required, access takes either proxy or direct, and uid is how other files refer to the source. Anything that should be encrypted in the database goes into secureJsonData, everything else into jsonData.

Alert rules have their own sample file and their own set of fields:

Code
YAML
apiVersion: 1

groups:
  - orgId: 1
    name: my_rule_group
    folder: my_first_folder
    interval: 60s
    rules:
      - uid: my_id_1
        title: my_first_rule
        condition: A
        data:
          - refId: A
            datasourceUid: "__expr__"
            model:
              expression: 1==0
              intervalMs: 1000
              maxDataPoints: 43200
              refId: A
              type: math
        dashboardUid: my_dashboard
        panelId: 123
        noDataState: Alerting
        executionErrorState: Alerting
        for: 60s
        labels:
          team: sre_team_1
        isPaused: false
        notification_settings:
          receiver: grafana-default-email
          group_by: ["alertname", "grafana_folder", "region"]

Two traps sit in this file. interval is how often the whole group is evaluated, while for is how long the condition must hold before an alert moves from Pending to Firing; mixing them up gives you alerts that are either too slow or that fire on a single reading. The second: a rule uid cannot exceed forty characters and allows only letters, digits, hyphen and underscore, so generating identifiers from service paths can quietly cross the limit. The group_by field, when set, has to contain the alertname and grafana_folder labels unless you use the special value ....

In Grafana Cloud the instance limits are visible as ordinary metrics in the grafanacloud-usage source:

Code
PROMQL
grafanacloud_instance_metrics_limits{limit_name="max_global_series_per_user"}
grafanacloud_logs_instance_limits{limit_name="ingestion_rate_mb"}
grafanacloud_traces_instance_limits{limit_name="max_bytes_per_trace"}

Default values from the documentation include ingestion_rate at 10,000 samples per second, max_global_series_per_user at 150,000 series, ingestion_rate_mb for logs at 5 MB and max_global_streams_per_user at 5,000 streams. Some of them scale automatically with consumption. These are technical instance limits, which is not the same thing as the allowance from your pricing plan.

Grafana Cloud, the free plan and a worked bill

The pricing page on the Grafana Labs site renders without JavaScript, so it could be read straight from the raw HTML. A banner at the top announces a change to the billing model, in which the company calls the current rule broken and says it is changing it, so treat the numbers below as the state on 22 August 2026 rather than a permanent table.

ItemFreeProEnterprise (Cloud)
Fixed fee0 USD19 USD per monthfrom 25,000 USD per year
Metrics included10k active series10k active seriesper contract
Logs and traces included50 GB each per month50 GB each per monthper contract
Metric retention14 days13 monthscustom
Log and trace retention14 days30 dayscustom
Users included3 active3 activeper contract
Supportcommunityemail 8x5premium

Rates above the threshold: metrics at 6.50 USD per thousand series in the 10k to 100k band, 5.90 USD in the 100k to 200k band, 5.50 USD above 200k. Logs and traces are split into three per gigabyte components: process at 0.050 USD, write at 0.400 USD and retain at 0.100 USD. A user beyond the free three costs 8.00 USD per month, and a user with access to Enterprise plugins costs 55.00 USD. The Enterprise plan takes metrics down to 3 USD per thousand series with an annual commitment.

Let us compute the bill on the Pro plan for 25k active series and 200 GB of logs per month. The fixed fee is 19.00 USD. Metrics: 25k minus the 10k included leaves 15k series above the threshold, at 6.50 USD per thousand, which is 97.50 USD. Logs: 200 GB minus the 50 GB included leaves 150 GB, and the three components sum to 0.55 USD per gigabyte, which is 82.50 USD. Together 19.00 plus 97.50 plus 82.50, that is 199.00 USD per month.

Two caveats about that arithmetic. First, the retain component is charged on data held over time, and the pricing page gives no conversion between a gigabyte ingested and a gigabyte stored for a month; the calculation above assumes they are the same number within a given month. Second, the 19 USD fee appears on the page separately under each product, with different inclusions each time. I read it as a single platform fee with separate thresholds per product, but the page does not say so explicitly, and the difference between one and several nineteens changes the bill.

Once you cross a limit on the Free plan there is no overage billing, because the plan takes no payment card. The excess is rejected by the instance limits, the same ones visible in the grafanacloud_instance_metrics_limits metrics. The pricing page describes the Free plan purely through limits and mentions no overage rate, so the cut-off follows from the absence of an alternative rather than from a separate sentence in the pricing table.

Grafana next to Sentry, Axiom, PostHog and OpenReplay

These tools often get thrown into one bucket labelled monitoring, even though they answer different questions and keep data in different places.

QuestionToolWhere the data lives
Which exception broke this request and on which lineSentrywith the vendor or self-hosted
What is in the logs from the last hourAxiomwith the vendor
How users move through the funnelPostHogwith the vendor or self-hosted
What the user saw on screen before the errorOpenReplayself-hosted or in their cloud
How all of it looks together on one screenGrafananowhere, Grafana queries other systems

The last row is the heart of the difference. Sentry, Axiom, PostHog and OpenReplay receive data and store it, so each of them is both a collector and a view. Grafana is the view alone. That is why the question "Sentry or Grafana" usually makes no sense: the first collects errors, the second can show them next to Prometheus metrics, provided somebody recorded those errors somewhere first.

For self-hosting, Grafana slots comfortably into the same setups as the rest of the tools in this collection. Panels alongside applications launched by Coolify or Dokploy come down to a single container with a volume mounted on the data/ directory and provisioning files baked into the image.

Common mistakes

First: treating Grafana as a store. The question "how do I increase retention in Grafana" has no answer, because retention is set in Prometheus, Loki or the SQL database. Grafana only remembers dashboards and alerts.

Second: a licence audit that reads only the LICENSE file. It will report AGPL for everything, including the @grafana/* packages, which are Apache 2.0. The reverse mistake is worse: checking @grafana/ui alone in the npm registry and concluding that the server is Apache too.

Third: describing Grafana as an Apache 2.0 project. That was true up to and including version 7.5. From 8.0.0 onwards AGPL applies, and that change is five years old.

Fourth: peer dependency ranges within the package family. @grafana/ui at 13.2.0 declares react at version 19 or above, while @grafana/scenes at 8.16.1, published on 20 August 2026, declares react in the ^18.0.0 range together with @grafana/ui at 11.6 or above. Putting both packages at their latest versions produces contradictory React requirements and the package manager will say so.

Fifth: pinning a version without checking whether it is deprecated. The registry carries @grafana/ui 9.3.0 marked as deprecated with a note about a broken publish, and @grafana/ui 10.3.0 with a note that the version was published by accident and does not contain the code of Grafana 10.3.0.

Sixth: confusing instance limits with the plan allowance. The default max_global_series_per_user is 150,000 series, while the free plan grants 10k active series. Those are two different numbers with different meanings, and the first does not release you from the second.

Seventh: counting on the free plan to serve a team. Three active users per month is enough for a prototype; the fourth person means moving to Pro and paying 8.00 USD for every further active user.

FAQ

Does Grafana store my metrics?

No. Grafana keeps dashboards, users, permissions and alert rules in its own database. Metrics, logs and traces stay in the sources, and Grafana queries them on every panel refresh.

Does AGPL force me to publish my dashboards?

No. Dashboards and provisioning files are input data, not Grafana's code. The obligation covers the source of a modified version of the program, and only when somebody uses that version.

Can I host Grafana for my customers?

You can, but if you host a modified version you have to offer those customers the source of your changes under AGPL terms. With an unmodified version clause thirteen adds no new obligation. Leave the ruling on your own case to a lawyer.

Do I have to release my plugin under AGPL?

The @grafana/data, @grafana/ui and @grafana/runtime packages that plugins compile against are carved out of AGPL and placed under Apache 2.0 explicitly in LICENSING.md. Backend plugins run as separate processes. Closed source plugins exist and are sold in the Enterprise edition.

What does Grafana Cloud cost once the free plan runs out?

The Pro plan is 19 USD per month plus usage: 6.50 USD per thousand metric series above 10k, 0.55 USD per gigabyte of logs across the three components, and 8.00 USD per active user above three. The example with 25k series and 200 GB of logs comes to 199.00 USD per month.

How does Grafana differ from Sentry or Axiom?

Sentry and Axiom receive data and store it, so they answer questions about errors and about logs on their own. Grafana receives nothing: it shows what sits in other systems and lets you put several sources on one screen.

The source code and both licence files are in the grafana/grafana repository, the data source documentation is in the Data sources section, and current rates are in the Grafana Cloud pricing table.

Read next

We use cookies to enhance your experience on the site