diff --git a/typo3/sysext/core/Classes/Cache/Backend/PageCacheBackend.php b/typo3/sysext/core/Classes/Cache/Backend/PageCacheBackend.php
new file mode 100644
index 0000000..f4983af
--- /dev/null
+++ b/typo3/sysext/core/Classes/Cache/Backend/PageCacheBackend.php
@@ -0,0 +1,95 @@
+<?php
+namespace TYPO3\CMS\Core\Cache\Backend;
+
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2014 Bernhard Kraft <kraft@webconsulting.at>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+/**
+ * A caching backend especially optimized for being used as the
+ * TYPO3 page cache
+ *
+ * @author Bernhard Kraft <kraft@webconsulting.at>
+ * @api
+ */
+class PageCacheBackend extends Typo3DatabaseBackend implements \TYPO3\CMS\Core\Cache\Backend\RedundancyAwareInterface {
+
+	/**
+	 * Removes all cache entries matching the specified identifier.
+	 * Usually this affects one page cache entry and up to three field cache entries.
+	 * Redundancy cache entries will only get deleted if they are not used by another page cache entry.
+	 *
+	 * @param string $entryIdentifier Specifies the cache entry to remove
+	 * @return boolean TRUE if (at least) an entry could be removed or FALSE if no entry was found
+	 */
+	public function remove($entryIdentifier) {
+		$removed = parent::remove($entryIdentifier);
+		if ($removed) {
+			$this->collectRedundancyGarbage();
+		}
+		return $removed;
+	}
+
+	/**
+	 * Removes all cache entries of this cache which are tagged by the specified tag.
+	 *
+	 * @param string $tag The tag the entries must have
+	 * @return void
+	 */
+	public function flushByTag($tag) {
+		parent::flushByTag($tag);
+		$this->collectRedundancyGarbage();
+	}
+
+	/**
+	 * Does garbage collection
+	 *
+	 * @return void
+	 */
+	public function collectGarbage() {
+		parent::collectGarbage();
+		$this->collectRedundancyGarbage();
+	}
+
+	/**
+	 * Does redundancy cache garbage collection
+	 *
+	 * @return void
+	 */
+	public function collectRedundancyGarbage() {
+		// This query finds redundancy entries which are not referenced any more by any page cache entries and deletes them
+		$rowsResource = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
+			'c1.identifier AS identifier',
+			$this->cacheTable . ' AS c1 LEFT JOIN ' . $this->tagsTable . ' AS c2 ON c1.identifier=c2.tag OR c1.identifier=c2.identifier',
+			'c2.tag IS NULL'
+		);
+		$cacheEntryIdentifiers = array();
+		while ($cacheRow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($rowsResource)) {
+			$cacheEntryIdentifiers[] = $GLOBALS['TYPO3_DB']->fullQuoteStr($cacheRow['identifier'], $this->cacheTable);
+		}
+		$GLOBALS['TYPO3_DB']->sql_free_result($rowsResource);
+
+		if (count($cacheEntryIdentifiers)) {
+			$GLOBALS['TYPO3_DB']->exec_DELETEquery($this->cacheTable, 'identifier IN (' . implode(', ', $cacheEntryIdentifiers) . ')');
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/typo3/sysext/core/Classes/Cache/Backend/RedundancyAwareInterface.php b/typo3/sysext/core/Classes/Cache/Backend/RedundancyAwareInterface.php
new file mode 100644
index 0000000..089daba
--- /dev/null
+++ b/typo3/sysext/core/Classes/Cache/Backend/RedundancyAwareInterface.php
@@ -0,0 +1,44 @@
+<?php
+namespace TYPO3\CMS\Core\Cache\Backend;
+
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2014 Bernhard Kraft <kraft@webconsulting.at>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+/**
+ * A contract for a cache backend which is able to handle entries
+ * which are shared among other entries with the purpose to reduce
+ * the amount of redundant data stored in the cache.
+ *
+ * @api
+ */
+interface RedundancyAwareInterface extends \TYPO3\CMS\Core\Cache\Backend\BackendInterface {
+
+	/**
+	 * Does redundancy cache garbage collection
+	 * This is the only method a redundancy aware interface MUST implement.
+	 * The method should be called by the backend at appropriate events i.e. after removing a cache entry.
+	 *
+	 * @return void
+	 */
+	public function collectRedundancyGarbage();
+
+}
\ No newline at end of file
diff --git a/typo3/sysext/core/Classes/Cache/Frontend/PageCacheEntry.php b/typo3/sysext/core/Classes/Cache/Frontend/PageCacheEntry.php
new file mode 100644
index 0000000..9a7d3ba
--- /dev/null
+++ b/typo3/sysext/core/Classes/Cache/Frontend/PageCacheEntry.php
@@ -0,0 +1,48 @@
+<?php
+namespace TYPO3\CMS\Core\Cache\Frontend;
+
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2014 Bernhard Kraft <kraft@webconsulting.at>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+/**
+ * This class represents a "squeezed" entry in the page cache.
+ * 
+ * If a the contents of page-cache array field ('content' or 'cache_data')
+ * get put in the cache on their own instead of their orginial value an
+ * instance of this class will be put into the page-cache array.
+ *
+ * This has mostly the sense of recognizing that a field was redundancy
+ * squeezed so it can get restored on retrieval.
+ *
+ *
+ * @author Bernhard Kraft <kraft@webconsulting.at>
+ */
+class PageCacheEntry {
+	protected $identifier = '';
+
+	public function __construct($identifier) {
+		$this->identifier = $identifier;
+	}
+	public function getIdentifier() {
+		return $this->identifier;
+	}
+}
\ No newline at end of file
diff --git a/typo3/sysext/core/Classes/Cache/Frontend/PageCacheFrontend.php b/typo3/sysext/core/Classes/Cache/Frontend/PageCacheFrontend.php
new file mode 100644
index 0000000..dfe969d
--- /dev/null
+++ b/typo3/sysext/core/Classes/Cache/Frontend/PageCacheFrontend.php
@@ -0,0 +1,237 @@
+<?php
+namespace TYPO3\CMS\Core\Cache\Frontend;
+
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2014 Bernhard Kraft <kraft@webconsulting.at>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+/**
+ * A cache frontend especially for the TYPO3 page cache
+ *
+ * It takes care of the fact that the array values "content" and "cache_data"
+ * of the passed array variable often contain redundant values and caches them
+ * separately.
+ *
+ * Each of those page-cache array values get stored into the same cache_pages
+ * cache backend but they get an identifier which is based on a hash of their
+ * content. So redundant entries are avoided.
+ *
+ *
+ * In the original page cache array those big data values which got redundancy
+ * squeezed are represented by an surrogate object "PageCacheEntry" whose sole
+ * purpose currently is to recognize them after unserialization and pull the
+ * additional data from the cache
+ *
+ *
+ * @author Bernhard Kraft <kraft@webconsulting.at>
+ */
+
+use \TYPO3\CMS\Core\Utility\GeneralUtility;
+
+class PageCacheFrontend extends \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend {
+	const STRING_PREFIX = 'string_';
+	const SERIALIZED_PREFIX = 'serialized_';
+
+	/**
+	 * Constructs the cache
+	 *
+	 * @param string $identifier A identifier which describes this cache
+	 * @param \TYPO3\CMS\Core\Cache\Backend\BackendInterface $backend Backend to be used for this cache
+	 * @throws \InvalidArgumentException if the backend isn't redundancy aware
+	 */
+	public function __construct($identifier, \TYPO3\CMS\Core\Cache\Backend\BackendInterface $backend) {
+		if (! $backend instanceof \TYPO3\CMS\Core\Cache\Backend\RedundancyAwareInterface) {
+			throw new \InvalidArgumentException('Backend class "' . get_class($backend) . '" does not implement "\TYPO3\CMS\Core\Cache\Backend\RedundancyAwareInterface".', 1391214304);
+		}
+		parent::__construct($identifier, $backend);
+	}
+
+
+	/**
+	 * Saves the passed TYPO3 page cache array in the cache.
+	 *
+	 * @param string $entryIdentifier An identifier used for this cache entry
+	 * @param array $variable The variable to cache
+	 * @param array $tags Tags to associate with this cache entry
+	 * @param integer $lifetime Lifetime of this cache entry in seconds. If NULL is specified, the default lifetime is used. "0" means unlimited liftime.
+	 * @return void
+	 * @throws \InvalidArgumentException if the identifier or tag is not valid
+	 * @api
+	 */
+	public function set($entryIdentifier, $variable, array $tags = array(), $lifetime = NULL) {
+		if (!is_array($variable)) {
+			throw new \InvalidArgumentException('Only array variables supported for storing!', 1391168251);
+		}
+
+		// By default two array values ("content" and "cache_data") get stored on their own because they
+		// usually contain large blocks of data and are redundant among requests in many cases.
+
+		// Field "content" is redundant among cached page variants when logged in users see the same
+		// as non-logged in users like when no output altering conditions, no access restricted
+		// content elemnts, etc. are contained on a page.
+		$variable['content'] = $this->getDataSurrogate($variable['content']);
+		if ($variable['content'] instanceof \TYPO3\CMS\Core\Cache\Frontend\PageCacheEntry) {
+			// A page cache entry remembers the redundant data pieces it uses also by adding
+			// appropriate tags. This allows to handle removal and garbage collection by the
+			// redundancy aware backend.
+			$tags[] = $variable['content']->getIdentifier();
+		}
+	
+		// Field "cache_data" is redundant among every cached pages as long as they share the same
+		// TypoScript setup. The only disturbing factor is the array key "rootLine" which is of
+		// course different for every page. So move this array key to the cache variable itself.
+		$variable['cache_rootLine'] = $this->getDataSurrogate($variable['cache_data']['rootLine']);
+		if ($variable['cache_rootLine'] instanceof \TYPO3\CMS\Core\Cache\Frontend\PageCacheEntry) {
+			$tags[] = $variable['cache_rootLine']->getIdentifier();
+		}
+		unset($variable['cache_data']['rootLine']);
+
+		$variable['cache_data'] = $this->getDataSurrogate($variable['cache_data']);
+		if ($variable['cache_data'] instanceof \TYPO3\CMS\Core\Cache\Frontend\PageCacheEntry) {
+			$tags[] = $variable['cache_data']->getIdentifier();
+		}
+
+		// Store processed array
+		parent::set($entryIdentifier, $variable, $tags, $lifetime);
+	}
+
+	/**
+	 * Finds and returns a variable value from the cache.
+	 *
+	 * @param string $entryIdentifier Identifier of the cache entry to fetch
+	 * @return mixed The value
+	 * @throws \InvalidArgumentException if the identifier is not valid
+	 * @api
+	 */
+	public function get($entryIdentifier) {
+		$result = parent::get($entryIdentifier);
+		if (is_array($result)) {
+			// Restore all array values which were replaced by surrogates
+			return $this->getPageCacheOriginalData($result);
+		} else {
+			return FALSE;
+		}
+	}
+
+	/**
+	 * Finds and returns all cache entries which are tagged by the specified tag.
+	 *
+	 * @param string $tag The tag to search for
+	 * @return array An array with the content of all matching entries. An empty array if no entries matched
+	 * @throws \InvalidArgumentException if the tag is not valid
+	 * @api
+	 */
+	public function getByTag($tag) {
+		$entries = parent::getByTag($tag);
+		foreach ($entries as $key => $entry) {
+			// Restore all array values which were put in a cache entry on their own
+			$entries[$key] = $this->getPageCacheOriginalData($entry);
+		}
+		return $entries;
+	}
+
+
+
+	/**********************************************
+	 *
+	 * End of public API
+	 *
+	 **********************************************/
+
+	/**
+	 * Determines if it is worth to put the data into the cache on its own.
+	 * If the size of the (serialzed) data is more than 1kB this will happen.
+	 * Data gets stored into cache by generating a hash identifier from the data.
+	 * This results in avoiding redundant data in cache entries.
+	 *
+	 * @param mixed $data The data which should get stored
+	 * @return mixed/array Either the original data if it was shorter than 1kB or an PageCacheArray data surrogate
+	 */
+	protected function getDataSurrogate($data) {
+		$prefix = self::STRING_PREFIX;
+		$serialized = false;
+		if (!is_string($data)) {
+			$prefix = self::SERIALIZED_PREFIX;
+			if ($this->useIgBinary === TRUE) {
+				$serialized = igbinary_serialize($data);
+			} else {
+				$serialized = serialize($data);
+			}
+		}
+		// If the serialized (or plain) data was less than 1024 characters (1024) don't
+		// store them on their own. Eventually the overhead is more than its worth.
+		if (strlen($serialized ? $serialized : $data) < 1024) {
+			return $data;
+		}
+		// Until this point we needed the original data to eventually return it.
+		// From now on only the value to be stores will be needed.
+		$data = $serialized ? $serialized : $data;
+
+		$hash = sha1($data);
+		$identifier = $prefix.$hash;
+		if (!$this->backend->has($identifier)) {
+			$this->backend->set($identifier, $data, array(), 0);
+		}
+		return GeneralUtility::makeInstance('TYPO3\CMS\Core\Cache\Frontend\PageCacheEntry', $identifier);
+	}
+
+	/**
+	 * Retrieves the contents of a redundant data surrogate which was put into the cache
+	 *
+	 * @param mixed,\TYPO3\CMS\Core\Cache\Frontend\PageCacheEntry If an PageCacheEntry object (surrogate) is passed the associated data will get retrieved.
+	 * @return mixed The original contents of the page cache array value
+	 */
+	protected function getOriginalData($content) {
+		if (! $content instanceof \TYPO3\CMS\Core\Cache\Frontend\PageCacheEntry) {
+			return $content;
+		}
+		$data = $this->backend->get($content->getIdentifier());
+		if (substr($content->getIdentifier(), 0, strlen(self::SERIALIZED_PREFIX)) === self::SERIALIZED_PREFIX) {
+			if ($this->useIgBinary === TRUE) {
+				$data = igbinary_unserialize($data);
+			} else {
+				$data = unserialize($data);
+			}
+		}
+		return $data;
+	}
+
+	/**
+	 * Restores redundant page cache array values which were put in another cache entry
+	 *
+	 * @param array $variable The main cache entry of the page with eventual redundancy surrogates
+	 * @return array $variable The same cache entry with all redundancy surrogates replaced properly
+	 */
+	protected function getPageCacheOriginalData(array $variable) {
+		if (isset($variable['content'])) {
+			$variable['content'] = $this->getOriginalData($variable['content']);
+		}
+		if (isset($variable['cache_data'])) {
+			$variable['cache_data'] = $this->getOriginalData($variable['cache_data']);
+		}
+		if (isset($variable['cache_rootLine'])) {
+			$variable['cache_data']['rootLine'] = $this->getOriginalData($variable['cache_rootLine']);
+			unset($variable['cache_rootLine']);
+		}
+		return $variable;
+	}
+
+}
\ No newline at end of file
diff --git a/typo3/sysext/core/Configuration/DefaultConfiguration.php b/typo3/sysext/core/Configuration/DefaultConfiguration.php
index 3f46906..69ae90a 100644
--- a/typo3/sysext/core/Configuration/DefaultConfiguration.php
+++ b/typo3/sysext/core/Configuration/DefaultConfiguration.php
@@ -153,8 +153,8 @@ return array(
 					'groups' => array('pages', 'all')
 				),
 				'cache_pages' => array(
-					'frontend' => 'TYPO3\CMS\Core\Cache\Frontend\VariableFrontend',
-					'backend' => 'TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend',
+					'frontend' => 'TYPO3\CMS\Core\Cache\Frontend\PageCacheFrontend',
+					'backend' => 'TYPO3\CMS\Core\Cache\Backend\PageCacheBackend',
 					'options' => array(
 						'compression' => TRUE
 					),
