diff --git a/engine/src/main/java/org/hibernate/validator/BaseHibernateValidatorConfiguration.java b/engine/src/main/java/org/hibernate/validator/BaseHibernateValidatorConfiguration.java
index 93eb1900f6..5d63d81bd9 100644
--- a/engine/src/main/java/org/hibernate/validator/BaseHibernateValidatorConfiguration.java
+++ b/engine/src/main/java/org/hibernate/validator/BaseHibernateValidatorConfiguration.java
@@ -363,6 +363,18 @@ public interface BaseHibernateValidatorConfiguration<S extends BaseHibernateVali
 	@Incubating
 	S constraintValidatorPayload(Object constraintValidatorPayload);
 
+	/**
+	 * Allows adding a payload which will be  available during the constraint validators initialization.
+	 * If the method is called multiple times passing different instances of the same class,
+	 * only the payload passed last will be available for that type.
+	 *
+	 * @param constraintValidatorInitializationPayload the payload to retrieve from the constraint validator initializers
+	 * @return {@code this} following the chaining method pattern
+	 * @since 9.0.0
+	 */
+	@Incubating
+	S addConstraintValidatorInitializationPayload(Object constraintValidatorInitializationPayload);
+
 	/**
 	 * Allows to set a getter property selection strategy defining the rules determining if a method is a getter
 	 * or not.
diff --git a/engine/src/main/java/org/hibernate/validator/constraintvalidation/HibernateConstraintValidatorInitializationContext.java b/engine/src/main/java/org/hibernate/validator/constraintvalidation/HibernateConstraintValidatorInitializationContext.java
index 24f5cd4d38..0956a8a055 100644
--- a/engine/src/main/java/org/hibernate/validator/constraintvalidation/HibernateConstraintValidatorInitializationContext.java
+++ b/engine/src/main/java/org/hibernate/validator/constraintvalidation/HibernateConstraintValidatorInitializationContext.java
@@ -56,4 +56,18 @@ public interface HibernateConstraintValidatorInitializationContext {
 	 */
 	@Incubating
 	Duration getTemporalValidationTolerance();
+
+	/**
+	 * Returns an instance of the specified type or {@code null} if the current constraint initialization context does not
+	 * contain an instance of such type.
+	 *
+	 * @param type the type of payload to retrieve
+	 * @return an instance of the specified type or {@code null} if the current constraint initialization context does not
+	 * contain an instance of such type
+	 *
+	 * @since 9.0.0
+	 * @see org.hibernate.validator.HibernateValidatorConfiguration#addConstraintValidatorInitializationPayload(Object)
+	 */
+	@Incubating
+	<C> C getConstraintValidatorInitializationPayload(Class<C> type);
 }
diff --git a/engine/src/main/java/org/hibernate/validator/internal/constraintvalidators/bv/PatternValidator.java b/engine/src/main/java/org/hibernate/validator/internal/constraintvalidators/bv/PatternValidator.java
index 6475693b76..1eb9d2e217 100644
--- a/engine/src/main/java/org/hibernate/validator/internal/constraintvalidators/bv/PatternValidator.java
+++ b/engine/src/main/java/org/hibernate/validator/internal/constraintvalidators/bv/PatternValidator.java
@@ -8,11 +8,14 @@
 import java.util.regex.Matcher;
 import java.util.regex.PatternSyntaxException;
 
-import jakarta.validation.ConstraintValidator;
 import jakarta.validation.ConstraintValidatorContext;
 import jakarta.validation.constraints.Pattern;
+import jakarta.validation.metadata.ConstraintDescriptor;
 
+import org.hibernate.validator.constraintvalidation.HibernateConstraintValidator;
 import org.hibernate.validator.constraintvalidation.HibernateConstraintValidatorContext;
+import org.hibernate.validator.constraintvalidation.HibernateConstraintValidatorInitializationContext;
+import org.hibernate.validator.internal.engine.constraintvalidation.PatternConstraintInitializer;
 import org.hibernate.validator.internal.engine.messageinterpolation.util.InterpolationHelper;
 import org.hibernate.validator.internal.util.logging.Log;
 import org.hibernate.validator.internal.util.logging.LoggerFactory;
@@ -20,7 +23,7 @@
 /**
  * @author Hardy Ferentschik
  */
