fix(symfony): clear SkolemIriConverter state between requests via ResetInterface#7829
Open
gwini wants to merge 3 commits intoapi-platform:4.2from
Open
fix(symfony): clear SkolemIriConverter state between requests via ResetInterface#7829gwini wants to merge 3 commits intoapi-platform:4.2from
gwini wants to merge 3 commits intoapi-platform:4.2from
Conversation
added 2 commits
March 8, 2026 16:58
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
SkolemIriConverterusesSplObjectStorage $objectHashMapandarray $classHashMapto cache IRI mappings for non-entity objects during serialization. In long-running processes (FrankenPHP worker mode,Swoole, RoadRunner), these maps accumulate entries across requests and are never cleared, causing a memory leak.
How I found it
Running Symfony 7.4 with API Platform 4.2.20 in FrankenPHP worker mode, I observed ~2.7 MB/request memory growth when calling an endpoint that serializes ~665 DTO objects (each containing two
CarbonImmutableproperties). Memory grew linearly with every request and was never reclaimed by GC.
Using a deep object-graph scanner with reflection across all container services, I traced the leaked references to
SkolemIriConverter::$objectHashMap— it held strong references to every serialized DTO andits nested objects across all previous requests. The class never implements
ResetInterface, soservices_resetternever clears it.After applying this fix, memory stabilized at ~76 MB across 20+ consecutive requests.
Changes
SkolemIriConverternow implementsResetInterfacewith areset()method that clears both$objectHashMapand$classHashMapkernel.resetso Symfony automatically callsreset()between requestsNote: The Laravel variant (
ApiPlatform\Laravel\Routing\SkolemIriConverter) has the same issue — its$objectHashMapand$classHashMapalso grow unbounded across requests when running under Octane or otherlong-running setups. I'm not familiar enough with Laravel's service lifecycle to implement the correct reset mechanism there. A follow-up PR for the Laravel side would be appreciated.