diff --git a/src/wp-includes/rest-api.php b/src/wp-includes/rest-api.php
index 7602dd7405..6769221fd5 100644
--- a/src/wp-includes/rest-api.php
+++ b/src/wp-includes/rest-api.php
@@ -191,26 +191,22 @@ function rest_api_default_filters() {
  * @since 4.7.0
  */
 function create_initial_rest_routes() {
-	foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) {
-		$class = ! empty( $post_type->rest_controller_class ) ? $post_type->rest_controller_class : 'WP_REST_Posts_Controller';
+	foreach ( get_post_types( array( 'show_in_rest' => true ) ) as $post_type ) {
+		$controller = WP_REST_Posts_Controller::get_for_post_type( $post_type );
 
-		if ( ! class_exists( $class ) ) {
-			continue;
-		}
-		$controller = new $class( $post_type->name );
-		if ( ! is_subclass_of( $controller, 'WP_REST_Controller' ) ) {
+		if ( ! $controller ) {
 			continue;
 		}
 
 		$controller->register_routes();
 
-		if ( post_type_supports( $post_type->name, 'revisions' ) ) {
-			$revisions_controller = new WP_REST_Revisions_Controller( $post_type->name );
+		if ( post_type_supports( $post_type, 'revisions' ) ) {
+			$revisions_controller = new WP_REST_Revisions_Controller( $post_type, $controller );
 			$revisions_controller->register_routes();
 		}
 
-		if ( 'attachment' !== $post_type->name ) {
-			$autosaves_controller = new WP_REST_Autosaves_Controller( $post_type->name );
+		if ( 'attachment' !== $post_type ) {
+			$autosaves_controller = new WP_REST_Autosaves_Controller( $post_type, $controller );
 			$autosaves_controller->register_routes();
 		}
 	}
diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php
index e55d3a3729..42bad39e33 100644
--- a/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php
+++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php
@@ -53,17 +53,23 @@ class WP_REST_Autosaves_Controller extends WP_REST_Revisions_Controller {
 	 * Constructor.
 	 *
 	 * @since 5.0.0
+	 * @since 5.3.0 Added optional $parent_controller parameter.
 	 *
-	 * @param string $parent_post_type Post type of the parent.
+	 * @param string                  $parent_post_type Post type of the parent.
+	 * @param WP_REST_Controller|null $parent_controller Controller for the Posts endpoint.
 	 */
-	public function __construct( $parent_post_type ) {
-		$this->parent_post_type = $parent_post_type;
-		$post_type_object       = get_post_type_object( $parent_post_type );
+	public function __construct( $parent_post_type, WP_REST_Controller $parent_controller = null ) {
+		if ( ! $parent_controller ) {
+			$parent_controller = WP_REST_Posts_Controller::get_for_post_type( $parent_post_type );
+		}
 
-		// Ensure that post type-specific controller logic is available.
-		$parent_controller_class = ! empty( $post_type_object->rest_controller_class ) ? $post_type_object->rest_controller_class : 'WP_REST_Posts_Controller';
+		if ( ! $parent_controller ) {
+			$parent_controller = new WP_REST_Posts_Controller( $parent_post_type );
+		}
 
-		$this->parent_controller    = new $parent_controller_class( $post_type_object->name );
+		$this->parent_post_type     = $parent_post_type;
+		$post_type_object           = get_post_type_object( $parent_post_type );
+		$this->parent_controller    = $parent_controller;
 		$this->revisions_controller = new WP_REST_Revisions_Controller( $parent_post_type );
 		$this->rest_namespace       = 'wp/v2';
 		$this->rest_base            = 'autosaves';
diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php
index b730844fde..5ca9ce35bb 100644
--- a/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php
+++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php
@@ -1582,8 +1582,13 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
 	 * @return bool Whether post can be read.
 	 */
 	protected function check_read_post_permission( $post, $request ) {
-		$posts_controller = new WP_REST_Posts_Controller( $post->post_type );
-		$post_type        = get_post_type_object( $post->post_type );
+		$posts_controller = WP_REST_Posts_Controller::get_for_post_type( $post->post_type );
+
+		if ( ! $posts_controller instanceof WP_REST_Posts_Controller ) {
+			$posts_controller = new WP_REST_Posts_Controller( $post->post_type );
+		}
+
+		$post_type = get_post_type_object( $post->post_type );
 
 		$has_password_filter = false;
 
diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php
index 090ca2a5da..00cf4f5ff6 100644
--- a/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php
+++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php
@@ -16,6 +16,14 @@
  */
 class WP_REST_Posts_Controller extends WP_REST_Controller {
 
+	/**
+	 * Instances of post type controllers keyed by post type.
+	 *
+	 * @since 5.3.0
+	 * @var WP_REST_Controller[]
+	 */
+	private static $post_type_controllers = array();
+
 	/**
 	 * Post type.
 	 *
@@ -48,6 +56,49 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
 		$this->meta = new WP_REST_Post_Meta_Fields( $this->post_type );
 	}
 
+	/**
+	 * Gets the REST API controller for a post type.
+	 *
+	 * @since 5.3.0
+	 *
+	 * @param string $post_type
+	 * @return WP_REST_Controller|null The controller instance, or null if the specified is invalid or the post type
+	 *                                 is set not to show in rest.
+	 */
+	public static function get_for_post_type( $post_type ) {
+		if ( array_key_exists( $post_type, self::$post_type_controllers ) ) {
+			return self::$post_type_controllers[ $post_type ];
+		}
+
+		$definition = get_post_type_object( $post_type );
+
+		if ( ! $definition ) {
+			self::$post_type_controllers[ $post_type ] = null;
+
+			return self::$post_type_controllers[ $post_type ];
+		}
+
+		$class = $definition->rest_controller_class ? $definition->rest_controller_class : WP_REST_Posts_Controller::class;
+
+		if ( ! class_exists( $class ) ) {
+			self::$post_type_controllers[ $post_type ] = null;
+
+			return self::$post_type_controllers[ $post_type ];
+		}
+
+		$controller = new $class( $post_type );
+
+		if ( ! is_subclass_of( $controller, WP_REST_Controller::class ) ) {
+			self::$post_type_controllers[ $post_type ] = null;
+
+			return self::$post_type_controllers[ $post_type ];
+		}
+
+		self::$post_type_controllers[ $post_type ] = $controller;
+
+		return self::$post_type_controllers[ $post_type ];
+	}
+
 	/**
 	 * Registers the routes for the objects of the controller.
 	 *
diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php
index 52df0f2206..0755df10b7 100644
--- a/src/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php
+++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php
@@ -44,12 +44,22 @@ class WP_REST_Revisions_Controller extends WP_REST_Controller {
 	 * Constructor.
 	 *
 	 * @since 4.7.0
+	 * @since 5.3.0 Added optional $parent_controller parameter.
 	 *
-	 * @param string $parent_post_type Post type of the parent.
+	 * @param string                  $parent_post_type  Post type of the parent.
+	 * @param WP_REST_Controller|null $parent_controller Controller for the Posts endpoint.
 	 */
-	public function __construct( $parent_post_type ) {
+	public function __construct( $parent_post_type, WP_REST_Controller $parent_controller = null ) {
+		if ( ! $parent_controller ) {
+			$parent_controller = WP_REST_Posts_Controller::get_for_post_type( $parent_post_type );
+		}
+
+		if ( ! $parent_controller ) {
+			$parent_controller = new WP_REST_Posts_Controller( $parent_post_type );
+		}
+
 		$this->parent_post_type  = $parent_post_type;
-		$this->parent_controller = new WP_REST_Posts_Controller( $parent_post_type );
+		$this->parent_controller = $parent_controller;
 		$this->namespace         = 'wp/v2';
 		$this->rest_base         = 'revisions';
 		$post_type_object        = get_post_type_object( $parent_post_type );
