diff --git a/src/idiap_devtools/scripts/update_pins.py b/src/idiap_devtools/scripts/update_pins.py
index 94a4669df7e5561c36fa424407b491c103ec8e00..a8e02adfaf64ee0dddbc0832f3848beb35f8b7e0 100644
--- a/src/idiap_devtools/scripts/update_pins.py
+++ b/src/idiap_devtools/scripts/update_pins.py
@@ -163,9 +163,10 @@ def update_pins(manual_pins, profile, python, only_pip, **_) -> None:
             resolved_packages.append((name, version))
 
     # we only monitor a subset of packages
-    resolved_packages = [
-        (p, v) for (p, v) in resolved_packages if p in packages
-    ]
+    resolved_packages = sorted(
+        [(p, v) for (p, v) in resolved_packages if p in packages],
+        key=lambda x: (x[0], len(x[0])),
+    )
 
     # write the new pinning
     click.secho(
@@ -216,6 +217,10 @@ package_names_map:
         python_packages = filter_python_packages(
             resolved_packages, conda_to_python
         )
+        python_packages = sorted(
+            [(p, v) for (p, v) in python_packages],
+            key=lambda x: (x[0], len(x[0])),
+        )
         click.secho(
             f"Saving {len(python_packages)} entries to "
             f"`{pip_constraints_path}'...",
diff --git a/src/idiap_devtools/update_pins.py b/src/idiap_devtools/update_pins.py
index f5ea2cfb1d9bdacc4769d1a4c444d3aefc89e8ff..c078b264bd4b686e48c8d783626b32f65421db74 100644
--- a/src/idiap_devtools/update_pins.py
+++ b/src/idiap_devtools/update_pins.py
@@ -114,6 +114,10 @@ def update_pip_constraints_only(
 
     with pip_constraints_path.open("wt") as f:
         python_packages = filter_python_packages(package_pairs, conda_to_python)
+        python_packages = sorted(
+            [(p, v) for (p, v) in python_packages],
+            key=lambda x: (x[0], len(x[0])),
+        )
         click.echo(
             f"Saving {len(python_packages)} entries to "
             f"`{pip_constraints_path}'..."