How to Set Up and Manage Thumbnail Generation and Dashboard Caching in Apache Superset

Apache Superset uses Celery workers to render chart and dashboard thumbnails via headless browsers, storing PNG images in configurable cache backends like Redis, while supporting both CLI bulk operations and REST API triggers.

Apache Superset provides automated thumbnail generation for charts and dashboards to power visual previews in the UI and reporting features. To set up and manage thumbnail generation and dashboard caching effectively, you must configure the executor permissions, enable Celery task processing, and select the appropriate trigger mechanism for your deployment. The implementation spans configuration files, asynchronous task queues, and screenshot utilities.

Configuring Thumbnail Executors and Cache Backends

The first layer of thumbnail management involves declaring which user context renders the screenshots and where the images are stored. In superset/config.py, the THUMBNAIL_EXECUTORS setting determines which user’s permissions apply when capturing dashboards or charts:


# superset/config.py

THUMBNAIL_EXECUTORS = [ExecutorType.CURRENT_USER]   # default

# THUMBNAIL_EXECUTORS = [FixedExecutor("admin")]   # fixed service account
  • ExecutorType.CURRENT_USER renders thumbnails with the credentials of the user requesting them.
  • FixedExecutor("username") always renders with a dedicated service account, essential for headless CI pipelines or anonymous embeds.

You must also configure the THUMBNAIL_CACHE_CONFIG to specify the storage backend. The thumbnail tasks read this configuration to store images under keys prefixed by superset_thumbnails_:


# superset_config.py

THUMBNAIL_EXECUTORS = [FixedExecutor("admin")]
THUMBNAIL_CACHE_CONFIG = {
    "CACHE_TYPE": "RedisCache",
    "CACHE_REDIS_URL": "redis://localhost:6379/1",
    "CACHE_KEY_PREFIX": "superset_thumbnails_",
}

Celery Task Execution and Screenshot Logic

The heavy-weight rendering logic runs asynchronously in Celery workers defined in superset/tasks/thumbnails.py. Three primary tasks handle the workflow:

  • cache_chart_thumbnail – Renders and stores chart previews.
  • cache_dashboard_thumbnail – Renders and stores dashboard previews.
  • cache_dashboard_screenshot – Captures full dashboard screenshots for reports.

These tasks call screenshot classes in superset/utils/screenshots.py. ChartScreenshot and DashboardScreenshot inherit from BaseScreenshot, which abstracts the headless browser (Playwright) interaction, window sizing, and the final storage operation:


# superset/tasks/thumbnails.py

screenshot = ChartScreenshot(url, chart.digest)
screenshot.compute_and_cache(
    user=user,
    window_size=window_size,
    thumb_size=thumb_size,
    force=force,
)

The Celery tasks include a soft timeout of 300 seconds to prevent workers from hanging indefinitely during rendering.

Triggering Thumbnail Generation

Superset provides multiple interfaces to initiate thumbnail generation depending on your operational needs.

CLI Bulk Operations

The superset cli thumbnails compute_thumbnails command in superset/cli/thumbnails.py supports bulk or selective regeneration:

Flag Purpose
-a / --asynchronous Dispatch to Celery workers instead of running inline
-d / --dashboards_only Process only dashboards
-c / --charts_only Process only charts
-f / --force Re-render even if cached images exist
-i / --model_id Restrict to specific chart or dashboard IDs

Force-recompute all dashboards synchronously:

superset cli thumbnails compute_thumbnails --dashboards_only --force

Process specific charts asynchronously:

superset cli thumbnails compute_thumbnails \
    --charts_only \
    --model_id 42,43,44 \
    --asynchronous

REST API Endpoints

The REST API in superset/dashboards/api.py exposes a POST endpoint at /api/v1/dashboard/<id>/thumbnail/ that triggers cache_dashboard_thumbnail. This endpoint powers the UI "Refresh thumbnail" button and accepts a JSON payload with a force parameter:

curl -X POST "http://localhost:8088/api/v1/dashboard/7/thumbnail/" \
     -H "Authorization: Bearer <YOUR_JWT>" \
     -H "Content-Type: application/json" \
     -d '{"force": true}'

The response includes the cache key and URL to the generated PNG.

Dashboard Caching and Cache Warmup Strategies

While thumbnail generation handles visual previews, dashboard caching pre-warms query results to accelerate load times. The superset/tasks/cache.py module implements strategies like TopNDashboardsStrategy that enumerate popular dashboards and trigger their query execution.

Although distinct from thumbnail generation, these strategies share the same Celery infrastructure. You can programmatically pre-warm both data caches and thumbnails:

from superset.tasks.cache import TopNDashboardsStrategy
from superset.tasks.thumbnails import cache_dashboard_thumbnail

# Warm up top 5 dashboards

strategy = TopNDashboardsStrategy(limit=5)
strategy.run()

# Force regenerate a specific dashboard thumbnail

cache_dashboard_thumbnail.delay(
    current_user="admin",
    dashboard_id=7,
    force=True
)

End-to-End Execution Flow

Understanding the complete lifecycle helps debug failures:

  1. Request initiation – CLI command or REST API call triggers the workflow.
  2. Executor resolution – The system selects a user based on THUMBNAIL_EXECUTORS via get_executor.
  3. Task queuing – Celery queues cache_dashboard_thumbnail or cache_chart_thumbnail.
  4. Browser rendering – The screenshot class builds a Superset URL, launches Playwright, and captures the PNG.
  5. Storagecompute_and_cache writes the image to thumbnail_cache (Redis/Memcached).
  6. Retrieval – The UI fetches images from cache, falling back to regeneration if missing or when force=True.

Summary

  • Configure THUMBNAIL_EXECUTORS in superset/config.py to control which user permissions apply during rendering.
  • Deploy Celery workers to execute superset/tasks/thumbnails.py tasks with a 300-second soft timeout.
  • Use ChartScreenshot and DashboardScreenshot classes in superset/utils/screenshots.py for headless browser automation.
  • Trigger generation via the compute_thumbnails CLI command or the /api/v1/dashboard/<id>/thumbnail/ REST endpoint.
  • Store images in Redis or Memcached using THUMBNAIL_CACHE_CONFIG.
  • Leverage TopNDashboardsStrategy in superset/tasks/cache.py to pre-warm dashboard data alongside thumbnails.

Frequently Asked Questions

How do I force thumbnail regeneration for all dashboards in Apache Superset?

Use the CLI command with the --force and --dashboards_only flags. Run superset cli thumbnails compute_thumbnails --dashboards_only --force to synchronously re-render all dashboard thumbnails, or add --asynchronous to distribute the work across Celery workers.

What is the difference between ExecutorType.CURRENT_USER and FixedExecutor?

ExecutorType.CURRENT_USER applies the permissions of the user who requested the thumbnail, ensuring row-level security filters are respected. FixedExecutor("username") always renders with a specific service account, which is necessary for automated pipelines or when generating thumbnails for anonymous embedded contexts where no current user exists.

Where does Superset store generated thumbnails?

Superset stores PNG images in the cache backend defined by THUMBNAIL_CACHE_CONFIG, typically Redis or Memcached. The keys are prefixed with superset_thumbnails_ and include a digest of the chart or dashboard to ensure deterministic cache lookups.

How do I troubleshoot thumbnail generation failures?

Check the Celery worker logs for errors from superset/tasks/thumbnails.py, verify that THUMBNAIL_EXECUTORS is properly configured in your config file, and ensure the Playwright browser dependencies are installed in the worker environment. You can also test rendering locally by running the CLI command without the --asynchronous flag to see immediate error output.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →