11 min read

Filter presets in Apache Superset

the feature removed in 4.0 — and how we rebuilt it

Superset deleted its experimental Filter Sets in 4.0. The need didn't go anywhere. The history of the removal, why every workaround falls short, and how our fork rebuilt presets with drift detection, sync, and per-user defaults.

Filter presets in Apache Superset — removed in 4.0 and rebuilt with drift detection (social preview)
By Rt Kazakov· Founder · Drafted

The loudest complaints we get about BI tools aren't about query speed or pipelines. They're about something mundane: people re-enter the same filter combination every single time they open a dashboard.

A regional manager always looks at their division. A marketing lead at one product group. An operations manager at a rolling seven-day window. Tableau, Power BI, and Qlik all let you save that state, whatever they call it: filter sets, bookmarks, saved views. Superset had it too. In 4.0 the maintainers deleted it. Here's the history of that decision, why every workaround falls short, and how we rebuilt the feature — already deployed for every client on our Enterprise Superset package, with the architecture the original never got.

A feature that shipped, stalled, and got deleted

The original "Filter Sets" arrived with the native filters redesign in Superset 1.x (around 2021), gated behind the DASHBOARD_NATIVE_FILTERS_SET feature flag — default False, permanently experimental. It let users bundle their selected filter values under a name and restore them later.

It never stabilized. The codebase accumulated UI layout inconsistencies, state hydration race conditions, and compatibility bugs with cascading filters, while maintainer attention went to core operations. During the 4.0 cleanup, the community approved deleting the whole thing: PR #26369 removed the feature, the flag, the database models, and the REST endpoints. The release notes are blunt:

"The feature is permanently removed as it was not being actively maintained, it was not widely used, and it was full of bugs. We also considered that if we were to provide a similar feature, it would be better to re-implement it from scratch given the amount of technical debt that the implementation had."

Deleting a half-finished, buggy feature to protect core stability is a defensible engineering call. But it left a real gap — especially for teams migrating from Tableau, Power BI, or Qlik, where saved views are assumed.

The workarounds, and why each one falls short

Stock Superset offers four ways to approximate saved filters. None survive contact with real usage:

  • Permalinks encode filter state into a UUID stored in the backend key_value table. Shareable, but anonymous one-off snapshots: no naming, no directory, no defaults, no management UI.
  • Default values on native filters are static and global — one default per filter for every user. A single dashboard serving three regions cannot give each region its own starting view.
  • URL parameters (native_filters_key) pass Rison-serialized state or short-lived cache keys. The keys expire from the server cache, and the saved view silently dies with them.
  • Duplicating the dashboard persists a filter combination at the cost of structural drift: every later change to the primary dashboard fails to cascade into the copies.

The demand never went away

Since 4.0 shipped, users keep filing requests for exactly this capability. Discussion #34386 (originally Issue #34377, July 2025) describes it precisely:

"End-users often need to apply the same combination of filters repeatedly to get to their specific, relevant view of the data... The only alternative is to bookmark the very long, state-encoded URL, which is not user-friendly, is hard to share, and can break if the dashboard structure changes."

Discussion #34094 asks for the "ability to save combined filter settings" to toggle between scenarios. The friction is also quantifiable: 150 analysts, 3 dashboard visits a day, 45 seconds of re-clicking multi-selects and date pickers per visit — that is roughly 1,400 lost hours a year on a single dashboard.

How we rebuilt it

Rather than waiting for an upstream rewrite, we re-introduced filter sets in our fork and fixed the specific reasons the original died. The result is a first-class FILTER SETS panel at the top of the native filters sidebar: selecting a preset applies a saved combination of every native filter — time ranges, categories, metrics, custom group-bys — in one click, as an in-place Redux state change that refreshes only the affected charts. No page reload.

Named, durable, inspectable objects

Presets are relational database objects managed through a nested REST API under the parent dashboard — list, create, update, and delete, scoped per dashboard and per user. Before applying a preset, analysts can inspect all saved parameters in a formatted view with localized dates and readable arrays.

Per-user defaults with a clear priority order

Any user can star a preset as their personal default loading state. On dashboard open, the default preset pre-loads before charts render — no double-fetching. Explicit deep links always win over defaults:

Permalink URL state          (wins over all)


Ephemeral native_filters_key URL state


User's default preset        (is_primary in DB)


Empty / default dashboard state (fallback)

Shared and personal presets

An explicit ownership model separates team alignment from personal research. Dashboard-scoped presets are curated by the dashboard owner ("Standard quarterly view"), visible to every reader, and protected from deletion or renaming by non-owners. User-scoped presets are private bookmarks visible only to their creator.

Drift detection — the problem that killed the original

The original implementation crashed when dashboard filters changed. Our version compares the preset's stored filter keys against the dashboard's active filters on every render:

const hasMetadataDesyncForPreset = (preset: FilterSet) => {
  const presetIds = Object.keys(preset.nativeFilters || {});
  const activeIds = nativeFilters.map(f => f.id);
 
  // Drift if active filters are missing from the preset,
  // or the preset still references deleted filters
  return (
    presetIds.some(id => !activeIds.includes(id)) ||
    activeIds.some(id => !presetIds.includes(id))
  );
};

On drift: a yellow warning triangle next to the preset name, a tooltip ("The list of filters on the dashboard has changed"), and — if applying the stale preset would produce bad SQL — a hard block.

One-click synchronization

Instead of recreating presets from scratch, a SYNCHRONIZE action reconciles the structure in memory: values for deleted filters are dropped, newly introduced filters get empty slots, surviving values are preserved, and the repaired payload is saved back with a single PUT. One click instead of re-selecting seven filters from memory.

The "apply filters first" gate

Save and update buttons stay disabled while the filter panel holds unapplied draft selections, with a tooltip saying exactly that. Only fully applied, validated filter states get serialized — nobody overwrites a team preset with a half-edited draft.

Presets inside embedded analytics

Because presets live in the core state and API layers — not in a UI add-on — they ship with every Enterprise deployment. End users of a SaaS portal can create, save, and manage their own presets through the same REST API, inside your product. We run this in production for every Enterprise client today — thousands of franchise managers and analysts across multiple countries.

Honest trade-offs

Fork presetsStock permalinks
Named, manageable, searchableyesno
Personal default loading statesyesno
Drift detection and syncyesno — URLs break silently
Permissions and ownership scopesyesno
Included for Drafted Enterprise clientsyes — every deploymentno
Metadata DB footprintsmall additional tablesminimal

Two honest limitations: presets capture native filters (time range, selects, sliders) — they are a dashboard-consumption tool, not a query versioning system or a chart-level drill-down recorder. Deploying it means running our maintained fork (current base: 4.1.1) — which is what every Enterprise package customer gets out of the box.

Takeaways

When a useful feature is removed for technical debt, the user need does not leave with it. If your team is migrating from Tableau or Power BI, audit how much time users lose to repetitive manual filtering — the math above tends to surprise people. And if dashboards face external customers, named persistent views are the difference between self-service analytics and a support queue.

We have already rolled out filter presets for every Drafted Enterprise client. If your team is stuck re-clicking the same filters on stock Superset, see what the Enterprise package includes — we can deploy the same setup for you.

Also on X

Long-form article on the removal story and drift detection: x.com/RtKazakov.

Topics

  • Apache Superset
  • Dashboard filters
  • Embedded analytics
  • Superset features