Skip to main content
Playlists automatically cycle through a list of dashboards at a specified interval, perfect for TV displays, monitoring walls, or presentations.

What are Playlists?

A playlist is an ordered collection of dashboards that rotate automatically:
  • Automated rotation: Cycle through dashboards at a fixed interval
  • Flexible composition: Add dashboards individually or by tag
  • Display modes: Normal, kiosk, or TV mode
  • Customizable intervals: Set rotation speed (e.g., 5m, 30s)
Playlists preserve query parameters like kiosk, orgId, and dashboard-specific settings across rotations.

Creating Playlists

Via the UI

  1. Navigate to DashboardsPlaylists
  2. Click New playlist
  3. Configure playlist:
    • Name: Descriptive title
    • Interval: Rotation interval (e.g., 5m, 30s, 1h)
  4. Add dashboards:
    • By title: Search and select individual dashboards
    • By tag: Include all dashboards with specific tags
  5. Reorder dashboards by dragging
  6. Save the playlist

Via the API

curl -X POST \
  'http://localhost:3000/api/playlist/v1/playlists' \
  -H 'Content-Type: application/json' \
  -d '{
    "playlist": {
      "metadata": {
        "generateName": "prod-"  // Server generates unique name
      },
      "spec": {
        "title": "Production Monitoring",
        "interval": "5m",
        "items": [
          {
            "type": "dashboard_by_uid",
            "value": "dashboard-uid-1"
          },
          {
            "type": "dashboard_by_uid",
            "value": "dashboard-uid-2"
          },
          {
            "type": "dashboard_by_tag",
            "value": "production"
          }
        ]
      }
    }
  }'

TypeScript Interface

import { Playlist, PlaylistSpec } from 'app/api/clients/playlist/v1';

interface Playlist {
  metadata?: {
    name?: string;              // Unique identifier (generated if not provided)
    generateName?: string;      // Prefix for auto-generated name
    namespace?: string;
    resourceVersion?: string;
    creationTimestamp?: string;
  };
  spec?: PlaylistSpec;
}

interface PlaylistSpec {
  title: string;                // Display name
  interval: string;             // Duration (e.g., "5m", "30s")
  items: PlaylistItem[];        // Dashboards to include
}

interface PlaylistItem {
  type: 'dashboard_by_uid' | 'dashboard_by_tag';
  value: string;                // Dashboard UID or tag name
}

Playlist Items

Dashboard by UID

Add specific dashboards:
{
  type: 'dashboard_by_uid',
  value: 'abc123'  // Dashboard UID
}

Dashboard by Tag

Include all dashboards with a tag:
{
  type: 'dashboard_by_tag',
  value: 'production'  // Tag name
}
Tag-based items dynamically include dashboards. Adding/removing tags from dashboards automatically updates the playlist.

Item Order

Dashboards play in the order they appear in the items array. When using tags, dashboards are sorted alphabetically.

Playlist Intervals

Intervals use Grafana’s duration format:
  • Seconds: 30s, 45s
  • Minutes: 1m, 5m, 15m
  • Hours: 1h, 2h
import { rangeUtil } from '@grafana/data';

// Convert interval string to milliseconds
const intervalMs = rangeUtil.intervalToMs('5m');  // 300000
Very short intervals (< 10s) may cause performance issues if dashboards are complex or queries are slow.

Starting a Playlist

Start Modal

From the playlists page, click Start playlist to configure:
  • Mode: Normal or Kiosk
  • Autofit panels: Adjust panel heights to screen
  • Hide logo: Remove branding (kiosk mode only)
  • Display controls: Toggle time picker, variables, links
interface StartModalOptions {
  mode: boolean;                    // false = normal, true = kiosk
  autoFit: boolean;
  hideLogo: boolean;                // Kiosk mode only
  displayTimePicker: boolean;
  displayVariables: boolean;
  displayLinks: boolean;
}

Direct URL

Start a playlist directly via URL:
/playlists/play/{playlist-name}?kiosk=true&autofitpanels=true
Supported query parameters:
  • kiosk: true for kiosk mode, tv for TV mode (deprecated)
  • autofitpanels: true to fit panels to screen
  • hideLogo: 1 to hide branding (kiosk mode)
  • _dash.hideTimePicker: true to hide time picker
  • _dash.hideVariables: true to hide variables
  • _dash.hideLinks: true to hide dashboard links

Programmatic Start

import { playlistSrv } from 'app/features/playlist/PlaylistSrv';
import { useGetPlaylistQuery } from 'app/api/clients/playlist/v1';

const { data: playlist } = useGetPlaylistQuery({ name: 'playlist-uid' });

if (playlist) {
  await playlistSrv.start(playlist);
}

Playlist Modes

Normal Mode

Standard Grafana UI with navigation:
  • Top navigation bar visible
  • Side menu accessible
  • Full dashboard controls
  • User can navigate away

Kiosk Mode

Clean display with minimal UI:
  • No navigation bars
  • No side menu
  • Optional time picker and variables
  • Press Esc or click settings icon to exit
Perfect for public displays and monitoring walls.

TV Mode (Deprecated)

Legacy mode, use kiosk mode instead:
// Old: TV mode
locationService.push('/playlists/play/abc123?kiosk=tv');

// New: Kiosk mode
locationService.push('/playlists/play/abc123?kiosk=true');

Controlling Playback

