Skip to content

perf(schemas): index organization_user_relations on (tenant_id, user_id)#8818

Merged
simeng-li merged 1 commit into
masterfrom
simeng-log-13472-perf-a-add-index-on-organization_user_relations-tenant_id
May 18, 2026
Merged

perf(schemas): index organization_user_relations on (tenant_id, user_id)#8818
simeng-li merged 1 commit into
masterfrom
simeng-log-13472-perf-a-add-index-on-organization_user_relations-tenant_id

Conversation

@simeng-li
Copy link
Copy Markdown
Contributor

@simeng-li simeng-li commented May 15, 2026

Summary

Refs LOG-13472. First task in the Phase 0.5 performance milestone surfaced by the audit before LOG-13462 lands.

What changed

  • packages/schemas/alterations/next-1778500000-add-organization-user-relations-user-id-index.ts — new migration that adds create index concurrently if not exists organization_user_relations__tenant_id_user_id on organization_user_relations (tenant_id, user_id). Built concurrently via the beforeUp hook so no table lock is held during the build. Reversible via beforeDown running drop index concurrently if exists.
  • packages/schemas/tables/organization_user_relations.sql — mirrors the new index inline so fresh installs get it without replaying the alteration.
  • .changeset/index-organization-user-relations-user-id.md@logto/schemas patch.

Expected result

  • Queries that filter by (tenant_id, user_id) without specifying organization_id switch from a partial PK scan to an Index Scan on the new secondary index. The two hot call sites this fixes:
    • getOrganizationsByUserId (packages/core/src/queries/organization/user-relations.ts:78-99) — runs on every token exchange / sign-in / org-list endpoint.
    • The membership-existence middleware on /organizations/:id/users/:userId/roles and /users/:userId/scopes (packages/core/src/utils/RelationQueries.ts:249-265 invoked from routes/organization/user/role-relations.ts:34).
  • No schema, API, or behavior change. Index is purely additive.

Reviewer notes

  • The PK column order (tenant_id, organization_id, user_id) does not serve user_id-only lookups, so they currently degrade. The FK constraint added in 1.30.0-1753669579-add-organization-user-relations-foreign-key.ts only indexes the referenced side (users (tenant_id, id)) — Postgres does not auto-index the referencing side.
  • Build runs via the beforeUp / beforeDown non-transactional hooks so CONCURRENTLY can be used without holding the write-blocking SHARE lock that a plain CREATE INDEX would hold for the duration of the build. This matches the pattern in 1.35.0-1765183934-add-logs-created-at-id-index.ts, 1.35.0-1765631949-drop-redundant-logs-id-index.ts, and 1.38.0-1772615848-add-oidc-model-instances-grant-id-partial-index.ts. if not exists / if exists keep both directions idempotent against transient failures.
  • Index name follows the repo's <table>__<columns> convention. Confirmed unique via grep.

Testing

Tested locally

Checklist

  • .changeset
  • unit tests
  • integration tests
  • necessary TSDoc comments

Copilot AI review requested due to automatic review settings May 15, 2026 06:48
@simeng-li simeng-li requested a review from gao-sun as a code owner May 15, 2026 06:48
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 15, 2026

COMPARE TO master

Total Size Diff 📈 +2.21 KB

Diff by File
Name Diff
.changeset/index-organization-user-relations-user-id.md 📈 +505 Bytes
.gitignore 📈 +18 Bytes
packages/schemas/alterations/next-1778500000-add-organization-user-relations-user-id-index.ts 📈 +1.58 KB
packages/schemas/tables/organization_user_relations.sql 📈 +116 Bytes

@simeng-li simeng-li force-pushed the simeng-log-13472-perf-a-add-index-on-organization_user_relations-tenant_id branch from e3d20bd to 30d74dd Compare May 15, 2026 06:49
@simeng-li simeng-li requested a review from wangsijie as a code owner May 15, 2026 06:49
@github-actions github-actions Bot added size/s and removed size/s labels May 15, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a secondary DB index to improve performance of organization membership reverse lookups (by tenant_id + user_id) that are on the hot path for sign-in/token exchange and membership checks.

Changes:

  • Add a new schema alteration to create (tenant_id, user_id) index on organization_user_relations.
  • Add a changeset bumping @logto/schemas as a patch release.

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 2 comments.

File Description
packages/schemas/alterations/next-1778500000-add-organization-user-relations-user-id-index.ts Adds an alteration to create/drop the new secondary index for (tenant_id, user_id) lookups.
.changeset/index-organization-user-relations-user-id.md Publishes the schema change via a Changeset patch release note for @logto/schemas.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@simeng-li simeng-li force-pushed the simeng-log-13472-perf-a-add-index-on-organization_user_relations-tenant_id branch from 30d74dd to 44a9e9e Compare May 15, 2026 06:58
@github-actions github-actions Bot added size/s and removed size/s labels May 15, 2026
@simeng-li simeng-li requested a review from Copilot May 15, 2026 06:59
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 4 changed files in this pull request and generated no new comments.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 4 changed files in this pull request and generated 1 comment.

The primary key on organization_user_relations is
(tenant_id, organization_id, user_id), which prevents queries that filter
by user_id without specifying organization_id from using the index.
getOrganizationsByUserId (called on every sign-in) and the membership-
existence middleware on /organizations/:id/users/:userId/roles endpoints
both fall through to a partial scan today.

The FK constraint organization_user_relations__user_id__fk added in
1.30.0 references users (tenant_id, id) and indexes only the referenced
side; Postgres does not auto-index the referencing side.

The new index is added to both the alteration script (for existing
databases) and the table source file (for fresh installs), matching the
pattern of the prior FK alteration on the same table.

Refs LOG-13472
@simeng-li simeng-li force-pushed the simeng-log-13472-perf-a-add-index-on-organization_user_relations-tenant_id branch from 44a9e9e to 33f35a6 Compare May 15, 2026 09:34
@github-actions github-actions Bot added size/s and removed size/s labels May 15, 2026
@simeng-li simeng-li merged commit 6172751 into master May 18, 2026
45 of 46 checks passed
@simeng-li simeng-li deleted the simeng-log-13472-perf-a-add-index-on-organization_user_relations-tenant_id branch May 18, 2026 02:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Development

Successfully merging this pull request may close these issues.

4 participants