Skip to content

Slow DB Query: org permission check takes ~2.6s on GET /organisations/{id}/groups/ #8228

Description

@sentry

Sentry: FLAGSMITH-API-6BK

User impact

GET /api/v1/organisations/{organisation_pk}/groups/ takes ~2.6 seconds, and
users feel all of it — the org Groups page just sits there loading.

  • 14 users affected, 16 occurrences
  • First seen 2026-08-03T16:38Z, still occurring (last seen 2026-08-05T16:04Z)
  • Not an error — nothing breaks, it's purely slow. This is why it was classified
    info/low by Sentry and initially archived.

Where the time goes

One span accounts for essentially the whole request:

Span Duration
db — org permission check (below) 2599 ms
db — count user permission groups 3 ms
remaining 8 spans 1 ms each

The query

An org-level permission check that LEFT OUTER JOINs the entire RBAC graph —
userorganisationpermission (+ its permissions M2M), userpermissiongroup
(+ users, + its org-permissions M2M), rbac_role, rbac_userrole,
rbac_grouprole, rbac_roleorganisationpermission (+ its permissions M2M) —
then WHERE … LIMIT 1:

SELECT %s AS "a" FROM "organisations_organisation"
LEFT OUTER JOIN "organisation_permissions_userorganisationpermission"LEFT OUTER JOIN "users_userpermissiongroup"LEFT OUTER JOIN "rbac_role"LEFT OUTER JOIN "rbac_userrole"LEFT OUTER JOIN "rbac_grouprole"LEFT OUTER JOIN "rbac_roleorganisationpermission"INNER JOIN "organisations_userorganisation"WHERE (… user_id = %s … OROR …) AND organisation_id = %s LIMIT 1

Suggested direction

It only needs to answer "does this user hold this permission on this org?", but
builds a full cross-product of three independent permission paths (direct,
group, role) before discarding all but one row. Splitting it into three cheap
EXISTS checks short-circuited with OR, or a UNION ALL … LIMIT 1, would
avoid the join explosion. Worth checking indexes on the RBAC join columns too.

Triage note

Initially archived --until auto by the sentry-triage skill because Sentry
rates it info/low. That was wrong: auto only re-alerts on a frequency
spike
, and a steady 2.6s regression affecting 14 users never spikes, so it
would have stayed silent indefinitely. Reopened and filed.


Slack alert · filed by the sentry-triage skill

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions