https://sonarly.com/issue/3795?type=bug
Creating a custom object via POST /metadata takes ~5.8 seconds (200 OK) because the workspace migration runner unnecessarily invalidates and recomputes 6 role/permissions caches, causing ~3.9s of redundant DB queries against core.role, core.roleTarget, and core.application tables.
Fix: The root cause was a single `if` block in `getLegacyCacheInvalidationPromises` that used an `||` condition to gate **all 6 caches** (including 5 expensive role/permissions caches) whenever **any** metadata change occurred — even when no role/roleTarget data changed.
When creating a custom object, `shouldIncrementMetadataGraphqlSchemaVersion = true` (because `flatObjectMetadataMaps`/`flatFieldMetadataMaps` changed), which triggered `invalidateAndRecompute` for all 6 caches including the 5 role caches (`rolesPermissions`, `userWorkspaceRoleMap`, `flatRoleTargetMaps`, `apiKeyRoleMap`, `flatRoleTargetByAgentIdMaps`). Those role caches fire expensive DB queries against `core.role`, `core.roleTarget`, and `core.application` (~3.9s of redundant work) even though no role data was touched.
The fix splits the single combined block into two separate conditional blocks:
1. `shouldIncrementMetadataGraphqlSchemaVersion` → only invalidates/recomputes `ORMEntityMetadatas`
2. `shouldInvalidateRoleMapCache` → only invalidates/recomputes the 5 role/permissions caches
```typescript file=packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/services/workspace-migration-runner.service.ts lines=88-106
if (shouldIncrementMetadataGraphqlSchemaVersion) {
asyncOperations.push(
this.workspaceCacheService.invalidateAndRecompute(workspaceId, [
'ORMEntityMetadatas',
]),
);
}
if (shouldInvalidateRoleMapCache) {
asyncOperations.push(
this.workspaceCacheService.invalidateAndRecompute(workspaceId, [
'rolesPermissions',
'userWorkspaceRoleMap',
'flatRoleTargetMaps',
'apiKeyRoleMap',
'flatRoleTargetByAgentIdMaps',
]),
);
}
```
Now custom object creation (`shouldIncrementMetadataGraphqlSchemaVersion = true`, `shouldInvalidateRoleMapCache = false`) only recomputes `ORMEntityMetadatas`, skipping the ~3.9s of unnecessary role cache DB queries. Role cache recomputation only happens when role/roleTarget data actually changes.