Describe the bug
TagService.deleteAllTagsForKeys calls getTagsWithKeyMetas which executes join fetch t.keyMetas, loading the entire KeyMeta collection for every affected tag into the JPA session (including eagerly-fetched Key and Namespace associations). For projects where tags are linked to thousands of keys, this materializes 10k+ entities per deletion. Under concurrent DELETE_KEYS batch jobs, this leads to G1 Old Gen filling up, excessive GC pressure, and liveness probe failures.
The same issue exists in the single-key remove(key, tag) path which accesses tag.keyMetas directly.
To Reproduce
- Create a project with a large number of keys (10k+) all sharing a common tag
- Trigger multiple concurrent batch key deletions (e.g. via the API)
- Observe JVM heap usage — G1 Old Gen fills up, GC overhead increases
- Liveness probe eventually fails under sustained load
Expected behavior
Deleting keys should not load unrelated KeyMeta entities into the JPA session. Only the tags that would become empty need to be identified and removed.
Screenshots
N/A
Versions and environment
- Tolgee Platform version: 3.173.4
- Environment: Kubernetes, Java 21, multiple concurrent batch workers
- Browser: N/A (backend issue)
Additional context
Suggested fix: replace the full entity-graph fetch with a pure-ID EXISTS subquery (findTagIdsThatWouldBecomeEmpty) that returns only tag IDs whose keyMeta count would drop to zero, then bulk-delete them via JPQL. A fix is proposed in #3568.
Describe the bug
TagService.deleteAllTagsForKeyscallsgetTagsWithKeyMetaswhich executesjoin fetch t.keyMetas, loading the entireKeyMetacollection for every affected tag into the JPA session (including eagerly-fetchedKeyandNamespaceassociations). For projects where tags are linked to thousands of keys, this materializes 10k+ entities per deletion. Under concurrentDELETE_KEYSbatch jobs, this leads to G1 Old Gen filling up, excessive GC pressure, and liveness probe failures.The same issue exists in the single-key
remove(key, tag)path which accessestag.keyMetasdirectly.To Reproduce
Expected behavior
Deleting keys should not load unrelated
KeyMetaentities into the JPA session. Only the tags that would become empty need to be identified and removed.Screenshots
N/A
Versions and environment
Additional context
Suggested fix: replace the full entity-graph fetch with a pure-ID
EXISTSsubquery (findTagIdsThatWouldBecomeEmpty) that returns only tag IDs whosekeyMetacount would drop to zero, then bulk-delete them via JPQL. A fix is proposed in #3568.