diff --git a/brian_dashboard_manager/grafana/provision.py b/brian_dashboard_manager/grafana/provision.py
index c8df565d908f02223e532753f77c84c268cc329f..ce99f7510550a2a81b444e2ad6e0c50371786733 100644
--- a/brian_dashboard_manager/grafana/provision.py
+++ b/brian_dashboard_manager/grafana/provision.py
@@ -2,6 +2,7 @@
 This module is responsible for the
 entire provisioning lifecycle.
 """
+import itertools
 import os
 import logging
 import time
@@ -39,8 +40,6 @@ from brian_dashboard_manager.templating.render import render_dashboard
 
 logger = logging.getLogger(__name__)
 
-DASHBOARD_CHANGES = None  # will be an instance of DashboardChanges
-
 MAX_WORKERS = 1
 DASHBOARDS = {
     'NREN': {
@@ -156,28 +155,6 @@ AGG_DASHBOARDS = {
 }
 
 
-class DashboardChanges(object):
-    def __init__(self, token):
-        # Map of dashboard UID -> whether it has been updated.
-        # This is used to remove stale dashboards at the end.
-        all_dashboards = find_dashboard(token) or []
-        self.updated = {d['uid']: False for d in all_dashboards}
-
-    def update_dash_list(self, dashboards):
-        for dashboard in dashboards:
-            if isinstance(dashboard, Future):
-                dashboard = dashboard.result()
-            if dashboard is None:
-                continue
-            self.updated[dashboard.get('uid')] = True
-
-    def delete_untouched(self, token):
-        for uid, provisioned in self.updated.items():
-            if not provisioned:
-                logger.info(f'Deleting stale dashboard with UID {uid}')
-                delete_dashboard(token, {'uid': uid})
-
-
 def provision_folder(token_request, folder_name, dash,
                      ds_name, excluded_dashboards):
     """
@@ -278,7 +255,15 @@ def excluded_folder_dashboards(org_config, folder_name):
 
 
 def _provision_interfaces(config, org_config, ds_name, token):
-    # Provision dashboards, overwriting existing ones.
+    """
+    Provision dashboards, overwriting existing ones.
+
+    :param config:
+    :param org_config:
+    :param ds_name:
+    :param token:
+    :return: yields dashboards that were created
+    """
 
     interfaces = get_interfaces(config['inventory_provider'])
 
@@ -333,7 +318,7 @@ def _provision_interfaces(config, org_config, ds_name, token):
             folder = result.result()
             if folder is None:
                 continue
-            DASHBOARD_CHANGES.update_dash_list(folder)
+            yield from folder
 
 
 def _provision_gws_indirect(config, org_config, ds_name, token):
@@ -356,7 +341,7 @@ def _provision_gws_indirect(config, org_config, ds_name, token):
                                                    token,
                                                    rendered, folder['id']))
 
-            DASHBOARD_CHANGES.update_dash_list(provisioned)
+            yield from provisioned
 
 
 def _provision_gws_direct(config, org_config, ds_name, token):
@@ -378,7 +363,7 @@ def _provision_gws_direct(config, org_config, ds_name, token):
                                                    token,
                                                    rendered, folder['id']))
 
-            DASHBOARD_CHANGES.update_dash_list(provisioned)
+            yield from provisioned
 
 
 def _provision_eumetsat_multicast(config, org_config, ds_name, token):
@@ -405,7 +390,7 @@ def _provision_eumetsat_multicast(config, org_config, ds_name, token):
                         rendered,
                         folder['id']))
 
-            DASHBOARD_CHANGES.update_dash_list(provisioned)
+            yield from provisioned
 
 
 def _provision_aggregates(config, org_config, ds_name, token):
@@ -433,7 +418,7 @@ def _provision_aggregates(config, org_config, ds_name, token):
                     agg_folder, dash, ds_name)
                 provisioned.append(res)
 
-            DASHBOARD_CHANGES.update_dash_list(provisioned)
+            yield from provisioned
 
 
 def _provision_static_dashboards(config, org_config, ds_name, token):
@@ -444,7 +429,9 @@ def _provision_static_dashboards(config, org_config, ds_name, token):
         if dashboard['title'] not in excluded_dashboards:
             res = create_dashboard(token, dashboard)
             if res:
