Skip to content

Memory spike in TagService when deleting keys with tags linked to many keys #3567

@Jbbouille

Description

@Jbbouille

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

  1. Create a project with a large number of keys (10k+) all sharing a common tag
  2. Trigger multiple concurrent batch key deletions (e.g. via the API)
  3. Observe JVM heap usage — G1 Old Gen fills up, GC overhead increases
  4. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions