diff --git a/mercurial/upgrade_utils/actions.py b/mercurial/upgrade_utils/actions.py
index 6b04f702c5010dfdc329fa6e942d072e2d640c4b_bWVyY3VyaWFsL3VwZ3JhZGVfdXRpbHMvYWN0aW9ucy5weQ==..7fe86498e84f07a2b24cb8a688d3856a122be394_bWVyY3VyaWFsL3VwZ3JhZGVfdXRpbHMvYWN0aW9ucy5weQ== 100644
--- a/mercurial/upgrade_utils/actions.py
+++ b/mercurial/upgrade_utils/actions.py
@@ -683,7 +683,11 @@
 
         newactions.append(d)
 
-    newactions.extend(o for o in sorted(optimizations) if o not in newactions)
+    newactions.extend(
+        o
+        for o in sorted(optimizations, key=(lambda x: x.name))
+        if o not in newactions
+    )
 
     # FUTURE consider adding some optimizations here for certain transitions.
     # e.g. adding generaldelta could schedule parent redeltas.
diff --git a/tests/test-upgrade-repo.t b/tests/test-upgrade-repo.t
index 6b04f702c5010dfdc329fa6e942d072e2d640c4b_dGVzdHMvdGVzdC11cGdyYWRlLXJlcG8udA==..7fe86498e84f07a2b24cb8a688d3856a122be394_dGVzdHMvdGVzdC11cGdyYWRlLXJlcG8udA== 100644
--- a/tests/test-upgrade-repo.t
+++ b/tests/test-upgrade-repo.t
@@ -467,6 +467,7 @@
   re-delta-fulladd
      every revision will be re-added as if it was new content. It will go through the full storage mechanism giving extensions a chance to process it (eg. lfs). This is similar to "re-delta-all" but even slower since more logic is involved.
   
+
   $ hg debugupgrade --optimize re-delta-parent --quiet
   requirements
      preserved: dotencode, fncache, generaldelta, revlogv1, share-safe, sparserevlog, store (no-rust !)
@@ -480,6 +481,20 @@
     - manifest
   
 
+passing multiple optimization:
+
+  $ hg debugupgrade --optimize re-delta-parent --optimize re-delta-multibase --quiet
+  requirements
+     preserved: * (glob)
+  
+  optimisations: re-delta-multibase, re-delta-parent
+  
+  processed revlogs:
+    - all-filelogs
+    - changelog
+    - manifest
+  
+
 unknown optimization:
 
   $ hg debugupgrade --optimize foobar