Backup & Restore Grafana on Windows
Complete backup strategy for Grafana on Windows — what to back up, automated PowerShell scripts, scheduled Task Scheduler jobs, restore procedures and database migration guidance.
What to back up
A complete Grafana backup on Windows requires three components:
Data directory
...\grafana\data\ — contains the SQLite database (grafana.db) with all dashboards, users, data sources, alerts and plugins.
Configuration file
...\grafana\conf\grafana.ini — all your custom settings including port, auth, SMTP and paths.
Provisioning (if used)
...\grafana\conf\provisioning\ — dashboard JSON files and data source YAML files if you use Infrastructure as Code provisioning.
Manual backup (one-time)
# Stop the Grafana service (important — prevents DB corruption)
Stop-Service -Name "Grafana" -Force
# Create timestamped backup directory
$timestamp = Get-Date -Format "yyyyMMdd-HHmm"
$dest = "C:\Backups\Grafana\grafana-$timestamp"
New-Item -ItemType Directory -Path $dest -Force | Out-Null
# Copy data directory
Copy-Item -Path "C:\Program Files\GrafanaLabs\grafana\data" `
-Destination "$dest\data" -Recurse
# Copy config
Copy-Item -Path "C:\Program Files\GrafanaLabs\grafana\conf\grafana.ini" `
-Destination "$dest\grafana.ini"
# Copy provisioning if it exists
$provPath = "C:\Program Files\GrafanaLabs\grafana\conf\provisioning"
if (Test-Path $provPath) {
Copy-Item -Path $provPath -Destination "$dest\provisioning" -Recurse
}
# Restart service
Start-Service -Name "Grafana"
Write-Host "Backup complete: $dest"Automated backup script
Save as C:\Scripts\grafana-backup.ps1 and schedule it with Task Scheduler.
#Requires -RunAsAdministrator
# grafana-backup.ps1 — Automated Grafana backup for Windows
param(
[string]$GrafanaPath = "C:\Program Files\GrafanaLabs\grafana",
[string]$BackupRoot = "C:\Backups\Grafana",
[int] $RetainDays = 30
)
$timestamp = Get-Date -Format "yyyyMMdd-HHmm"
$dest = "$BackupRoot\grafana-$timestamp"
try {
# Stop service
Stop-Service -Name "Grafana" -Force -ErrorAction Stop
Write-Host "Service stopped"
# Create backup directory
New-Item -ItemType Directory -Path $dest -Force | Out-Null
# Backup data directory
Copy-Item "$GrafanaPath\data" "$dest\data" -Recurse
Write-Host "Data directory backed up"
# Backup config
Copy-Item "$GrafanaPath\conf\grafana.ini" "$dest\grafana.ini"
# Backup provisioning
if (Test-Path "$GrafanaPath\conf\provisioning") {
Copy-Item "$GrafanaPath\conf\provisioning" "$dest\provisioning" -Recurse
}
# Compress backup
Compress-Archive -Path $dest -DestinationPath "$dest.zip" -Force
Remove-Item $dest -Recurse -Force
Write-Host "Backup compressed: $dest.zip"
# Remove old backups
Get-ChildItem $BackupRoot -Filter "*.zip" |
Where-Object { $_.CreationTime -lt (Get-Date).AddDays(-$RetainDays) } |
Remove-Item -Force
Write-Host "Old backups cleaned up"
} finally {
# Always restart service
Start-Service -Name "Grafana"
Write-Host "Service restarted"
}Schedule with Windows Task Scheduler
# Register a daily backup task at 2:00 AM
$action = New-ScheduledTaskAction `
-Execute "powershell.exe" `
-Argument "-NonInteractive -ExecutionPolicy Bypass -File C:\Scripts\grafana-backup.ps1"
$trigger = New-ScheduledTaskTrigger -Daily -At "02:00"
$principal = New-ScheduledTaskPrincipal `
-UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest
Register-ScheduledTask `
-TaskName "Grafana Daily Backup" `
-Action $action `
-Trigger $trigger `
-Principal $principal `
-Description "Daily Grafana backup"Restore procedure
Stop the service
Stop-Service -Name "Grafana" -ForceExtract the backup
Expand-Archive -Path "C:\Backups\Grafana\grafana-20260608-0200.zip" -DestinationPath "C:\Restore" -ForceRestore data directory
Remove-Item "C:\Program Files\GrafanaLabs\grafana\data" -Recurse -Force
Copy-Item "C:\Restore\grafana-20260608-0200\data" `
"C:\Program Files\GrafanaLabs\grafana\data" -RecurseRestore config
Copy-Item "C:\Restore\grafana-20260608-0200\grafana.ini" `
"C:\Program Files\GrafanaLabs\grafana\conf\grafana.ini"Start the service and verify
Start-Service -Name "Grafana"
Start-Sleep 5
Invoke-WebRequest "http://localhost:3000" -UseBasicParsingExport dashboards as JSON (lightweight backup)
For dashboard-only backups without stopping the service, export dashboards via the Grafana API:
# Export all dashboards via API
$headers = @{ Authorization = "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("admin:admin")) }
$dashboards = (Invoke-RestMethod "http://localhost:3000/api/search?type=dash-db" -Headers $headers)
foreach ($dash in $dashboards) {
$uid = $dash.uid
$title = $dash.title -replace '[\/:*?"<>|]', '_'
$json = Invoke-RestMethod "http://localhost:3000/api/dashboards/uid/$uid" -Headers $headers
$json | ConvertTo-Json -Depth 20 | Out-File "C:\Backups\Dashboards\$title.json"
}
Write-Host "Exported $($dashboards.Count) dashboards"