Grafana
Dashboards and alerting on top of data you already store, AGPLv3 since 2021
Grafana queries data sources you already run, Prometheus, InfluxDB, Loki, PostgreSQL, MySQL and dozens more, and renders dashboards and alert rules against them. It stores dashboards, users and alert state, but no metrics of its own.
Our verdict on Grafana#
Grafana is never the answer on its own. With no data source configured it is an empty shell, so budget for Prometheus, InfluxDB or Loki underneath it and count that RAM too. The licence is AGPLv3, not Apache, since April 2021; the current release is 13.2.1 from September 2026. What Enterprise gates is worth knowing before you build a workflow around it: SAML, role-based access control, data source permissions, query caching, reporting and scheduled PDF export, usage insights, recorded queries, and around 40 commercial data source plugins including Splunk, Snowflake, ServiceNow and Datadog. Everything a single operator needs is in the free build, including unified alerting and OIDC login. The upgrade to watch has already happened: Grafana 12 removed AngularJS entirely in May 2025, so old community panel plugins simply stop rendering. Check your plugin list before jumping majors.
Who Grafana is for#
Choose it if
- Anyone already running Prometheus or InfluxDB who wants one screen instead of nine PromQL tabs
- A homelabber who wants a wall display of temperatures, power draw and disk health in one place
- Someone consolidating alerts from several data sources into one notification policy
- Small teams who need shared dashboards with OIDC login and no per-seat billing
Look elsewhere if
- You have no time series database and no intention of running one; Grafana stores nothing to graph
- You want out-of-the-box monitoring: this is a query and display layer, and dashboards are your job
- You need SAML, reporting or per-team data source permissions without paying for Enterprise
What running it actually looks like#
One container, port 3000, one volume at /var/lib/grafana. First login is admin/admin with a forced change, or set GF_SECURITY_ADMIN_PASSWORD before the first start, since it is ignored afterwards. The container runs as uid 472, so a bind mounted host directory fails with permission errors until you chown 472:472 it; a named Docker volume avoids the whole problem. Provisioning is the part worth doing properly: YAML files under /etc/grafana/provisioning/datasources and /dashboards let Grafana rebuild data sources and dashboards from disk on start, which makes the database close to disposable. Plugins need either outbound internet at start via GF_INSTALL_PLUGINS or a pre-baked image. Both an OSS image and an Enterprise image are published; the Enterprise build runs with free features until you add a licence.
Resource profile#
- Memory
- 150 MB idle, around 400 MB in ordinary use. Docs state 512 MB as the evaluation minimum and 2 to 4 GB for their small tier. A single-household instance with a dozen dashboards sits far below that unless alert rules are numerous.
- CPU and acceleration
- Idle until someone opens a dashboard, then it is proportional to panels times query cost on the data source. Alert rule evaluation and the image renderer plugin are the two things that make it spike unattended.
- Storage growth
- `grafana.db` stays in the tens of MB. What grows is dashboard version history and the annotation table, both of which have configurable maximum ages worth setting if alerting is busy.
- Operational load
- 2 of 5, Light. One container, one file to back up, and in-place upgrades inside a major version are uneventful. It is not a 1 because schema migrations run automatically on start and cannot be reversed, and because each major version has removed something people depended on.
Figures describe a small single-household install and are the working assumptions behind our stack planner. Your numbers will differ with library size, user count and hardware. See methodology.
Data and backup surface#
/var/lib/grafana holds grafana.db (SQLite), installed plugins, and rendered PNGs. The database contains dashboards, users, API keys, alert rules and the encrypted data source credentials, which are encrypted with secret_key from the config: back that up too or restored data sources will not authenticate. SQLite means a live file copy can be torn; stop the container or use sqlite3 grafana.db ".backup". Plugins and PNGs are regenerable. The better pattern is provisioning dashboards from JSON in git, which leaves only users and alert state in the database.
Derived backup shape
SQLite backup. sqlite3 <db> ".backup out.db" while running, or stop the container and copy. A live cp of a WAL-mode SQLite file can restore corrupt.
Traps and surprises#
Bind mounts fail because the container is uid 472
The Docker image runs as user 472, not root, so -v ./grafana:/var/lib/grafana on a fresh host produces permission denied on first boot and an immediate exit. Either chown -R 472:472 the host directory, run with user: '472', or use a named volume. The same applies after restoring a backup as root: fix ownership before starting the container.
Angular plugins stopped working in Grafana 12
AngularJS was deprecated in Grafana 9, disabled by default in 11 with an angular_support_enabled escape hatch, and removed outright in Grafana 12 in May 2025. Any community panel that never got a React rewrite renders as an error, and core Angular panels were force migrated. Inventory your installed plugins on the old version before upgrading a major, because there is no toggle to put it back.
Database migrations are one way
Grafana runs schema migrations automatically on start and offers no downgrade. If you upgrade the image and hate the result, reverting the tag against the migrated database usually fails to start or behaves strangely. Copy grafana.db before every major upgrade, and treat the pair (image tag, database) as one unit when you roll back.
SQLite is no longer recommended for production
The installation docs now say SQLite works for local development and small evaluation instances but does not scale for production workloads. In practice the pain shows up as database is locked under busy unified alerting, not under dashboard use. A single-household instance is fine; if you have hundreds of alert rules or several people editing at once, move to PostgreSQL before the errors start.
Free build, Enterprise image
Grafana Labs publishes both an OSS image and an Enterprise image, and the Enterprise build runs happily with only free features until a licence is applied. That is convenient and confusing: the two are not the same binary or the same licence, and only the OSS build is AGPLv3. If licence compliance matters to you, pin the OSS image explicitly rather than accepting whatever a tutorial pasted.
Specifications#
- Category
- Monitoring and observability
- Licence
- AGPL-3.0-only (Copyleft)
- Written in
- Go / TypeScript
- First release
- 2014
- Maturity
- Mature
- Datastore
- SQLite 3 by default, MySQL 8.0+ or PostgreSQL 12+ supported
- Default ports
3000- Ships as
- docker, deb/rpm package, native binary, helm chart
- arm64 builds
- Yes
- Identity
- Native OIDC. Generic OAuth2 and OIDC plus named providers (Google, GitHub, Azure AD, Okta, Keycloak) are in the free build; SAML, LDAP team sync and role-based access control are Enterprise.
- Replaces
- Datadog, Kibana, New Relic, Amazon CloudWatch dashboards
- Project site
- grafana.com/oss/grafana
- Source
- github.com/grafana/grafana
- Documentation
- grafana.com/docs/grafana/latest
Alternatives to Grafana#
Everything else in monitoring and observability, closest in operational weight first.
| Tool | Ops load | Idle RAM | Licence |
|---|---|---|---|
| Netdata | 2, Light | 150 MB | GPL-3.0-or-later (agent); dashboard UI under NCUL1 |
| Uptime Kuma | 2, Light | 120 MB | MIT |
| Beszel | 1, Set and forget | 40 MB | MIT |
| Dozzle | 1, Set and forget | 15 MB | MIT |
| Gatus | 1, Set and forget | 25 MB | Apache-2.0 |
| Prometheus | 3, Moderate | 150 MB | Apache-2.0 |
Where Grafana comes up elsewhere#
Guides
Sources#
Facts on this page were checked against the project's own material. Where a number is our own estimate rather than a published figure, the text says so.
Published . Last reviewed . Found something out of date? Tell us and we will fix it and log the change.