While a playlist is playing:
  • Next: Skip to next dashboard (programmatically: playlistSrv.next())
  • Previous: Go to previous dashboard (playlistSrv.prev())
  • Stop: Exit playlist (playlistSrv.stop())

Auto-reload

Every 3 loops, the playlist performs a full page reload to prevent memory leaks:
// From PlaylistSrv.ts:64
if (this.numberOfLoops >= 3) {
  window.location.href = this.startUrl;  // Full reload
  return;
}

Preserved Parameters

These query parameters persist across dashboard transitions:
const queryParamsToPreserve = {
  kiosk: true,
  autofitpanels: true,
  orgId: true,
  hideLogo: true,
  '_dash.hideTimePicker': true,
  '_dash.hideVariables': true,
  '_dash.hideLinks': true,
};

Managing Playlists

List Playlists

curl 'http://localhost:3000/api/playlist/v1/playlists'

Get Playlist

curl 'http://localhost:3000/api/playlist/v1/playlists/{name}'

Update Playlist

curl -X PUT \
  'http://localhost:3000/api/playlist/v1/playlists/{name}' \
  -H 'Content-Type: application/json' \
  -d '{
    "playlist": {
      "metadata": {
        "name": "playlist-uid",
        "resourceVersion": "123"  // For optimistic locking
      },
      "spec": {
        "title": "Updated Title",
        "interval": "10m",
        "items": [ /* updated items */ ]
      }
    }
  }'

Delete Playlist

curl -X DELETE 'http://localhost:3000/api/playlist/v1/playlists/{name}'

Sharing Playlists

Share playlists via URL:
https://grafana.example.com/playlists/play/playlist-uid?kiosk=true

Embedded in iframe

<iframe
  src="https://grafana.example.com/playlists/play/playlist-uid?kiosk=true&autofitpanels=true"
  width="1920"
  height="1080"
  frameborder="0">
</iframe>

URL Builder

import { urlUtil } from '@grafana/data';
import { config } from '@grafana/runtime';

const playlistUrl = urlUtil.renderUrl(
  `/playlists/play/${playlistName}`,
  {
    kiosk: true,
    autofitpanels: true,
    hideLogo: '1'
  }
);

const fullUrl = `${config.appUrl}${playlistUrl}`;

Use Cases

Rotate through operational dashboards on large displays:
{
  title: 'NOC Overview',
  interval: '30s',
  items: [
    { type: 'dashboard_by_tag', value: 'noc' },
    { type: 'dashboard_by_tag', value: 'incidents' }
  ]
}
Start in kiosk mode with autofitpanels for wall displays.
Show high-level metrics to leadership:
{
  title: 'Executive Overview',
  interval: '5m',
  items: [
    { type: 'dashboard_by_uid', value: 'revenue-metrics' },
    { type: 'dashboard_by_uid', value: 'user-growth' },
    { type: 'dashboard_by_uid', value: 'system-health' }
  ]
}
Cycle through team dashboards during meetings:
{
  title: 'Team Standup',
  interval: '2m',
  items: [
    { type: 'dashboard_by_tag', value: 'team-api' },
    { type: 'dashboard_by_uid', value: 'sprint-progress' }
  ]
}
Rotate through production, staging, and dev:
{
  title: 'All Environments',
  interval: '1m',
  items: [
    { type: 'dashboard_by_tag', value: 'prod-overview' },
    { type: 'dashboard_by_tag', value: 'staging-overview' },
    { type: 'dashboard_by_tag', value: 'dev-overview' }
  ]
}

Best Practices

Playlists are only as fast as the slowest dashboard:
  • Limit the number of panels per dashboard
  • Use reasonable time ranges (avoid querying years of data)
  • Optimize queries and use caching
  • Test rotation speed with actual query load
  • Fast rotation (15-30s): Simple dashboards, quick overview
  • Medium rotation (1-5m): Detailed dashboards, monitoring walls
  • Slow rotation (10m+): Complex analytics, executive displays
Match interval to dashboard complexity.
Use tag-based items for maintainable playlists:
items: [
  { type: 'dashboard_by_tag', value: 'production' },
  { type: 'dashboard_by_tag', value: 'critical-alerts' }
]
Adding/removing tags from dashboards automatically updates the playlist.
For TV displays:
  • Use autofitpanels=true to optimize panel sizing
  • Design dashboards for the target resolution (usually 1920x1080)
  • Test visibility from viewing distance
  • Use larger fonts and fewer panels
If a dashboard fails to load:
  • Playlist continues to next dashboard after interval
  • Use dashboard health tags to exclude broken dashboards
  • Monitor playlist URLs for errors

Troubleshooting

  • Check browser console for JavaScript errors
  • Verify interval format (e.g., 5m, not 5 minutes)
  • Ensure dashboards in playlist are accessible
  • Check that playlist service is running: playlistSrv.state.isPlaying
Playlist auto-reloads every 3 loops to prevent memory leaks:
// Adjust in PlaylistSrv.ts if needed
if (this.numberOfLoops >= 3) {
  window.location.href = this.startUrl;
}
For infinite playback, this is expected behavior.
Ensure variables use URL-sync or default values:
  • Playlists don’t preserve variable selections between dashboards
  • Each dashboard loads with its default variable values
  • Use _dash.hideVariables=true if variables shouldn’t be user-editable

Dashboards

Create dashboards to include in playlists

Dashboard Settings

Configure dashboard display options

Kiosk Mode

Detailed kiosk mode documentation

Sharing

Share dashboards and playlists

Build docs developers (and LLMs) love