diff --git a/typo3/sysext/core/Documentation/Changelog/master/Deprecation-94957-TypoScriptFrontendController-cObjectDepthCounter.rst b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-94957-TypoScriptFrontendController-cObjectDepthCounter.rst
new file mode 100644
index 0000000000000000000000000000000000000000..29b5abe492bbd04d1d391bac4942b77343bf4fe6
--- /dev/null
+++ b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-94957-TypoScriptFrontendController-cObjectDepthCounter.rst
@@ -0,0 +1,42 @@
+.. include:: ../../Includes.txt
+
+=======================================================================
+Deprecation: #94957 - TypoScriptFrontendController->cObjectDepthCounter
+=======================================================================
+
+See :issue:`94957`
+
+Description
+===========
+
+The :php:`TypoScriptFrontendController` contains a property to prevent endless
+recursion of content objects during frontend rendering. With TypoScript
+becoming less complex, this check becomes obsolete. To reduce dependencies
+between :php:`TypoScriptFrontendController` and :php:`ContentObjectRenderer`,
+the handling has been removed and property :php:`TypoScriptFrontendController->cObjectDepthCounter`
+has bee marked as deprecated.
+
+
+Impact
+======
+
+If a TypoScript setup somehow manages to create a recursion, PHP will now stop
+with a fatal PHP nesting level error at some point, instead of TYPO3 frontend
+rendering silently stopping.
+
+
+Affected Installations
+======================
+
+Instances using property :php:`TypoScriptFrontendController->cObjectDepthCounter`
+are affected. That property has been handled mostly internally, this case is unlikely.
+The extension scanner will find usages with a weak match.
+
+
+Migration
+=========
+
+Drop usages of property :php:`TypoScriptFrontendController->cObjectDepthCounter`,
+it is unused within TYPO3 v11.
+
+.. index:: Frontend, PHP-API, FullyScanned, ext:frontend
diff --git a/typo3/sysext/extbase/Classes/Utility/FrontendSimulatorUtility.php b/typo3/sysext/extbase/Classes/Utility/FrontendSimulatorUtility.php
index 359db6bc8ee319a0c569b2b38719b902a7c8be7f..cf77bc543d1e75ea30c98f773f949959849fdbd5 100644
--- a/typo3/sysext/extbase/Classes/Utility/FrontendSimulatorUtility.php
+++ b/typo3/sysext/extbase/Classes/Utility/FrontendSimulatorUtility.php
@@ -34,8 +34,7 @@ class FrontendSimulatorUtility
     protected static $tsfeBackup;
 
     /**
-     * Sets the $TSFE->cObjectDepthCounter in Backend mode
-     * This somewhat hacky work around is currently needed because the cObjGetSingle() function of \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer relies on this setting
+     * \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer->cObjGetSingle() relies on $GLOBALS['TSFE']
      *
      * @param ContentObjectRenderer|null $cObj
      */
@@ -43,7 +42,6 @@ class FrontendSimulatorUtility
     {
         self::$tsfeBackup = $GLOBALS['TSFE'] ?? null;
         $GLOBALS['TSFE'] = new \stdClass();
-        $GLOBALS['TSFE']->cObjectDepthCounter = 100;
         $GLOBALS['TSFE']->cObj = $cObj ?? GeneralUtility::makeInstance(ContentObjectRenderer::class);
     }
 
