# Clean up stale and duplicate Grafana dashboards in one place

> See every dashboard across every folder, spot the stale ones, the clones and the broken ones, then retag, move or retire them without hunting.

- Workflow type: app
- Services: Grafana, Linear
- Categories: Engineering, Operations
- Published: 2026-08-24

## What it does

- Builds one searchable table of every dashboard in your Grafana instance, showing which folder it lives in, its tags, when it was last edited, who edited it, and how many times it has been saved.
- Filters down to the problem cases in a click: dashboards nobody has touched in six months, dashboards with no tags at all, and near-identical titles that suggest someone copied a dashboard instead of reusing one.
- Opens any dashboard in a side panel with its full edit history, a comparison of the last two changes, and a warning when a chart points at a data connection that no longer exists.
- Gives you a Review button on every row that hands the dashboard to a background assistant, which reads it end to end and writes back a short verdict: keep it, retag it, merge it into a sibling, or retire it.

## What you'll need

- A Grafana account, either Grafana Cloud or your own hosted instance, with permission to view and edit dashboards
- A Linear workspace, if you want to file cleanup tickets straight from the app
- A rough sense of who owns which folder, so cleanup decisions land with the right people

## Prompt

I want an app for cleaning up Grafana dashboard sprawl. The main view is an inventory table of every dashboard across all folders, one row per dashboard, with columns for title, folder, tags, last updated, who last edited it, and how many saved versions it has.

Build the inventory from Grafana's Search Dashboards and Folders to enumerate dashboards, and List Folders to resolve folder names and populate the folder filter. Enrich each row with Get Dashboard by UID so you have the current version number, the updated timestamp, and the last editor. Get version counts from List Dashboard Versions, either lazily per row or in a background pass. Cache the enriched inventory so the table loads fast when I reopen the app, with a Refresh button that rebuilds it.

Above the table put filters and quick chips for the three sprawl patterns I care about: dashboards nobody has touched in six months (make the window configurable), dashboards with no tags at all, and near-duplicate titles that suggest someone cloned a dashboard instead of using a template variable. Detect near-duplicates by normalizing titles, so lowercase them, strip punctuation, and strip trailing numbers and environment or region suffixes like prod, staging, or us-east-1, then group rows whose normalized titles match or are very close. Show the group size on the row so I can see at a glance that a dashboard is one of six similar ones. Also let me filter by folder and by tag, and sort by last updated and by version count.

Clicking a row opens a detail panel. It pulls the full dashboard with Get Dashboard by UID and shows the panel list and template variables, shows the edit history from List Dashboard Versions with who changed what and when, and diffs the last two versions with Compare Dashboard Versions so I can tell whether recent activity was a real change or a cosmetic save. The panel also cross-references every data source referenced anywhere in the dashboard JSON, including panel targets, template variables, and annotations, against List Data Sources, and flags any panel pointing at a data source that no longer exists. That is the fastest signal that a dashboard is actively broken, so surface it as a badge on the inventory row too.

From a row or from the detail panel I can act. Retag a dashboard or move it into a different folder with Update Dashboard, keeping the rest of the dashboard JSON intact and preserving the version so I do not clobber someone else's edit. Delete a dead dashboard with Delete Dashboard by UID, always behind an explicit confirmation step that names the dashboard and its folder and requires a second deliberate click. File a cleanup ticket in Linear with Create Issue, prefilled with the dashboard title, folder, last edited date, the reason it was flagged, and a link back to the dashboard, assigned to the last editor when their Grafana identity matches a Linear user and left unassigned with the editor named in the description when it does not. Let me pick the Linear team once in settings and reuse it for every ticket.

Add a Review this dashboard button on every row that kicks off a background agent. The agent reads the dashboard JSON with Get Dashboard by UID, walks the history with List Dashboard Versions and Compare Dashboard Versions, checks the referenced data sources against List Data Sources, and looks at the other dashboards in its near-duplicate group. It decides whether the dashboard is stale, a redundant clone, actively broken, or healthy and worth keeping, then writes back a short verdict with a recommended action, one of keep, retag, merge into a named sibling, or retire, plus a one-line reason. Store the verdict against the dashboard UID with the time of the review so it renders as a badge and tooltip on the row, let me re-run a review later, and let me select a batch of rows and kick off reviews for all of them with the rows updating as each verdict lands.

The people using this are the platform or observability owners doing a periodic cleanup pass, so optimize for working through a long list. Keep the table dense and scannable, remember my filter state between visits, show a running count of how many dashboards fall into each flagged category, and make deletion clearly the last resort next to retagging, moving, and filing a ticket.

## How to customize

- Change the staleness window from six months to whatever your team treats as dead.
- Adjust how closely two titles have to match before the app flags them as clones, and add the naming suffixes your team uses so they get ignored.
- Choose which Linear team cleanup tickets go to, and set a default label or priority for them.

## FAQ

### Will this delete dashboards automatically?

No. Nothing is ever removed on its own. Deleting is a manual action on a single dashboard, and it sits behind a confirmation step that names the dashboard and the folder it lives in before anything happens.

### Does it work with Grafana Cloud and self-hosted Grafana?

Both. You connect it with the same kind of access you would grant any other tool from Grafana's admin settings, and the app works the same way against a hosted stack or your own server.

### How does it decide two dashboards are duplicates?

It compares titles after stripping out the noise, things like punctuation, trailing numbers, and environment or region suffixes, then groups the ones that look the same. The Review button goes further and compares the actual contents before calling something a clone.

### Can I use it without Linear?

Yes. The inventory, the filters, the detail panel, the retagging and the review verdicts all work on their own. Linear only comes in when you want to hand a cleanup task to someone else as a ticket.

### Does the review assistant change my dashboards?

No. It only reads the dashboard and its history, then writes a short written verdict back into the app so it shows on the row. Any actual change, retagging, moving, or retiring, is still something you click.

Use this prompt in General Input: https://www.generalinput.com/prompts/clean-up-stale-and-duplicate-grafana-dashboards-in-one-place