diff --git a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/mutiny/Mutiny.java b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/mutiny/Mutiny.java
index 22ec48da1c..65b0ad9062 100644
--- a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/mutiny/Mutiny.java
+++ b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/mutiny/Mutiny.java
@@ -194,6 +194,17 @@ interface SelectionQuery<R> extends AbstractQuery {
 		 */
 		Uni<R> getSingleResultOrNull();
 
+		/**
+		 * Determine the size of the query result list that would be
+		 * returned by calling {@link #getResultList()} with no
+		 * {@linkplain #getFirstResult() offset} or
+		 * {@linkplain #getMaxResults() limit} applied to the query.
+		 *
+		 * @return the size of the list that would be returned
+		 */
+		@Incubating
+		Uni<Long> getResultCount();
+
 		/**
 		 * Asynchronously execute this query, returning the query results
 		 * as a {@link List}, via a {@link Uni}. If the query
diff --git a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/mutiny/impl/MutinyQueryImpl.java b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/mutiny/impl/MutinyQueryImpl.java
index 9cb3a0287c..d0608ba5f7 100644
--- a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/mutiny/impl/MutinyQueryImpl.java
+++ b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/mutiny/impl/MutinyQueryImpl.java
@@ -47,6 +47,11 @@ public int getMaxResults() {
 		return delegate.getMaxResults();
 	}
 
+	@Override
+	public Uni<Long> getResultCount() {
+		return uni( delegate::getReactiveResultCount );
+	}
+
 	@Override
 	public Uni<List<R>> getResultList() {
 		return uni( delegate::getReactiveResultList );
diff --git a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/mutiny/impl/MutinySelectionQueryImpl.java b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/mutiny/impl/MutinySelectionQueryImpl.java
index 0d037e0ed6..b001e618a9 100644
--- a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/mutiny/impl/MutinySelectionQueryImpl.java
+++ b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/mutiny/impl/MutinySelectionQueryImpl.java
@@ -45,6 +45,11 @@ public int getMaxResults() {
 		return delegate.getMaxResults();
 	}
 
+	@Override
+	public Uni<Long> getResultCount() {
+		return uni( delegate::getReactiveResultCount );
+	}
+
 	@Override
 	public Uni<List<R>> getResultList() {
 		return uni( delegate::getReactiveResultList );
diff --git a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/query/ReactiveSelectionQuery.java b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/query/ReactiveSelectionQuery.java
index 81508c13b4..2b347b3de7 100644
--- a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/query/ReactiveSelectionQuery.java
+++ b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/query/ReactiveSelectionQuery.java
@@ -49,6 +49,8 @@ default CompletionStage<List<R>> getReactiveResultList() {
 
 	CompletionStage<R> getReactiveSingleResultOrNull();
 
+	CompletionStage<Long> getReactiveResultCount();
+
 	CompletionStage<R> reactiveUnique();
 
 	CompletionStage<Optional<R>> reactiveUniqueResultOptional();
diff --git a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/query/spi/ReactiveAbstractSelectionQuery.java b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/query/spi/ReactiveAbstractSelectionQuery.java
index 69ebe52a1c..f01b5d3150 100644
--- a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/query/spi/ReactiveAbstractSelectionQuery.java
+++ b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/query/spi/ReactiveAbstractSelectionQuery.java
@@ -21,6 +21,8 @@
 import org.hibernate.engine.spi.SharedSessionContractImplementor;
 import org.hibernate.query.IllegalQueryOperationException;
 import org.hibernate.query.hql.internal.QuerySplitter;
+import org.hibernate.query.internal.DelegatingDomainQueryExecutionContext;
+import org.hibernate.query.spi.DomainQueryExecutionContext;
 import org.hibernate.query.spi.QueryInterpretationCache;
 import org.hibernate.query.spi.QueryOptions;
 import org.hibernate.query.sqm.internal.DomainParameterXref;
@@ -33,6 +35,7 @@
 import org.hibernate.reactive.query.sqm.internal.AggregatedSelectReactiveQueryPlan;
 import org.hibernate.reactive.query.sqm.internal.ConcreteSqmSelectReactiveQueryPlan;
 import org.hibernate.reactive.query.sqm.spi.ReactiveSelectQueryPlan;
+import org.hibernate.reactive.sql.results.spi.ReactiveSingleResultConsumer;
 import org.hibernate.sql.results.internal.TupleMetadata;
 
 import jakarta.persistence.NoResultException;
@@ -146,6 +149,17 @@ public CompletionStage<R> getReactiveSingleResult() {
 				.exceptionally( this::convertException );
 	}
 
+	public CompletionStage<Long> getReactiveResultsCount(SqmSelectStatement<?> sqmStatement, DomainQueryExecutionContext domainQueryExecutionContext) {
+		final DelegatingDomainQueryExecutionContext context = new DelegatingDomainQueryExecutionContext( domainQueryExecutionContext ) {
+			@Override
+			public QueryOptions getQueryOptions() {
+				return QueryOptions.NONE;
+			}
+		};
+		return buildConcreteSelectQueryPlan( sqmStatement.createCountQuery(), Long.class, getQueryOptions() )
+				.reactiveExecuteQuery( context, new ReactiveSingleResultConsumer<>() );
+	}
+
 	private R reactiveSingleResult(List<R> list) {
 		if ( list.isEmpty() ) {
 			throw new NoResultException( String.format( "No result found for query [%s]", getQueryString() ) );
@@ -269,7 +283,7 @@ private ReactiveSelectQueryPlan<R> buildAggregatedSelectQueryPlan(SqmSelectState
 		return new AggregatedSelectReactiveQueryPlan<>(  aggregatedQueryPlans );
 	}
 
-	private <T> ReactiveSelectQueryPlan<T> buildConcreteSelectQueryPlan(
+	public  <T> ReactiveSelectQueryPlan<T> buildConcreteSelectQueryPlan(
 			SqmSelectStatement<?> concreteSqmStatement,
 			Class<T> resultType,
 			QueryOptions queryOptions) {
diff --git a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/query/sql/internal/ReactiveNativeQueryImpl.java b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/query/sql/internal/ReactiveNativeQueryImpl.java
index a441b4b555..1c97f847a3 100644
--- a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/query/sql/internal/ReactiveNativeQueryImpl.java
+++ b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/query/sql/internal/ReactiveNativeQueryImpl.java
@@ -93,6 +93,16 @@ private <T> T getNull() {
 		return null;
 	}
 
+	@Override
+	public long getResultCount() {
+		throw LOG.nonReactiveMethodCall( "getReactiveResultCount()" );
+	}
+
+	@Override
+	public CompletionStage<Long> getReactiveResultCount() {
+		throw LOG.notYetImplemented();
+	}
+
 	private ReactiveAbstractSelectionQuery<R> createSelectionQueryDelegate(SharedSessionContractImplementor session) {
 		return new ReactiveAbstractSelectionQuery<>(
 				this::getQueryOptions,
diff --git a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/query/sqm/internal/ConcreteSqmSelectReactiveQueryPlan.java b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/query/sqm/internal/ConcreteSqmSelectReactiveQueryPlan.java
index 16135b9a2c..858e2d2098 100644
--- a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/query/sqm/internal/ConcreteSqmSelectReactiveQueryPlan.java
+++ b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/query/sqm/internal/ConcreteSqmSelectReactiveQueryPlan.java
@@ -36,6 +36,7 @@
 import org.hibernate.reactive.query.sqm.spi.ReactiveSelectQueryPlan;
 import org.hibernate.reactive.sql.exec.internal.StandardReactiveSelectExecutor;
 import org.hibernate.reactive.sql.results.spi.ReactiveListResultsConsumer;
+import org.hibernate.reactive.sql.results.spi.ReactiveResultsConsumer;
 import org.hibernate.sql.ast.SqlAstTranslator;
 import org.hibernate.sql.ast.SqlAstTranslatorFactory;
 import org.hibernate.sql.ast.spi.FromClauseAccess;
@@ -59,6 +60,7 @@
 public class ConcreteSqmSelectReactiveQueryPlan<R> extends ConcreteSqmSelectQueryPlan<R>
 		implements ReactiveSelectQueryPlan<R> {
 
+	private final SqmInterpreter<Object, ReactiveResultsConsumer<Object, R>> executeQueryInterpreter;
 	private final SqmInterpreter<List<R>, Void> listInterpreter;
 	private final RowTransformer<R> rowTransformer;
 
@@ -80,6 +82,8 @@ public ConcreteSqmSelectReactiveQueryPlan(
 		this.rowTransformer = determineRowTransformer( sqm, resultType, tupleMetadata, queryOptions );
 		this.listInterpreter = (unused, executionContext, sqmInterpretation, jdbcParameterBindings) ->
 				listInterpreter( hql, domainParameterXref, executionContext, sqmInterpretation, jdbcParameterBindings, rowTransformer );
+		this.executeQueryInterpreter = (resultsConsumer, executionContext, sqmInterpretation, jdbcParameterBindings) ->
+				executeQueryInterpreter( hql, domainParameterXref, executionContext, sqmInterpretation, jdbcParameterBindings, rowTransformer, resultsConsumer );
 	}
 
 	private static <R> CompletionStage<List<R>> listInterpreter(
@@ -110,6 +114,40 @@ private static <R> CompletionStage<List<R>> listInterpreter(
 				.whenComplete( (rs, t) -> domainParameterXref.clearExpansions() );
 	}
 
+	private static <R> CompletionStage<Object> executeQueryInterpreter(
+			String hql,
+			DomainParameterXref domainParameterXref,
+			DomainQueryExecutionContext executionContext,
+			CacheableSqmInterpretation sqmInterpretation,
+			JdbcParameterBindings jdbcParameterBindings,
+			RowTransformer<R> rowTransformer,
+			ReactiveResultsConsumer<Object, R> resultsConsumer) {
+		final ReactiveSharedSessionContractImplementor session = (ReactiveSharedSessionContractImplementor) executionContext.getSession();
+		final JdbcOperationQuerySelect jdbcSelect = sqmInterpretation.getJdbcSelect();
+		// I'm using a supplier so that the whenComplete at the end will catch any errors, like a finally-block
+		Supplier<SubselectFetch.RegistrationHandler> fetchHandlerSupplier = () -> SubselectFetch
+				.createRegistrationHandler( session.getPersistenceContext().getBatchFetchQueue(), sqmInterpretation.selectStatement, JdbcParametersList.empty(), jdbcParameterBindings );
+		return completedFuture( fetchHandlerSupplier )
+				.thenApply( Supplier::get )
+				.thenCompose( subSelectFetchKeyHandler ->  session
+						.reactiveAutoFlushIfRequired( jdbcSelect.getAffectedTableNames() )
+						.thenCompose( required -> StandardReactiveSelectExecutor.INSTANCE
+								.executeQuery( jdbcSelect,
+									   jdbcParameterBindings,
+									   ConcreteSqmSelectQueryPlan.listInterpreterExecutionContext( hql, executionContext, jdbcSelect, subSelectFetchKeyHandler ),
+									   rowTransformer,
+									   null,
+									   sql -> executionContext.getSession()
+											   .getJdbcCoordinator()
+											   .getStatementPreparer()
+											   .prepareQueryStatement( sql, false, null ),
+									   resultsConsumer
+								)
+						)
+				)
+				.whenComplete( (rs, t) -> domainParameterXref.clearExpansions() );
+	}
+
 	@Override
 	public ScrollableResultsImplementor<R> performScroll(ScrollMode scrollMode, DomainQueryExecutionContext executionContext) {
 		throw new UnsupportedOperationException();
@@ -119,10 +157,21 @@ public ScrollableResultsImplementor<R> performScroll(ScrollMode scrollMode, Doma
 	public CompletionStage<List<R>> reactivePerformList(DomainQueryExecutionContext executionContext) {
 		return executionContext.getQueryOptions().getEffectiveLimit().getMaxRowsJpa() == 0
 				? completedFuture( emptyList() )
-				: withCacheableSqmInterpretation( executionContext, listInterpreter );
+				: withCacheableSqmInterpretation( executionContext, null, listInterpreter );
+	}
+
+	@Override
+	public <T> CompletionStage<T> reactiveExecuteQuery(
+			DomainQueryExecutionContext executionContext,
+			ReactiveResultsConsumer<T, R> resultsConsumer) {
+		return withCacheableSqmInterpretation(
+				executionContext,
+				resultsConsumer,
+				(SqmInterpreter<T, ReactiveResultsConsumer<T, R>>) (SqmInterpreter) executeQueryInterpreter
+		);
 	}
 
-	private <T, X> CompletionStage<T> withCacheableSqmInterpretation(DomainQueryExecutionContext executionContext, SqmInterpreter<T, X> interpreter) {
+	private <T, X> CompletionStage<T> withCacheableSqmInterpretation(DomainQueryExecutionContext executionContext, X context, SqmInterpreter<T, X> interpreter) {
 		// NOTE : VERY IMPORTANT - intentional double-lock checking
 		//		The other option would be to leverage `java.util.concurrent.locks.ReadWriteLock`
 		//		to protect access.  However, synchronized is much simpler here.  We will verify
@@ -162,7 +211,7 @@ private <T, X> CompletionStage<T> withCacheableSqmInterpretation(DomainQueryExec
 			jdbcParameterBindings = createJdbcParameterBindings( localCopy, executionContext );
 		}
 
-		return interpreter.interpret( null, executionContext, localCopy, jdbcParameterBindings );
+		return interpreter.interpret( context, executionContext, localCopy, jdbcParameterBindings );
 	}
 
 	private JdbcParameterBindings createJdbcParameterBindings(CacheableSqmInterpretation sqmInterpretation, DomainQueryExecutionContext executionContext) {
diff --git a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/query/sqm/internal/ReactiveQuerySqmImpl.java b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/query/sqm/internal/ReactiveQuerySqmImpl.java
index 3c23e6c765..fbe3295d68 100644
--- a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/query/sqm/internal/ReactiveQuerySqmImpl.java
+++ b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/query/sqm/internal/ReactiveQuerySqmImpl.java
@@ -139,6 +139,17 @@ public CompletionStage<R> getReactiveSingleResult() {
 		return selectionQueryDelegate.getReactiveSingleResult();
 	}
 
+	@Override
+	public long getResultCount() {
+		throw LOG.nonReactiveMethodCall( "getReactiveResultCount()" );
+	}
+
+	@Override
+	public CompletionStage<Long> getReactiveResultCount() {
+		return selectionQueryDelegate
+				.getReactiveResultsCount( ( (SqmSelectStatement<?>) getSqmStatement() ).createCountQuery(), this );
+	}
+
 	@Override
 	public CompletionStage<R> getReactiveSingleResultOrNull() {
 		return selectionQueryDelegate.getReactiveSingleResultOrNull();
diff --git a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/query/sqm/internal/ReactiveSqmSelectionQueryImpl.java b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/query/sqm/internal/ReactiveSqmSelectionQueryImpl.java
index 138f996a4c..13e1676979 100644
--- a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/query/sqm/internal/ReactiveSqmSelectionQueryImpl.java
+++ b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/query/sqm/internal/ReactiveSqmSelectionQueryImpl.java
@@ -212,6 +212,12 @@ public R getSingleResultOrNull() {
 		return selectionQueryDelegate.getSingleResultOrNull();
 	}
 
+	@Override
+	public CompletionStage<Long> getReactiveResultCount() {
+		return selectionQueryDelegate
+				.getReactiveResultsCount( getSqmStatement().createCountQuery(), this );
+	}
+
 	@Override
 	public List<R> getResultList() {
 		return selectionQueryDelegate.getResultList();
diff --git a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/query/sqm/spi/ReactiveSelectQueryPlan.java b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/query/sqm/spi/ReactiveSelectQueryPlan.java
index c83a6883f9..6ef50764cb 100644
--- a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/query/sqm/spi/ReactiveSelectQueryPlan.java
+++ b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/query/sqm/spi/ReactiveSelectQueryPlan.java
@@ -14,6 +14,7 @@
 import org.hibernate.query.spi.ScrollableResultsImplementor;
 import org.hibernate.query.spi.SelectQueryPlan;
 import org.hibernate.reactive.logging.impl.Log;
+import org.hibernate.reactive.sql.results.spi.ReactiveResultsConsumer;
 import org.hibernate.sql.results.spi.ResultsConsumer;
 
 import static org.hibernate.reactive.logging.impl.LoggerFactory.make;
@@ -44,7 +45,7 @@ default <T> T executeQuery(DomainQueryExecutionContext executionContext, Results
 	/**
 	 * Execute the query
 	 */
-	default <T> CompletionStage<T> reactiveExecuteQuery(DomainQueryExecutionContext executionContext, ResultsConsumer<T, R> resultsConsumer) {
+	default <T> CompletionStage<T> reactiveExecuteQuery(DomainQueryExecutionContext executionContext, ReactiveResultsConsumer<T, R> resultsConsumer) {
 		return failedFuture( new UnsupportedOperationException() );
 	}
 
diff --git a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/sql/results/internal/ReactiveInitializersList.java b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/sql/results/internal/ReactiveInitializersList.java
index d861cddc4c..e752a49ca0 100644
--- a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/sql/results/internal/ReactiveInitializersList.java
+++ b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/sql/results/internal/ReactiveInitializersList.java
@@ -56,6 +56,12 @@ public void finishUpRow(final RowProcessingState rowProcessingState) {
 		}
 	}
 
+	public void startLoading(final RowProcessingState rowProcessingState) {
+		for ( int i = initializers.length - 1; i >= 0; i-- ) {
+			initializers[i].startLoading( rowProcessingState );
+		}
+	}
+
 	public CompletionStage<Void> initializeInstance(final ReactiveRowProcessingState rowProcessingState) {
 		return loop( initializers, initializer -> {
 			if ( initializer instanceof ReactiveInitializer ) {
diff --git a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/sql/results/spi/ReactiveSingleResultConsumer.java b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/sql/results/spi/ReactiveSingleResultConsumer.java
new file mode 100644
index 0000000000..ad3d17853a
--- /dev/null
+++ b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/sql/results/spi/ReactiveSingleResultConsumer.java
@@ -0,0 +1,46 @@
+/* Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * Copyright: Red Hat Inc. and Hibernate Authors
+ */
+package org.hibernate.reactive.sql.results.spi;
+
+import java.util.concurrent.CompletionStage;
+
+import org.hibernate.Incubating;
+import org.hibernate.engine.spi.SharedSessionContractImplementor;
+import org.hibernate.reactive.sql.exec.spi.ReactiveRowProcessingState;
+import org.hibernate.reactive.sql.exec.spi.ReactiveValuesResultSet;
+import org.hibernate.sql.results.jdbc.internal.JdbcValuesSourceProcessingStateStandardImpl;
+import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingOptions;
+
+@Incubating
+public class ReactiveSingleResultConsumer<T> implements ReactiveResultsConsumer<T, T> {
+
+	@Override
+	public CompletionStage<T> consume(
+			ReactiveValuesResultSet jdbcValues,
+			SharedSessionContractImplementor session,
+			JdbcValuesSourceProcessingOptions processingOptions,
+			JdbcValuesSourceProcessingStateStandardImpl jdbcValuesSourceProcessingState,
+			ReactiveRowProcessingState rowProcessingState,
+			ReactiveRowReader<T> rowReader) {
+		rowReader.getReactiveInitializersList().startLoading( rowProcessingState );
+		return rowProcessingState.next()
+				.thenCompose( hasNext -> rowReader
+						.reactiveReadRow( rowProcessingState, processingOptions )
+						.thenApply( result -> {
+							rowProcessingState.finishRowProcessing( true );
+							rowReader.finishUp( jdbcValuesSourceProcessingState );
+							jdbcValuesSourceProcessingState.finishUp( false );
+							return result;
+						} )
+				);
+	}
+
+	@Override
+	public boolean canResultsBeCached() {
+		return false;
+	}
+
+}
diff --git a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/stage/Stage.java b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/stage/Stage.java
index 5fc1d671ee..47da9f6cff 100644
--- a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/stage/Stage.java
+++ b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/stage/Stage.java
@@ -5,20 +5,18 @@
  */
 package org.hibernate.reactive.stage;
 
-import jakarta.persistence.CacheRetrieveMode;
-import jakarta.persistence.CacheStoreMode;
-import jakarta.persistence.EntityGraph;
-import jakarta.persistence.FlushModeType;
-import jakarta.persistence.LockModeType;
-import jakarta.persistence.Parameter;
-import jakarta.persistence.criteria.CriteriaBuilder;
-import jakarta.persistence.criteria.CriteriaDelete;
-import jakarta.persistence.criteria.CriteriaQuery;
-import jakarta.persistence.criteria.CriteriaUpdate;
-import jakarta.persistence.metamodel.Attribute;
-import jakarta.persistence.metamodel.Metamodel;
+import java.lang.invoke.MethodHandles;
+import java.util.List;
+import java.util.concurrent.CompletionStage;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
 import org.hibernate.Cache;
-import org.hibernate.*;
+import org.hibernate.CacheMode;
+import org.hibernate.Filter;
+import org.hibernate.FlushMode;
+import org.hibernate.Incubating;
+import org.hibernate.LockMode;
 import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLazinessInterceptor;
 import org.hibernate.collection.spi.AbstractPersistentCollection;
 import org.hibernate.collection.spi.PersistentCollection;
@@ -38,16 +36,25 @@
 import org.hibernate.reactive.util.impl.CompletionStages;
 import org.hibernate.stat.Statistics;
 
-import java.lang.invoke.MethodHandles;
-import java.util.List;
-import java.util.concurrent.CompletionStage;
-import java.util.function.BiFunction;
-import java.util.function.Function;
+import jakarta.persistence.CacheRetrieveMode;
+import jakarta.persistence.CacheStoreMode;
+import jakarta.persistence.EntityGraph;
+import jakarta.persistence.FlushModeType;
+import jakarta.persistence.LockModeType;
+import jakarta.persistence.Parameter;
+import jakarta.persistence.criteria.CriteriaBuilder;
+import jakarta.persistence.criteria.CriteriaDelete;
+import jakarta.persistence.criteria.CriteriaQuery;
+import jakarta.persistence.criteria.CriteriaUpdate;
+import jakarta.persistence.metamodel.Attribute;
+import jakarta.persistence.metamodel.Metamodel;
 
 import static org.hibernate.engine.internal.ManagedTypeHelper.asPersistentAttributeInterceptable;
 import static org.hibernate.engine.internal.ManagedTypeHelper.isPersistentAttributeInterceptable;
 import static org.hibernate.internal.util.LockModeConverter.convertToLockMode;
-import static org.hibernate.jpa.internal.util.CacheModeHelper.*;
+import static org.hibernate.jpa.internal.util.CacheModeHelper.interpretCacheMode;
+import static org.hibernate.jpa.internal.util.CacheModeHelper.interpretCacheRetrieveMode;
+import static org.hibernate.jpa.internal.util.CacheModeHelper.interpretCacheStoreMode;
 
 /**
  * An API for Hibernate Reactive where non-blocking operations are
@@ -188,6 +195,17 @@ interface SelectionQuery<R> extends AbstractQuery {
 		 */
 		CompletionStage<R> getSingleResultOrNull();
 
+		/**
+		 * Determine the size of the query result list that would be
+		 * returned by calling {@link #getResultList()} with no
+		 * {@linkplain #getFirstResult() offset} or
+		 * {@linkplain #getMaxResults() limit} applied to the query.
+		 *
+		 * @return the size of the list that would be returned
+		 */
+		@Incubating
+		CompletionStage<Long> getResultCount();
+
 		/**
 		 * Asynchronously execute this query, returning the query results
 		 * as a {@link List}, via a {@link CompletionStage}. If the query
diff --git a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/stage/impl/StageQueryImpl.java b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/stage/impl/StageQueryImpl.java
index 3a4948275a..fb022c4997 100644
--- a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/stage/impl/StageQueryImpl.java
+++ b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/stage/impl/StageQueryImpl.java
@@ -38,6 +38,11 @@ public int getMaxResults() {
 		return delegate.getMaxResults();
 	}
 
+	@Override
+	public CompletionStage<Long> getResultCount() {
+		return delegate.getReactiveResultCount();
+	}
+
 	@Override
 	public CompletionStage<List<R>> getResultList() {
 		return delegate.getReactiveResultList();
diff --git a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/stage/impl/StageSelectionQueryImpl.java b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/stage/impl/StageSelectionQueryImpl.java
index f28bfd9d03..6a1be5d084 100644
--- a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/stage/impl/StageSelectionQueryImpl.java
+++ b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/stage/impl/StageSelectionQueryImpl.java
@@ -41,6 +41,11 @@ public int getMaxResults() {
 		return delegate.getMaxResults();
 	}
 
+	@Override
+	public CompletionStage<Long> getResultCount() {
+		return delegate.getReactiveResultCount();
+	}
+
 	@Override
 	public CompletionStage<List<T>> getResultList() {
 		return delegate.getReactiveResultList();