diff --git a/typo3/sysext/fluid/Classes/ViewHelpers/CObjectViewHelper.php b/typo3/sysext/fluid/Classes/ViewHelpers/CObjectViewHelper.php
index cb65502758e2b04b2ff16560d75e869a4218eef1..aa108c5f8dae5954252e581a577d9939f307e428 100644
--- a/typo3/sysext/fluid/Classes/ViewHelpers/CObjectViewHelper.php
+++ b/typo3/sysext/fluid/Classes/ViewHelpers/CObjectViewHelper.php
@@ -237,15 +237,13 @@ class CObjectViewHelper extends AbstractViewHelper
     }
 
     /**
-     * Sets the $TSFE->cObjectDepthCounter in Backend mode
-     * This somewhat hacky work around is currently needed because the cObjGetSingle() function of \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer relies on this setting
+     * \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer->cObjGetSingle() relies on $GLOBALS['TSFE']
      */
     protected static function simulateFrontendEnvironment()
     {
         static::$tsfeBackup = $GLOBALS['TSFE'] ?? null;
         $GLOBALS['TSFE'] = new \stdClass();
         $GLOBALS['TSFE']->cObj = GeneralUtility::makeInstance(ContentObjectRenderer::class);
-        $GLOBALS['TSFE']->cObjectDepthCounter = 100;
     }
 
     /**
diff --git a/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php b/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php
index bb84104979cf36421e51023d6bf71ee67f7a17f9..7dd3b666bc064e75eaeadd57fee3f3f7bb05ff44 100644
--- a/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php
+++ b/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php
@@ -706,38 +706,32 @@ class ContentObjectRenderer implements LoggerAwareInterface
     public function cObjGetSingle($name, $conf, $TSkey = '__')
     {
         $content = '';
-        // Checking that the function is not called eternally. This is done by interrupting at a depth of 100
-        $this->getTypoScriptFrontendController()->cObjectDepthCounter--;
-        if ($this->getTypoScriptFrontendController()->cObjectDepthCounter > 0) {
-            $timeTracker = $this->getTimeTracker();
-            $name = trim($name);
-            if ($timeTracker->LR) {
-                $timeTracker->push($TSkey, $name);
-            }
-            // Checking if the COBJ is a reference to another object. (eg. name of 'some.object =< styles.something')
-            if (isset($name[0]) && $name[0] === '<') {
-                $key = trim(substr($name, 1));
-                $cF = GeneralUtility::makeInstance(TypoScriptParser::class);
-                // $name and $conf is loaded with the referenced values.
-                $confOverride = is_array($conf) ? $conf : [];
-                [$name, $conf] = $cF->getVal($key, $this->getTypoScriptFrontendController()->tmpl->setup);
-                $conf = array_replace_recursive(is_array($conf) ? $conf : [], $confOverride);
-                // Getting the cObject
-                $timeTracker->incStackPointer();
-                $content .= $this->cObjGetSingle($name, $conf, $key);
-                $timeTracker->decStackPointer();
-            } else {
-                $contentObject = $this->getContentObject($name);
-                if ($contentObject) {
-                    $content .= $this->render($contentObject, $conf);
-                }
-            }
-            if ($timeTracker->LR) {
-                $timeTracker->pull($content);
+        $timeTracker = $this->getTimeTracker();
+        $name = trim($name);
+        if ($timeTracker->LR) {
+            $timeTracker->push($TSkey, $name);
+        }
+        // Checking if the COBJ is a reference to another object. (eg. name of 'some.object =< styles.something')
+        if (isset($name[0]) && $name[0] === '<') {
+            $key = trim(substr($name, 1));
+            $cF = GeneralUtility::makeInstance(TypoScriptParser::class);
+            // $name and $conf is loaded with the referenced values.
+            $confOverride = is_array($conf) ? $conf : [];
+            [$name, $conf] = $cF->getVal($key, $this->getTypoScriptFrontendController()->tmpl->setup);
+            $conf = array_replace_recursive(is_array($conf) ? $conf : [], $confOverride);
+            // Getting the cObject
+            $timeTracker->incStackPointer();
+            $content .= $this->cObjGetSingle($name, $conf, $key);
+            $timeTracker->decStackPointer();
+        } else {
+            $contentObject = $this->getContentObject($name);
+            if ($contentObject) {
+                $content .= $this->render($contentObject, $conf);
             }
         }
-        // Increasing on exit...
-        $this->getTypoScriptFrontendController()->cObjectDepthCounter++;
+        if ($timeTracker->LR) {
+            $timeTracker->pull($content);
+        }
         return $content;
     }
 
diff --git a/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php b/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php
index c39fd55dde9c4d659a872948346d3699a7d11f48..4f74261fc933a36c8ff6b768fd59485806acdd08 100644
--- a/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php
+++ b/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php
@@ -438,6 +438,7 @@ class TypoScriptFrontendController implements LoggerAwareInterface
      * Checking that the function is not called eternally. This is done by
      * interrupting at a depth of 50
      * @var int
+     * @deprecated since v11, will be removed in v12.
      */
     public $cObjectDepthCounter = 50;
 
diff --git a/typo3/sysext/frontend/Tests/Unit/Plugin/AbstractPluginTest.php b/typo3/sysext/frontend/Tests/Unit/Plugin/AbstractPluginTest.php
index d73752ec44bd7e0868ee86f021573848e5878554..e1bc7daa618c6c876e3190fc8cced07ea241c573 100644
--- a/typo3/sysext/frontend/Tests/Unit/Plugin/AbstractPluginTest.php
+++ b/typo3/sysext/frontend/Tests/Unit/Plugin/AbstractPluginTest.php
@@ -53,7 +53,6 @@ class AbstractPluginTest extends UnitTestCase
         parent::setUp();
 
         $tsfe = $this->prophesize(TypoScriptFrontendController::class);
-        $tsfe->cObjectDepthCounter = 100;
         $tsfe->getLanguage(Argument::cetera())->willReturn(
             $this->createSiteWithDefaultLanguage()->getLanguageById(0)
         );
diff --git a/typo3/sysext/install/Configuration/ExtensionScanner/Php/PropertyPublicMatcher.php b/typo3/sysext/install/Configuration/ExtensionScanner/Php/PropertyPublicMatcher.php
index 34adf66b907e1b3550bcfc76d120216fcb9bea09..17ab1bb7152129eabcdff5fd68676684ab1a9c8f 100644
--- a/typo3/sysext/install/Configuration/ExtensionScanner/Php/PropertyPublicMatcher.php
+++ b/typo3/sysext/install/Configuration/ExtensionScanner/Php/PropertyPublicMatcher.php
@@ -870,4 +870,9 @@ return [
             'Deprecation-94958-ContentObjectRendererProperties.rst',
         ],
     ],
+    'TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController->cObjectDepthCounter' => [
+        'restFiles' => [
+            'Deprecation-94957-TypoScriptFrontendController-cObjectDepthCounter.rst'
+        ],
+    ],
 ];