-                DASHBOARD_CHANGES.updated[res.get('uid')] = True
+                # yield a fake dashboard dict
+                # ... only the 'uid' element is referenced
+                yield {'uid': res.get('uid')}
         else:
             delete_dashboard(token, dashboard)
 
@@ -452,11 +439,11 @@ def _provision_static_dashboards(config, org_config, ds_name, token):
     # Make sure it's set for the organization
     logger.info('Configuring Home dashboard')
     set_home_dashboard(token, org_config['name'] == 'GÉANT Staff')
-    # just hardcode that we updated home dashboard
-    DASHBOARD_CHANGES.updated['home'] = True
+
+    yield {'uid': 'home'}
 
 
-def _set_ignored_folders_as_updated(config, org_config, token):
+def _get_ignored_dashboards(config, org_config, token):
     # get dashboard UIDs from ignored folders
     # and make sure we don't touch them
     ignored_folders = config.get('ignored_folders', [])
@@ -473,8 +460,9 @@ def _set_ignored_folders_as_updated(config, org_config, token):
             continue
 
         for dash in to_ignore:
-            # mark it updated, so we don't modify it.
-            DASHBOARD_CHANGES.updated[dash['uid']] = True
+            # return a hard-coded fake dashboard dict
+            # ... only the 'uid' element is referenced
+            yield {'uid': dash['uid']}  # could just yield dash
 
 
 def _delete_unknown_folders(config, token):
@@ -535,8 +523,6 @@ def _provision_orgs(config):
 
 def provision(config):
 
-    global DASHBOARD_CHANGES
-
     start = time.time()
     tokens = []
     all_orgs = _provision_orgs(config)
@@ -555,35 +541,55 @@ def provision(config):
 
     for org in all_orgs:
         org_id = org['id']
+
+        logger.info(
+            f'--- Provisioning org {org["name"]} (ID #{org_id}) ---')
+
         delete_expired_api_tokens(request, org_id)
         token = create_api_token(request, org_id)
         token_request = TokenRequest(token=token['key'], **config)
         tokens.append((org_id, token['id']))
 
-        DASHBOARD_CHANGES = DashboardChanges(token_request)
-
-        logger.info(
-            f'--- Provisioning org {org["name"]} (ID #{org_id}) ---')
-
         org_config = _find_org_config(org)
         if not org_config:
             # message logged from _find_org_config
             continue
 
+        all_original_dashboards = find_dashboard(token_request) or []
+        all_original_dashboard_uids = {
+            d['uid'] for d in all_original_dashboards}
+
         datasource = _provision_datasource(config, token_request)
         ds_name = datasource.get('name', 'PollerInfluxDB')
 
-        _provision_interfaces(config, org_config, ds_name, token_request)
-        _provision_gws_indirect(config, org_config, ds_name, token_request)
-        _provision_gws_direct(config, org_config, ds_name, token_request)
-        _provision_eumetsat_multicast(
-            config, org_config, ds_name, token_request)
-        _provision_aggregates(config, org_config, ds_name, token_request)
-        _provision_static_dashboards(
-            config, org_config, ds_name, token_request)
-        _set_ignored_folders_as_updated(config, org_config, token_request)
-
-        DASHBOARD_CHANGES.delete_untouched(token_request)
+        managed_dashboards = itertools.chain(
+            _provision_interfaces(
+                config, org_config, ds_name, token_request),
+            _provision_gws_indirect(
+                config, org_config, ds_name, token_request),
+            _provision_gws_direct(
+                config, org_config, ds_name, token_request),
+            _provision_eumetsat_multicast(
+                config, org_config, ds_name, token_request),
+            _provision_aggregates(
+                config, org_config, ds_name, token_request),
+            _provision_static_dashboards(
+                config, org_config, ds_name, token_request),
+            _get_ignored_dashboards(
+                config, org_config, token_request)
+        )
+
+        managed_dashboard_uids = set()
+        for dashboard in managed_dashboards:
+            if isinstance(dashboard, Future):
+                dashboard = dashboard.result()
+            if dashboard is None:
+                continue
+            managed_dashboard_uids.add(dashboard.get('uid'))
+
+        for uid in all_original_dashboard_uids - managed_dashboard_uids:
+            logger.info(f'Deleting stale dashboard with UID {uid}')
+            delete_dashboard(token, {'uid': uid})
 
         _delete_unknown_folders(config, token_request)