-public class PatternValidator implements ConstraintValidator<Pattern, CharSequence> {
+public class PatternValidator implements HibernateConstraintValidator<Pattern, CharSequence> {
 
 	private static final Log LOG = LoggerFactory.make( MethodHandles.lookup() );
 
@@ -28,7 +31,8 @@ public class PatternValidator implements ConstraintValidator<Pattern, CharSequen
 	private String escapedRegexp;
 
 	@Override
-	public void initialize(Pattern parameters) {
+	public void initialize(ConstraintDescriptor<Pattern> constraintDescriptor, HibernateConstraintValidatorInitializationContext initializationContext) {
+		Pattern parameters = constraintDescriptor.getAnnotation();
 		Pattern.Flag[] flags = parameters.flags();
 		int intFlag = 0;
 		for ( Pattern.Flag flag : flags ) {
@@ -36,7 +40,8 @@ public void initialize(Pattern parameters) {
 		}
 
 		try {
-			pattern = java.util.regex.Pattern.compile( parameters.regexp(), intFlag );
+			pattern = initializationContext.getConstraintValidatorInitializationPayload( PatternConstraintInitializer.class )
+					.of( parameters.regexp(), intFlag );
 		}
 		catch (PatternSyntaxException e) {
 			throw LOG.getInvalidRegularExpressionException( e );
diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/AbstractConfigurationImpl.java b/engine/src/main/java/org/hibernate/validator/internal/engine/AbstractConfigurationImpl.java
index 61a9436457..b199d6cf99 100644
--- a/engine/src/main/java/org/hibernate/validator/internal/engine/AbstractConfigurationImpl.java
+++ b/engine/src/main/java/org/hibernate/validator/internal/engine/AbstractConfigurationImpl.java
@@ -4,6 +4,7 @@
  */
 package org.hibernate.validator.internal.engine;
 
+import static org.hibernate.validator.internal.util.CollectionHelper.newHashMap;
 import static org.hibernate.validator.internal.util.CollectionHelper.newHashSet;
 import static org.hibernate.validator.internal.util.logging.Messages.MESSAGES;
 
@@ -122,6 +123,7 @@ public abstract class AbstractConfigurationImpl<T extends BaseHibernateValidator
 	private ScriptEvaluatorFactory scriptEvaluatorFactory;
 	private Duration temporalValidationTolerance;
 	private Object constraintValidatorPayload;
+	private final Map<Class<?>, Object> constraintValidatorInitializationPayload = newHashMap();
 	private GetterPropertySelectionStrategy getterPropertySelectionStrategy;
 	private Set<Locale> locales = Collections.emptySet();
 	private Locale defaultLocale = Locale.getDefault();
@@ -350,6 +352,14 @@ public T constraintValidatorPayload(Object constraintValidatorPayload) {
 		return thisAsT();
 	}
 
+	@Override
+	public T addConstraintValidatorInitializationPayload(Object constraintValidatorInitializationPayload) {
+		Contracts.assertNotNull( constraintValidatorInitializationPayload, MESSAGES.parameterMustNotBeNull( "constraintValidatorInitializationPayload" ) );
+
+		this.constraintValidatorInitializationPayload.put( constraintValidatorInitializationPayload.getClass(), constraintValidatorInitializationPayload );
+		return thisAsT();
+	}
+
 	@Override
 	public T getterPropertySelectionStrategy(GetterPropertySelectionStrategy getterPropertySelectionStrategy) {
 		Contracts.assertNotNull( getterPropertySelectionStrategy, MESSAGES.parameterMustNotBeNull( "getterPropertySelectionStrategy" ) );
@@ -546,6 +556,10 @@ public Object getConstraintValidatorPayload() {
 		return constraintValidatorPayload;
 	}
 
+	public Map<Class<?>, Object> getConstraintValidatorInitializationPayload() {
+		return constraintValidatorInitializationPayload;
+	}
+
 	public GetterPropertySelectionStrategy getGetterPropertySelectionStrategy() {
 		return getterPropertySelectionStrategy;
 	}
diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/PredefinedScopeValidatorFactoryImpl.java b/engine/src/main/java/org/hibernate/validator/internal/engine/PredefinedScopeValidatorFactoryImpl.java
index 1fc874b195..60ae1d06c0 100644
--- a/engine/src/main/java/org/hibernate/validator/internal/engine/PredefinedScopeValidatorFactoryImpl.java
+++ b/engine/src/main/java/org/hibernate/validator/internal/engine/PredefinedScopeValidatorFactoryImpl.java
@@ -10,6 +10,7 @@
 import static org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper.determineBeanMetaDataClassNormalizer;
 import static org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper.determineConstraintExpressionLanguageFeatureLevel;
 import static org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper.determineConstraintMappings;
+import static org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper.determineConstraintValidatorInitializationPayload;
 import static org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper.determineConstraintValidatorPayload;
 import static org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper.determineCustomViolationExpressionLanguageFeatureLevel;
 import static org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper.determineExternalClassLoader;
@@ -46,6 +47,7 @@
 import org.hibernate.validator.PredefinedScopeHibernateValidatorFactory;
 import org.hibernate.validator.internal.cfg.context.DefaultConstraintMapping;
 import org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManager;
+import org.hibernate.validator.internal.engine.constraintvalidation.PatternConstraintInitializer;
 import org.hibernate.validator.internal.engine.constraintvalidation.PredefinedScopeConstraintValidatorManagerImpl;
 import org.hibernate.validator.internal.engine.groups.ValidationOrderGenerator;
 import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorManager;
@@ -118,6 +120,7 @@ public PredefinedScopeValidatorFactoryImpl(ConfigurationState configurationState
 						determineAllowParallelMethodsDefineParameterConstraints( hibernateSpecificConfig, properties )
 				).build();
 
+		PatternConstraintInitializer.CachingPatternConstraintInitializer patternConstraintInitializer = new PatternConstraintInitializer.CachingPatternConstraintInitializer();
 		this.validatorFactoryScopedContext = new ValidatorFactoryScopedContext(
 				configurationState.getMessageInterpolator(),
 				configurationState.getTraversableResolver(),
@@ -129,6 +132,7 @@ public PredefinedScopeValidatorFactoryImpl(ConfigurationState configurationState
 				determineFailFastOnPropertyViolation( hibernateSpecificConfig, properties ),
 				determineTraversableResolverResultCacheEnabled( hibernateSpecificConfig, properties ),
 				determineConstraintValidatorPayload( hibernateSpecificConfig ),
+				determineConstraintValidatorInitializationPayload( hibernateSpecificConfig, patternConstraintInitializer ),
 				determineConstraintExpressionLanguageFeatureLevel( hibernateSpecificConfig, properties ),
 				determineCustomViolationExpressionLanguageFeatureLevel( hibernateSpecificConfig, properties ),
 				determineShowValidatedValuesInTraceLogs( hibernateSpecificConfig, properties )
@@ -214,6 +218,9 @@ public PredefinedScopeValidatorFactoryImpl(ConfigurationState configurationState
 				beanClassesToInitialize
 		);
 
+		// at this point all constraints had to be initialized, so we can clear up the pattern cache:
+		patternConstraintInitializer.close();
+
 		if ( LOG.isDebugEnabled() ) {
 			logValidatorFactoryScopedConfiguration( validatorFactoryScopedContext );
 		}
diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorFactoryConfigurationHelper.java b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorFactoryConfigurationHelper.java
index e835053b55..33f806e93f 100644
--- a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorFactoryConfigurationHelper.java
+++ b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorFactoryConfigurationHelper.java
@@ -11,6 +11,7 @@
 import java.lang.invoke.MethodHandles;
 import java.time.Duration;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -21,6 +22,7 @@
 import org.hibernate.validator.cfg.ConstraintMapping;
 import org.hibernate.validator.internal.cfg.context.DefaultConstraintMapping;
 import org.hibernate.validator.internal.engine.constraintdefinition.ConstraintDefinitionContribution;
+import org.hibernate.validator.internal.engine.constraintvalidation.PatternConstraintInitializer;
 import org.hibernate.validator.internal.engine.messageinterpolation.DefaultLocaleResolver;
 import org.hibernate.validator.internal.engine.scripting.DefaultScriptEvaluatorFactory;
 import org.hibernate.validator.internal.metadata.DefaultBeanMetaDataClassNormalizer;
@@ -252,8 +254,7 @@ static Duration determineTemporalValidationTolerance(ConfigurationState configur
 	}
 
 	static Object determineConstraintValidatorPayload(ConfigurationState configurationState) {
-		if ( configurationState instanceof AbstractConfigurationImpl ) {
-			AbstractConfigurationImpl<?> hibernateSpecificConfig = (AbstractConfigurationImpl<?>) configurationState;
+		if ( configurationState instanceof AbstractConfigurationImpl<?> hibernateSpecificConfig ) {
 			if ( hibernateSpecificConfig.getConstraintValidatorPayload() != null ) {
 				LOG.logConstraintValidatorPayload( hibernateSpecificConfig.getConstraintValidatorPayload() );
 				return hibernateSpecificConfig.getConstraintValidatorPayload();
@@ -263,6 +264,23 @@ static Object determineConstraintValidatorPayload(ConfigurationState configurati
 		return null;
 	}
 
+	static Map<Class<?>, Object> determineConstraintValidatorInitializationPayload(ConfigurationState configurationState, PatternConstraintInitializer patternConstraintInitializer) {
+		if ( configurationState instanceof AbstractConfigurationImpl<?> hibernateSpecificConfig ) {
+			if ( hibernateSpecificConfig.getConstraintValidatorPayload() != null ) {
+				Map<Class<?>, Object> configured = hibernateSpecificConfig.getConstraintValidatorInitializationPayload();
+				Map<Class<?>, Object> payload = new HashMap<>();
+				payload.put( PatternConstraintInitializer.class, patternConstraintInitializer );
+				if ( configured != null ) {
+					payload.putAll( configured );
+				}
+				LOG.logConstraintValidatorInitializationPayload( payload );
+				return Collections.unmodifiableMap( payload );
+			}
+		}
+
+		return Map.of( PatternConstraintInitializer.class, patternConstraintInitializer );
+	}
+
 	static ExpressionLanguageFeatureLevel determineConstraintExpressionLanguageFeatureLevel(AbstractConfigurationImpl<?> hibernateSpecificConfig,
 			Map<String, String> properties) {
 		if ( hibernateSpecificConfig != null && hibernateSpecificConfig.getConstraintExpressionLanguageFeatureLevel() != null ) {
diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorFactoryImpl.java b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorFactoryImpl.java
index b9b5a98419..5bac15a05c 100644
--- a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorFactoryImpl.java
+++ b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorFactoryImpl.java
@@ -10,6 +10,7 @@
 import static org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper.determineBeanMetaDataClassNormalizer;
 import static org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper.determineConstraintExpressionLanguageFeatureLevel;
 import static org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper.determineConstraintMappings;
+import static org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper.determineConstraintValidatorInitializationPayload;
 import static org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper.determineConstraintValidatorPayload;
 import static org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper.determineCustomViolationExpressionLanguageFeatureLevel;
 import static org.hibernate.validator.internal.engine.ValidatorFactoryConfigurationHelper.determineExternalClassLoader;
@@ -47,6 +48,7 @@
 import org.hibernate.validator.internal.cfg.context.DefaultConstraintMapping;
 import org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManager;
 import org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManagerImpl;
+import org.hibernate.validator.internal.engine.constraintvalidation.PatternConstraintInitializer;
 import org.hibernate.validator.internal.engine.groups.ValidationOrderGenerator;
 import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorManager;
 import org.hibernate.validator.internal.metadata.BeanMetaDataManager;
@@ -163,6 +165,7 @@ public ValidatorFactoryImpl(ConfigurationState configurationState) {
 				determineFailFastOnPropertyViolation( hibernateSpecificConfig, properties ),
 				determineTraversableResolverResultCacheEnabled( hibernateSpecificConfig, properties ),
 				determineConstraintValidatorPayload( hibernateSpecificConfig ),
+				determineConstraintValidatorInitializationPayload( hibernateSpecificConfig, new PatternConstraintInitializer.SimplePatternConstraintInitializer() ),
 				determineConstraintExpressionLanguageFeatureLevel( hibernateSpecificConfig, properties ),
 				determineCustomViolationExpressionLanguageFeatureLevel( hibernateSpecificConfig, properties ),
 				determineShowValidatedValuesInTraceLogs( hibernateSpecificConfig, properties )
diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorFactoryScopedContext.java b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorFactoryScopedContext.java
index 558b4a860b..d0179d5034 100644
--- a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorFactoryScopedContext.java
+++ b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorFactoryScopedContext.java
@@ -5,6 +5,7 @@
 package org.hibernate.validator.internal.engine;
 
 import java.time.Duration;
+import java.util.Map;
 
 import jakarta.validation.ClockProvider;
 import jakarta.validation.MessageInterpolator;
@@ -102,6 +103,7 @@ public class ValidatorFactoryScopedContext {
 			boolean failFastOnPropertyViolation,
 			boolean traversableResolverResultCacheEnabled,
 			Object constraintValidatorPayload,
+			Map<Class<?>, Object> constraintValidatorInitializationPayload,
 			ExpressionLanguageFeatureLevel constraintExpressionLanguageFeatureLevel,
 			ExpressionLanguageFeatureLevel customViolationExpressionLanguageFeatureLevel,
 			boolean showValidatedValuesInTraceLogs) {
@@ -109,7 +111,8 @@ public class ValidatorFactoryScopedContext {
 				failFastOnPropertyViolation, traversableResolverResultCacheEnabled, showValidatedValuesInTraceLogs, constraintValidatorPayload, constraintExpressionLanguageFeatureLevel,
 				customViolationExpressionLanguageFeatureLevel,
 				new HibernateConstraintValidatorInitializationContextImpl( scriptEvaluatorFactory, clockProvider,
-						temporalValidationTolerance ) );
+						temporalValidationTolerance, constraintValidatorInitializationPayload
+				) );
 	}
 
 	private ValidatorFactoryScopedContext(MessageInterpolator messageInterpolator,
@@ -214,7 +217,7 @@ static class Builder {
 		private ExpressionLanguageFeatureLevel customViolationExpressionLanguageFeatureLevel;
 
 		private boolean showValidatedValuesInTraceLogs;
-		private HibernateConstraintValidatorInitializationContextImpl constraintValidatorInitializationContext;
+		private final HibernateConstraintValidatorInitializationContextImpl constraintValidatorInitializationContext;
 
 		Builder(ValidatorFactoryScopedContext defaultContext) {
 			Contracts.assertNotNull( defaultContext, "Default context cannot be null." );
@@ -348,7 +351,8 @@ public ValidatorFactoryScopedContext build() {
 							constraintValidatorInitializationContext,
 							scriptEvaluatorFactory,
 							clockProvider,
-							temporalValidationTolerance
+							temporalValidationTolerance,
+							constraintValidatorInitializationContext.getConstraintValidatorInitializationPayload()
 					)
 			);
 		}
diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/constraintvalidation/HibernateConstraintValidatorInitializationContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/engine/constraintvalidation/HibernateConstraintValidatorInitializationContextImpl.java
index a3df91dc06..8b7bfb0ba5 100644
--- a/engine/src/main/java/org/hibernate/validator/internal/engine/constraintvalidation/HibernateConstraintValidatorInitializationContextImpl.java
+++ b/engine/src/main/java/org/hibernate/validator/internal/engine/constraintvalidation/HibernateConstraintValidatorInitializationContextImpl.java
@@ -5,6 +5,7 @@
 package org.hibernate.validator.internal.engine.constraintvalidation;
 
 import java.time.Duration;
+import java.util.Map;
 
 import jakarta.validation.ClockProvider;
 
@@ -23,25 +24,29 @@ public class HibernateConstraintValidatorInitializationContextImpl implements Hi
 
 	private final Duration temporalValidationTolerance;
 
+	private final Map<Class<?>, Object> constraintValidatorInitializationPayload;
+
 	private final int hashCode;
 
 	public HibernateConstraintValidatorInitializationContextImpl(ScriptEvaluatorFactory scriptEvaluatorFactory, ClockProvider clockProvider,
-			Duration temporalValidationTolerance) {
+			Duration temporalValidationTolerance, Map<Class<?>, Object> constraintValidatorInitializationPayload
+	) {
 		this.scriptEvaluatorFactory = scriptEvaluatorFactory;
 		this.clockProvider = clockProvider;
 		this.temporalValidationTolerance = temporalValidationTolerance;
+		this.constraintValidatorInitializationPayload = constraintValidatorInitializationPayload;
 		this.hashCode = createHashCode();
 	}
 
 	public static HibernateConstraintValidatorInitializationContextImpl of(HibernateConstraintValidatorInitializationContextImpl defaultContext,
-			ScriptEvaluatorFactory scriptEvaluatorFactory, ClockProvider clockProvider, Duration temporalValidationTolerance) {
+			ScriptEvaluatorFactory scriptEvaluatorFactory, ClockProvider clockProvider, Duration temporalValidationTolerance, Map<Class<?>, Object> constraintValidatorInitializationPayload) {
 		if ( scriptEvaluatorFactory == defaultContext.scriptEvaluatorFactory
 				&& clockProvider == defaultContext.clockProvider
 				&& temporalValidationTolerance.equals( defaultContext.temporalValidationTolerance ) ) {
 			return defaultContext;
 		}
 
-		return new HibernateConstraintValidatorInitializationContextImpl( scriptEvaluatorFactory, clockProvider, temporalValidationTolerance );
+		return new HibernateConstraintValidatorInitializationContextImpl( scriptEvaluatorFactory, clockProvider, temporalValidationTolerance, constraintValidatorInitializationPayload );
 	}
 
 	@Override
@@ -59,6 +64,16 @@ public Duration getTemporalValidationTolerance() {
 		return temporalValidationTolerance;
 	}
 
+	@SuppressWarnings("unchecked") // because of the way we populate that map
+	@Override
+	public <C> C getConstraintValidatorInitializationPayload(Class<C> type) {
+		return ( (C) constraintValidatorInitializationPayload.get( type ) );
+	}
+
+	public Map<Class<?>, Object> getConstraintValidatorInitializationPayload() {
+		return constraintValidatorInitializationPayload;
+	}
+
 	@Override
 	public boolean equals(Object o) {
 		if ( this == o ) {
diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/constraintvalidation/PatternConstraintInitializer.java b/engine/src/main/java/org/hibernate/validator/internal/engine/constraintvalidation/PatternConstraintInitializer.java
new file mode 100644
index 0000000000..59ad76c408
--- /dev/null
+++ b/engine/src/main/java/org/hibernate/validator/internal/engine/constraintvalidation/PatternConstraintInitializer.java
@@ -0,0 +1,44 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ * Copyright Red Hat Inc. and Hibernate Authors
+ */
+package org.hibernate.validator.internal.engine.constraintvalidation;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Pattern;
+
+public interface PatternConstraintInitializer extends AutoCloseable {
+
+	Pattern of(String pattern, int flags);
+
+	@Override
+	default void close() {
+	}
+
+	class SimplePatternConstraintInitializer implements PatternConstraintInitializer {
+
+		@Override
+		public Pattern of(String pattern, int flags) {
+			return Pattern.compile( pattern, flags );
+		}
+	}
+
+	class CachingPatternConstraintInitializer implements PatternConstraintInitializer {
+		private final Map<PatternKey, Pattern> cache = new ConcurrentHashMap<PatternKey, Pattern>();
+
+		@Override
+		public Pattern of(String pattern, int flags) {
+			return cache.computeIfAbsent( new PatternKey( pattern, flags ), key -> Pattern.compile( pattern, flags ) );
+		}
+
+		@Override
+		public void close() {
+			cache.clear();
+		}
+
+		private record PatternKey(String pattern, int flags) {
+		}
+	}
+
+}
diff --git a/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java b/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java
index 9b69aff753..bbf964815c 100644
--- a/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java
+++ b/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java
@@ -942,4 +942,8 @@ ConstraintDefinitionException getConstraintValidatorDefinitionConstraintMismatch
 	@Message(id = 268, value = "The default group sequence provider %s does not implement neither `getValidationGroups(Class<?> klass, T object)` nor `getValidationGroups(T object)` methods."
 			+ " One of them has to be implemented for the default group sequence provider to be correctly defined.")
 	GroupDefinitionException getDefaultGroupSequenceProviderTypeDoesNotImplementAnyMethodsException(@FormatWith(ClassObjectFormatter.class) Class<?> klass);
+
+	@LogMessage(level = DEBUG)
+	@Message(id = 269, value = "Constraint validator initialization payload set to %1$s.")
+	void logConstraintValidatorInitializationPayload(Object payload);
 }
diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/constraintvalidators/bv/PatternValidatorTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/constraintvalidators/bv/PatternValidatorTest.java
index ab287fbc2f..588bc91eed 100644
--- a/engine/src/test/java/org/hibernate/validator/test/internal/constraintvalidators/bv/PatternValidatorTest.java
+++ b/engine/src/test/java/org/hibernate/validator/test/internal/constraintvalidators/bv/PatternValidatorTest.java
@@ -4,6 +4,7 @@
  */
 package org.hibernate.validator.test.internal.constraintvalidators.bv;
 
+import static org.hibernate.validator.testutils.ConstraintValidatorInitializationHelper.initialize;
 import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertTrue;
 
@@ -26,10 +27,10 @@ public void testIsValid() {
 		ConstraintAnnotationDescriptor.Builder<Pattern> descriptorBuilder = new ConstraintAnnotationDescriptor.Builder<>( Pattern.class );
 		descriptorBuilder.setAttribute( "regexp", "foobar" );
 		descriptorBuilder.setMessage( "pattern does not match" );
-		Pattern p = descriptorBuilder.build().getAnnotation();
+		ConstraintAnnotationDescriptor<Pattern> descriptor = descriptorBuilder.build();
 
 		PatternValidator constraint = new PatternValidator();
-		constraint.initialize( p );
+		initialize( constraint, descriptor );
 
 		assertTrue( constraint.isValid( null, null ) );
 		assertFalse( constraint.isValid( "", null ) );
@@ -42,10 +43,10 @@ public void testIsValid() {
 	public void testIsValidForCharSequence() {
 		ConstraintAnnotationDescriptor.Builder<Pattern> descriptorBuilder = new ConstraintAnnotationDescriptor.Builder<>( Pattern.class );
 		descriptorBuilder.setAttribute( "regexp", "char sequence" );
-		Pattern p = descriptorBuilder.build().getAnnotation();
+		ConstraintAnnotationDescriptor<Pattern> descriptor = descriptorBuilder.build();
 
 		PatternValidator constraint = new PatternValidator();
-		constraint.initialize( p );
+		initialize( constraint, descriptor );
 
 		assertTrue( constraint.isValid( new MyCustomStringImpl( "char sequence" ), null ) );
 	}
@@ -55,10 +56,10 @@ public void testIsValidForEmptyStringRegexp() {
 		ConstraintAnnotationDescriptor.Builder<Pattern> descriptorBuilder = new ConstraintAnnotationDescriptor.Builder<>( Pattern.class );
 		descriptorBuilder.setAttribute( "regexp", "|^.*foo$" );
 		descriptorBuilder.setMessage( "pattern does not match" );
-		Pattern p = descriptorBuilder.build().getAnnotation();
+		ConstraintAnnotationDescriptor<Pattern> descriptor = descriptorBuilder.build();
 
 		PatternValidator constraint = new PatternValidator();
-		constraint.initialize( p );
+		initialize( constraint, descriptor );
 
 		assertTrue( constraint.isValid( null, null ) );
 		assertTrue( constraint.isValid( "", null ) );
@@ -72,9 +73,9 @@ public void testInvalidRegularExpression() {
 		ConstraintAnnotationDescriptor.Builder<Pattern> descriptorBuilder = new ConstraintAnnotationDescriptor.Builder<>( Pattern.class );
 		descriptorBuilder.setAttribute( "regexp", "(unbalanced parentheses" );
 		descriptorBuilder.setMessage( "pattern does not match" );
-		Pattern p = descriptorBuilder.build().getAnnotation();
+		ConstraintAnnotationDescriptor<Pattern> descriptor = descriptorBuilder.build();
 
 		PatternValidator constraint = new PatternValidator();
-		constraint.initialize( p );
+		initialize( constraint, descriptor );
 	}
 }
diff --git a/engine/src/test/java/org/hibernate/validator/testutils/ConstraintValidatorInitializationHelper.java b/engine/src/test/java/org/hibernate/validator/testutils/ConstraintValidatorInitializationHelper.java
index c99741b3ba..ab50f8d449 100644
--- a/engine/src/test/java/org/hibernate/validator/testutils/ConstraintValidatorInitializationHelper.java
+++ b/engine/src/test/java/org/hibernate/validator/testutils/ConstraintValidatorInitializationHelper.java
@@ -17,6 +17,7 @@
 import org.hibernate.validator.internal.engine.ConstraintCreationContext;
 import org.hibernate.validator.internal.engine.DefaultClockProvider;
 import org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManagerImpl;
+import org.hibernate.validator.internal.engine.constraintvalidation.PatternConstraintInitializer;
 import org.hibernate.validator.internal.engine.scripting.DefaultScriptEvaluatorFactory;
 import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorManager;
 import org.hibernate.validator.internal.metadata.core.ConstraintHelper;
@@ -96,6 +97,14 @@ public ClockProvider getClockProvider() {
 			public Duration getTemporalValidationTolerance() {
 				return duration;
 			}
+
+			@Override
+			public <C> C getConstraintValidatorInitializationPayload(Class<C> type) {
+				if ( PatternConstraintInitializer.class.equals( type ) ) {
+					return (C) new PatternConstraintInitializer.SimplePatternConstraintInitializer();
+				}
+				return null;
+			}
 		};
 	}
 }