diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/DefaultEvaluationStrategy.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/DefaultEvaluationStrategy.java
index 74a7294618d..eb8c0eeb720 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/DefaultEvaluationStrategy.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/DefaultEvaluationStrategy.java
@@ -392,7 +392,7 @@ public CloseableIteration<BindingSet> evaluate(TupleExpr expr, BindingSet bindin
 			} else if (expr instanceof SingletonSet) {
 				result = precompile(expr).evaluate(bindings);
 			} else if (expr instanceof EmptySet) {
-				result = new EmptyIteration<>();
+				result = QueryEvaluationStep.EMPTY_ITERATION;
 			} else if (expr instanceof ZeroLengthPath) {
 				result = precompile(expr).evaluate(bindings);
 			} else if (expr instanceof ArbitraryLengthPath) {
@@ -624,7 +624,7 @@ protected QueryEvaluationStep prepare(Filter node, QueryEvaluationContext contex
 			// If we have a failed compilation we always return false.
 			// Which means empty. so let's short circuit that.
 //			ves = new QueryValueEvaluationStep.ConstantQueryValueEvaluationStep(BooleanLiteral.FALSE);
-			return bs -> new EmptyIteration<>();
+			return bs -> QueryEvaluationStep.EMPTY_ITERATION;
 		}
 		return bs -> {
 			CloseableIteration<BindingSet> evaluate = null;
@@ -839,7 +839,7 @@ protected QueryEvaluationStep prepare(SingletonSet singletonSet, QueryEvaluation
 
 	protected QueryEvaluationStep prepare(EmptySet emptySet, QueryEvaluationContext context)
 			throws QueryEvaluationException {
-		return bindings -> new EmptyIteration<>();
+		return bindings -> QueryEvaluationStep.EMPTY_ITERATION;
 	}
 
 	@Override
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/evaluationsteps/JoinQueryEvaluationStep.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/evaluationsteps/JoinQueryEvaluationStep.java
index 66c726afa29..5343911f905 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/evaluationsteps/JoinQueryEvaluationStep.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/evaluationsteps/JoinQueryEvaluationStep.java
@@ -43,7 +43,7 @@ public JoinQueryEvaluationStep(EvaluationStrategy strategy, Join join, QueryEval
 					joinAttributes, context);
 			join.setAlgorithm(HashJoinIteration.class.getSimpleName());
 		} else {
-			eval = bindings -> new JoinIterator(leftPrepared, rightPrepared, bindings);
+			eval = bindings -> JoinIterator.getInstance(leftPrepared, rightPrepared, bindings);
 			join.setAlgorithm(JoinIterator.class.getSimpleName());
 		}
 	}
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/evaluationsteps/UnionQueryEvaluationStep.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/evaluationsteps/UnionQueryEvaluationStep.java
index 63dbd1a1e28..29690ddccf3 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/evaluationsteps/UnionQueryEvaluationStep.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/evaluationsteps/UnionQueryEvaluationStep.java
@@ -35,9 +35,9 @@ public CloseableIteration<BindingSet> evaluate(BindingSet bindings) {
 			evaluate = leftQes.evaluate(bindings);
 			evaluate1 = rightQes.evaluate(bindings);
 
-			if (evaluate instanceof EmptyIteration) {
+			if (evaluate == QueryEvaluationStep.EMPTY_ITERATION) {
 				return evaluate1;
-			} else if (evaluate1 instanceof EmptyIteration) {
+			} else if (evaluate1 == QueryEvaluationStep.EMPTY_ITERATION) {
 				return evaluate;
 			}
 
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/iterator/DescribeIteration.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/iterator/DescribeIteration.java
index 792ce0100c2..b4e9710508e 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/iterator/DescribeIteration.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/iterator/DescribeIteration.java
@@ -27,6 +27,8 @@
 import org.eclipse.rdf4j.query.algebra.StatementPattern;
 import org.eclipse.rdf4j.query.algebra.Var;
 import org.eclipse.rdf4j.query.algebra.evaluation.EvaluationStrategy;
+import org.eclipse.rdf4j.query.algebra.evaluation.QueryEvaluationStep;
+import org.eclipse.rdf4j.query.algebra.evaluation.QueryValueEvaluationStep;
 
 /**
  * Iteration that implements a simplified version of Symmetric Concise Bounded Description (omitting reified
@@ -208,7 +210,7 @@ protected BindingSet getNextElement() throws QueryEvaluationException {
 	protected CloseableIteration<BindingSet> createNextIteration(Value subject, Value object)
 			throws QueryEvaluationException {
 		if (subject == null && object == null) {
-			return new EmptyIteration<>();
+			return QueryEvaluationStep.EMPTY_ITERATION;
 		}
 
 		Var subjVar = new Var(VARNAME_SUBJECT, subject);
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/iterator/JoinIterator.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/iterator/JoinIterator.java
index a0b82e49378..de24672726d 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/iterator/JoinIterator.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/iterator/JoinIterator.java
@@ -29,11 +29,6 @@
  * @author Jeen Broekstra
  */
 public class JoinIterator extends LookAheadIteration<BindingSet> {
-	public static final EmptyIteration<BindingSet> EMPTY_ITERATION = new EmptyIteration<>();
-
-	/*-----------*
-	 * Variables *
-	 *-----------*/
 
 	private final CloseableIteration<BindingSet> leftIter;
 
@@ -41,15 +36,26 @@ public class JoinIterator extends LookAheadIteration<BindingSet> {
 
 	private final QueryEvaluationStep preparedRight;
 
-	/*--------------*
-	 * Constructors *
-	 *--------------*/
-
 	public JoinIterator(QueryEvaluationStep leftPrepared,
-			QueryEvaluationStep rightPrepared, BindingSet bindings) throws QueryEvaluationException {
+			QueryEvaluationStep preparedRight, BindingSet bindings) throws QueryEvaluationException {
 		leftIter = leftPrepared.evaluate(bindings);
+		this.preparedRight = preparedRight;
+	}
+
+	private JoinIterator(CloseableIteration<BindingSet> leftIter, QueryEvaluationStep preparedRight)
+			throws QueryEvaluationException {
+		this.leftIter = leftIter;
+		this.preparedRight = preparedRight;
+	}
+
+	public static CloseableIteration<BindingSet> getInstance(QueryEvaluationStep leftPrepared,
+			QueryEvaluationStep preparedRight, BindingSet bindings) {
+		CloseableIteration<BindingSet> leftIter = leftPrepared.evaluate(bindings);
+		if (leftIter == QueryEvaluationStep.EMPTY_ITERATION) {
+			return leftIter;
+		}
 
-		this.preparedRight = rightPrepared;
+		return new JoinIterator(leftIter, preparedRight);
 	}
 
 	/*---------*
diff --git a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/iterator/LeftJoinIterator.java b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/iterator/LeftJoinIterator.java
index 831ec8e2314..93ebd004204 100644
--- a/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/iterator/LeftJoinIterator.java
+++ b/core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/iterator/LeftJoinIterator.java
@@ -31,8 +31,6 @@
 import org.eclipse.rdf4j.query.algebra.evaluation.util.QueryEvaluationUtility;
 
 public class LeftJoinIterator extends LookAheadIteration<BindingSet> {
-	public static final EmptyIteration<BindingSet> EMPTY_ITERATION = new EmptyIteration<>();
-
 	/*-----------*
 	 * Variables *
 	 *-----------*/
@@ -63,7 +61,7 @@ public LeftJoinIterator(EvaluationStrategy strategy, LeftJoin join, BindingSet b
 		leftIter = strategy.evaluate(join.getLeftArg(), bindings);
 
 		// Initialize with empty iteration so that var is never null
-		rightIter = EMPTY_ITERATION;
+		rightIter = QueryEvaluationStep.EMPTY_ITERATION;
 
 		prepareRightArg = strategy.precompile(join.getRightArg(), context);
 		join.setAlgorithm(this);
@@ -83,7 +81,7 @@ public LeftJoinIterator(QueryEvaluationStep left, QueryEvaluationStep right, Que
 		leftIter = left.evaluate(bindings);
 
 		// Initialize with empty iteration so that var is never null
-		rightIter = EMPTY_ITERATION;
+		rightIter = QueryEvaluationStep.EMPTY_ITERATION;
 
 		prepareRightArg = right;
 		this.joinCondition = joinCondition;
diff --git a/core/queryalgebra/evaluation/src/test/java/org/eclipse/rdf4j/query/algebra/evaluation/iterator/JoinIteratorTest.java b/core/queryalgebra/evaluation/src/test/java/org/eclipse/rdf4j/query/algebra/evaluation/iterator/JoinIteratorTest.java
index 33d910457e9..8f7dd1f84ed 100644
--- a/core/queryalgebra/evaluation/src/test/java/org/eclipse/rdf4j/query/algebra/evaluation/iterator/JoinIteratorTest.java
+++ b/core/queryalgebra/evaluation/src/test/java/org/eclipse/rdf4j/query/algebra/evaluation/iterator/JoinIteratorTest.java
@@ -106,11 +106,11 @@ private void testBindingSetAssignmentJoin(int expectedSize, int n, BindingSet bi
 			right.setBindingSets(rightb);
 		}
 
-		JoinIterator lrIter = new JoinIterator(evaluator.precompile(left), evaluator.precompile(right), bindings);
+		var lrIter = JoinIterator.getInstance(evaluator.precompile(left), evaluator.precompile(right), bindings);
 		Set<BindingSet> lr = Iterations.asSet(lrIter);
 		assertEquals(expectedSize, lr.size());
 
-		JoinIterator rlIter = new JoinIterator(evaluator.precompile(right), evaluator.precompile(left), bindings);
+		var rlIter = JoinIterator.getInstance(evaluator.precompile(right), evaluator.precompile(left), bindings);
 		Set<BindingSet> rl = Iterations.asSet(rlIter);
 		assertEquals(expectedSize, rl.size());