diff --git src/wp-includes/post.php src/wp-includes/post.php
index 1920e84..6bd61ee 100644
--- src/wp-includes/post.php
+++ src/wp-includes/post.php
@@ -4231,6 +4231,19 @@ function get_page( $page, $output = OBJECT, $filter = 'raw') {
 function get_page_by_path( $page_path, $output = OBJECT, $post_type = 'page' ) {
 	global $wpdb;
 
+	$last_changed = wp_cache_get( 'last_changed', 'posts' );
+	if ( false === $last_changed ) {
+		$last_changed = microtime();
+		wp_cache_set( 'last_changed', $last_changed, 'posts' );
+	}
+
+	$hash = md5( $page_path . serialize( $post_type ) );
+	$cache_key = "get_page_by_path:$hash:$last_changed";
+	$cached = wp_cache_get( $cache_key, 'posts' );
+	if ( false !== $cached ) {
+		return get_post( $cached );
+	}
+
 	$page_path = rawurlencode(urldecode($page_path));
 	$page_path = str_replace('%2F', '/', $page_path);
 	$page_path = str_replace('%20', ' ', $page_path);
@@ -4285,6 +4298,9 @@ function get_page_by_path( $page_path, $output = OBJECT, $post_type = 'page' ) {
 		}
 	}
 
+	// We cache misses as well as hits.
+	wp_cache_set( $cache_key, $foundid, 'posts' );
+
 	if ( $foundid ) {
 		return get_post( $foundid, $output );
 	}
diff --git tests/phpunit/tests/post/getPageByPath.php tests/phpunit/tests/post/getPageByPath.php
index 7bd3610..2604d9b 100644
--- tests/phpunit/tests/post/getPageByPath.php
+++ tests/phpunit/tests/post/getPageByPath.php
@@ -123,4 +123,101 @@ class Tests_Post_GetPageByPath extends WP_UnitTestCase {
 
 		$this->assertNull( $found );
 	}
+
+	/**
+	 * @ticket 36711
+	 */
+	public function test_should_hit_cache() {
+		global $wpdb;
+
+		$page = self::factory()->post->create( array(
+			'post_type' => 'page',
+			'post_name' => 'foo',
+		) );
+
+		// Prime cache.
+		$found = get_page_by_path( 'foo' );
+		$this->assertSame( $page, $found->ID );
+
+		$num_queries = $wpdb->num_queries;
+
+		$found = get_page_by_path( 'foo' );
+		$this->assertSame( $page, $found->ID );
+		$this->assertSame( $num_queries, $wpdb->num_queries );
+	}
+
+	/**
+	 * @ticket 36711
+	 */
+	public function test_bad_path_should_be_cached() {
+		global $wpdb;
+
+		// Prime cache.
+		$found = get_page_by_path( 'foo' );
+		$this->assertNull( $found );
+
+		$num_queries = $wpdb->num_queries;
+
+		$found = get_page_by_path( 'foo' );
+		$this->assertNull( $found );
+		$this->assertSame( $num_queries, $wpdb->num_queries );
+	}
+
+	/**
+	 * @ticket 36711
+	 */
+	public function test_cache_should_not_match_post_in_different_post_type_with_same_path() {
+		global $wpdb;
+
+		register_post_type( 'wptests_pt' );
+
+		$p1 = self::factory()->post->create( array(
+			'post_type' => 'page',
+			'post_name' => 'foo',
+		) );
+
+		$p2 = self::factory()->post->create( array(
+			'post_type' => 'wptests_pt',
+			'post_name' => 'foo',
+		) );
+
+		// Prime cache for the page.
+		$found = get_page_by_path( 'foo' );
+		$this->assertSame( $p1, $found->ID );
+
+		$num_queries = $wpdb->num_queries;
+
+		$found = get_page_by_path( 'foo', OBJECT, 'wptests_pt' );
+		$this->assertSame( $p2, $found->ID );
+		$num_queries++;
+		$this->assertSame( $num_queries, $wpdb->num_queries );
+	}
+
+	/**
+	 * @ticket 36711
+	 */
+	public function test_cache_should_be_invalidated_when_post_name_is_edited() {
+		global $wpdb;
+
+		$page = self::factory()->post->create( array(
+			'post_type' => 'page',
+			'post_name' => 'foo',
+		) );
+
+		// Prime cache.
+		$found = get_page_by_path( 'foo' );
+		$this->assertSame( $page, $found->ID );
+
+		wp_update_post( array(
+			'ID' => $page,
+			'post_name' => 'bar',
+		) );
+
+		$num_queries = $wpdb->num_queries;
+
+		$found = get_page_by_path( 'bar' );
+		$this->assertSame( $page, $found->ID );
+		$num_queries++;
+		$this->assertSame( $num_queries, $wpdb->num_queries );
+	}
 }
