diff --git a/CHANGELOG.md b/CHANGELOG.md
index e657561c..cc47da74 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ### Added
 
+- [GCI91](https://github.com/green-code-initiative/creedengo-java/pull/111) New rule to detect if a sort method is called before a filter in stream
+
 ### Changed
 
 - [#103](https://github.com/green-code-initiative/creedengo-java/pull/103) GCI69 Java : calls to hasMoreElements() and nextElement() methods from java.util.Enumeration interface aren't flagged anymore when called in a for loop
diff --git a/pom.xml b/pom.xml
index ae43a190..014b03b9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -78,7 +78,7 @@
         1.8
 
         
-        2.2.2
+        2.2.3
 
         
         https://repo1.maven.org/maven2
@@ -231,6 +231,10 @@
                 org.apache.maven.plugins
                 maven-compiler-plugin
                 3.13.0
+                
+                    16
+                    16
+                
             
             
                 org.apache.maven.plugins
diff --git a/src/it/java/org/greencodeinitiative/creedengo/java/integration/tests/GCIRulesIT.java b/src/it/java/org/greencodeinitiative/creedengo/java/integration/tests/GCIRulesIT.java
index eff99826..064272ab 100644
--- a/src/it/java/org/greencodeinitiative/creedengo/java/integration/tests/GCIRulesIT.java
+++ b/src/it/java/org/greencodeinitiative/creedengo/java/integration/tests/GCIRulesIT.java
@@ -1,6 +1,7 @@
 package org.greencodeinitiative.creedengo.java.integration.tests;
 
 import org.junit.jupiter.api.Test;
+import org.sonarqube.ws.Common;
 import org.sonarqube.ws.Issues;
 import org.sonarqube.ws.Measures;
 
@@ -548,4 +549,15 @@ void testGCI94() {
         checkIssuesForFile(filePath, ruleId, ruleMsg, startLines, endLines, SEVERITY, TYPE, EFFORT_1MIN);
     }
 
+    @Test
+    void testGCI91() {
+        String filePath = "src/main/java/org/greencodeinitiative/creedengo/java/checks/UseFilterBeforeSort.java";
+        String ruleId = "creedengo-java:GCI91";
+        String ruleMsg = "Use 'filter' before 'sorted' for better efficiency.";
+        int[] startLines = new int[]{11,16};
+        int[] endLines = new int[]{14, 20};
+
+        checkIssuesForFile(filePath, ruleId, ruleMsg, startLines, endLines, Common.Severity.MAJOR, TYPE, EFFORT_5MIN);
+    }
+
 }
diff --git a/src/it/test-projects/creedengo-java-plugin-test-project/src/main/java/org/greencodeinitiative/creedengo/java/checks/UseFilterBeforeSort.java b/src/it/test-projects/creedengo-java-plugin-test-project/src/main/java/org/greencodeinitiative/creedengo/java/checks/UseFilterBeforeSort.java
new file mode 100644
index 00000000..18b9c321
--- /dev/null
+++ b/src/it/test-projects/creedengo-java-plugin-test-project/src/main/java/org/greencodeinitiative/creedengo/java/checks/UseFilterBeforeSort.java
@@ -0,0 +1,27 @@
+package org.greencodeinitiative.creedengo.java.checks;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+class UseFilterBeforeSort {
+    UseFilterBeforeSort() {
+    }
+
+    public void manipulateStream(final List list) {
+        list.stream() // Noncompliant {{Use 'filter' before 'sorted' for better efficiency.}}
+                .sorted()
+                .filter(s -> s.startsWith("A"))
+                .collect(Collectors.toList());
+
+        list.stream() // Noncompliant {{Use 'filter' before 'sorted' for better efficiency.}}
+                .sorted()
+                .map(element -> element.toString())
+                .filter(s -> s.startsWith("A"))
+                .collect(Collectors.toList());
+
+        list.stream() // Compliant {{Use 'filter' before 'sorted' for better efficiency.}}
+                .filter(s -> s.startsWith("A"))
+                .sorted()
+                .collect(Collectors.toList());
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/org/greencodeinitiative/creedengo/java/JavaCheckRegistrar.java b/src/main/java/org/greencodeinitiative/creedengo/java/JavaCheckRegistrar.java
index 791f0cef..1f084e39 100644
--- a/src/main/java/org/greencodeinitiative/creedengo/java/JavaCheckRegistrar.java
+++ b/src/main/java/org/greencodeinitiative/creedengo/java/JavaCheckRegistrar.java
@@ -50,7 +50,8 @@ public class JavaCheckRegistrar implements CheckRegistrar {
             FreeResourcesOfAutoCloseableInterface.class,
             AvoidMultipleIfElseStatement.class,
             UseOptionalOrElseGetVsOrElse.class,
-            MakeNonReassignedVariablesConstants.class
+            MakeNonReassignedVariablesConstants.class,
+            UseFilterBeforeSort.class
     );
 
     /**
diff --git a/src/main/java/org/greencodeinitiative/creedengo/java/checks/UseFilterBeforeSort.java b/src/main/java/org/greencodeinitiative/creedengo/java/checks/UseFilterBeforeSort.java
new file mode 100644
index 00000000..8b6b04fe
--- /dev/null
+++ b/src/main/java/org/greencodeinitiative/creedengo/java/checks/UseFilterBeforeSort.java
@@ -0,0 +1,77 @@
+package org.greencodeinitiative.creedengo.java.checks;
+
+import org.sonar.check.Rule;
+import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
+import org.sonar.plugins.java.api.tree.*;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+@Rule(key = "GCI91")
+public class UseFilterBeforeSort extends IssuableSubscriptionVisitor {
+    @Override
+    public List nodesToVisit() {
+        return Collections.singletonList(Tree.Kind.METHOD_INVOCATION);
+    }
+
+    @Override
+    public void visitNode(Tree tree) {
+        if (tree instanceof MethodInvocationTree) {
+            MethodInvocationTree mit = (MethodInvocationTree) tree;
+
+            if (!isTerminalOperation(mit)) {
+                return; // Ignoring intermediate steps (filter, sorted, etc.)
+            }
+
+            List methodChain = extractChainedMethodNames(mit);
+
+            int sortedIndex = methodChain.indexOf("sorted");
+            int filterIndex = methodChain.indexOf("filter");
+
+            if (sortedIndex != -1 && filterIndex != -1 && sortedIndex < filterIndex) {
+                reportIssue(tree, "Use 'filter' before 'sorted' for better efficiency.");
+            }
+        }
+    }
+
+    private List extractChainedMethodNames(MethodInvocationTree terminalInvocation) {
+        List methodNames = new ArrayList<>();
+        ExpressionTree current = terminalInvocation;
+
+        while (current instanceof MethodInvocationTree) {
+            MethodInvocationTree methodCall = (MethodInvocationTree) current;
+            ExpressionTree methodSelect = methodCall.methodSelect();
+
+            if (methodSelect instanceof MemberSelectExpressionTree) {
+                MemberSelectExpressionTree memberSelect = (MemberSelectExpressionTree) methodSelect;
+                methodNames.add(memberSelect.identifier().name());
+                current = memberSelect.expression(); // Go to the previous method
+            } else {
+                break;
+            }
+        }
+
+        Collections.reverse(methodNames); // Reverse to get right order in collection like stream → ... → collect
+        return methodNames;
+    }
+
+    private boolean isTerminalOperation(MethodInvocationTree tree) {
+        if (!(tree.methodSelect() instanceof MemberSelectExpressionTree)) {
+            return false;
+        }
+        String methodName = ((MemberSelectExpressionTree) tree.methodSelect()).identifier().name();
+        // Ajouter ici tous les terminaux connus
+        return "collect".equals(methodName)
+                || "forEach".equals(methodName)
+                || "reduce".equals(methodName)
+                || "count".equals(methodName)
+                || "toArray".equals(methodName)
+                || "anyMatch".equals(methodName)
+                || "allMatch".equals(methodName)
+                || "noneMatch".equals(methodName)
+                || "findFirst".equals(methodName)
+                || "findAny".equals(methodName);
+    }
+
+}
diff --git a/src/main/resources/org/greencodeinitiative/creedengo/java/creedengo_way_profile.json b/src/main/resources/org/greencodeinitiative/creedengo/java/creedengo_way_profile.json
index 059bf0f5..33fb1a7e 100644
--- a/src/main/resources/org/greencodeinitiative/creedengo/java/creedengo_way_profile.json
+++ b/src/main/resources/org/greencodeinitiative/creedengo/java/creedengo_way_profile.json
@@ -18,6 +18,7 @@
 	"GCI78",
 	"GCI79",
 	"GCI82",
+	"GCI91",
 	"GCI94"
   ]
 }
diff --git a/src/test/files/UseFilterBeforeSort.java b/src/test/files/UseFilterBeforeSort.java
new file mode 100644
index 00000000..1b5712ce
--- /dev/null
+++ b/src/test/files/UseFilterBeforeSort.java
@@ -0,0 +1,44 @@
+/*
+ * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs
+ * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.greencodeinitiative.creedengo.java.checks;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+class UseFilterBeforeSort {
+    UseFilterBeforeSort() {
+    }
+
+    public void manipulateStream(List list) {
+        list.stream() // Noncompliant {{Use 'filter' before 'sorted' for better efficiency.}}
+                .sorted()
+                .filter(s -> s.startsWith("A"))
+                .collect(Collectors.toList());
+
+        list.stream() // Noncompliant {{Use 'filter' before 'sorted' for better efficiency.}}
+                .sorted()
+                .otherMethod()
+                .filter(s -> s.startsWith("A"))
+                .collect(Collectors.toList());
+
+        list.stream() // Compliant {{Use 'filter' before 'sorted' for better efficiency.}}
+                .filter(s -> s.startsWith("A"))
+                .sorted()
+                .collect(Collectors.toList());
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/org/greencodeinitiative/creedengo/java/checks/UseFilterBeforeSortTest.java b/src/test/java/org/greencodeinitiative/creedengo/java/checks/UseFilterBeforeSortTest.java
new file mode 100644
index 00000000..4d9a53d5
--- /dev/null
+++ b/src/test/java/org/greencodeinitiative/creedengo/java/checks/UseFilterBeforeSortTest.java
@@ -0,0 +1,14 @@
+package org.greencodeinitiative.creedengo.java.checks;
+
+import org.junit.jupiter.api.Test;
+import org.sonar.java.checks.verifier.CheckVerifier;
+
+public class UseFilterBeforeSortTest {
+    @Test
+    void testHasIssues() {
+        CheckVerifier.newVerifier()
+                .onFile("src/test/files/UseFilterBeforeSort.java")
+                .withCheck(new UseFilterBeforeSort())
+                .verifyIssues();
+    }
+}