diff --git a/contrib/perf.py b/contrib/perf.py
index 04bfcb41674503405a781de444034716843431f9_Y29udHJpYi9wZXJmLnB5..f02b62b7b056e2fc4d899deac2fae7c1453c4fb6_Y29udHJpYi9wZXJmLnB5 100644
--- a/contrib/perf.py
+++ b/contrib/perf.py
@@ -882,8 +882,20 @@
     fm.end()
 
 
+def _default_clear_on_disk_tags_cache(repo):
+    from mercurial import tags
+
+    repo.cachevfs.tryunlink(tags._filename(repo))
+
+
+def _default_clear_on_disk_tags_fnodes_cache(repo):
+    from mercurial import tags
+
+    repo.cachevfs.tryunlink(tags._fnodescachefile)
+
+
 @command(
     b'perf::tags|perftags',
     formatteropts
     + [
         (b'', b'clear-revlogs', False, b'refresh changelog and manifest'),
@@ -885,8 +897,20 @@
 @command(
     b'perf::tags|perftags',
     formatteropts
     + [
         (b'', b'clear-revlogs', False, b'refresh changelog and manifest'),
+        (
+            b'',
+            b'clear-on-disk-cache',
+            False,
+            b'clear on disk tags cache (DESTRUCTIVE)',
+        ),
+        (
+            b'',
+            b'clear-fnode-cache',
+            False,
+            b'clear on disk file node cache (DESTRUCTIVE),',
+        ),
     ],
 )
 def perftags(ui, repo, **opts):
@@ -890,7 +914,15 @@
     ],
 )
 def perftags(ui, repo, **opts):
+    """Benchmark tags retrieval in various situation
+
+    The option marked as (DESTRUCTIVE) will alter the on-disk cache, possibly
+    altering performance after the command was run. However, it does not
+    destroy any stored data.
+    """
+    from mercurial import tags
+
     opts = _byteskwargs(opts)
     timer, fm = gettimer(ui, opts)
     repocleartagscache = repocleartagscachefunc(repo)
     clearrevlogs = opts[b'clear_revlogs']
@@ -893,9 +925,22 @@
     opts = _byteskwargs(opts)
     timer, fm = gettimer(ui, opts)
     repocleartagscache = repocleartagscachefunc(repo)
     clearrevlogs = opts[b'clear_revlogs']
+    clear_disk = opts[b'clear_on_disk_cache']
+    clear_fnode = opts[b'clear_fnode_cache']
+
+    clear_disk_fn = getattr(
+        tags,
+        "clear_cache_on_disk",
+        _default_clear_on_disk_tags_cache,
+    )
+    clear_fnodes_fn = getattr(
+        tags,
+        "clear_cache_fnodes",
+        _default_clear_on_disk_tags_fnodes_cache,
+    )
 
     def s():
         if clearrevlogs:
             clearchangelog(repo)
             clearfilecache(repo.unfiltered(), 'manifest')
@@ -897,8 +942,12 @@
 
     def s():
         if clearrevlogs:
             clearchangelog(repo)
             clearfilecache(repo.unfiltered(), 'manifest')
+        if clear_disk:
+            clear_disk_fn(repo)
+        if clear_fnode:
+            clear_fnodes_fn(repo)
         repocleartagscache()
 
     def t():
diff --git a/mercurial/tags.py b/mercurial/tags.py
index 04bfcb41674503405a781de444034716843431f9_bWVyY3VyaWFsL3RhZ3MucHk=..f02b62b7b056e2fc4d899deac2fae7c1453c4fb6_bWVyY3VyaWFsL3RhZ3MucHk= 100644
--- a/mercurial/tags.py
+++ b/mercurial/tags.py
@@ -910,3 +910,13 @@
             )
         finally:
             lock.release()
+
+
+def clear_cache_on_disk(repo):
+    """function used by the perf extension to "tags" cache"""
+    repo.cachevfs.tryunlink(_filename(repo))
+
+
+def clear_cache_fnodes(repo):
+    """function used by the perf extension to clear "file node cache"""
+    repo.cachevfs.tryunlink(_filename(repo))
diff --git a/tests/test-contrib-perf.t b/tests/test-contrib-perf.t
index 04bfcb41674503405a781de444034716843431f9_dGVzdHMvdGVzdC1jb250cmliLXBlcmYudA==..f02b62b7b056e2fc4d899deac2fae7c1453c4fb6_dGVzdHMvdGVzdC1jb250cmliLXBlcmYudA== 100644
--- a/tests/test-contrib-perf.t
+++ b/tests/test-contrib-perf.t
@@ -194,7 +194,7 @@
                  benchmark the full generation of a stream clone
    perf::stream-locked-section
                  benchmark the initial, repo-locked, section of a stream-clone
-   perf::tags    (no help text available)
+   perf::tags    Benchmark tags retrieval in various situation
    perf::templating
                  test the rendering time of a given template
    perf::unbundle