Skip to content

perf: cache selected organization per request#2267

Merged
DonKoko merged 5 commits intomainfrom
feat-implement-cache-for-getSelectedOrganisation
Jan 16, 2026
Merged

perf: cache selected organization per request#2267
DonKoko merged 5 commits intomainfrom
feat-implement-cache-for-getSelectedOrganisation

Conversation

@DonKoko
Copy link
Copy Markdown
Contributor

@DonKoko DonKoko commented Jan 15, 2026

Request-scoped caching for selected organization (AsyncLocalStorage)

What changed

  • Added an AsyncLocalStorage-backed request cache and wrapped each request in it.
  • getSelectedOrganisation now uses the request cache to reuse the same in-flight promise per user.
  • Kept the same fallback/eviction behavior on errors.

Why

  • Remix single-fetch still runs multiple loaders/actions in parallel, but each loader can receive a cloned Request, so Request-keyed caches don’t hit.
  • This caused repeated userOrganization.findMany calls within the same HTTP request, which amplified Prisma connection pool pressure.
  • AsyncLocalStorage provides a true request-scoped store that survives Request cloning.

Impact

  • One userOrganization.findMany per request/user, even when multiple loaders fire.
  • Lower peak DB connections during data-heavy pages (e.g., bookings).
  • No behavior change for org selection; only dedupes work.

Notes

  • Cache is scoped to a single request to avoid stale cross-request data.
  • hasPermission fallback query is unchanged and remains a defensive edge case.

@vercel
Copy link
Copy Markdown

vercel bot commented Jan 15, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Review Updated (UTC)
shelf-docs Ignored Ignored Preview Jan 16, 2026 11:08am

Review with Vercel Agent

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

This PR optimizes database query performance by caching getSelectedOrganisation results per request, reducing redundant queries when parallel loaders call requirePermission.

Changes:

  • Added per-request caching using WeakMap to store organization lookup promises
  • Refactored the original function into getSelectedOrganisationUncached as the implementation
  • Created a new wrapper getSelectedOrganisation that implements promise-based caching

Comment thread app/modules/organization/context.server.ts Outdated
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 3 changed files in this pull request and generated 6 comments.

Comment thread app/utils/request-cache.server.ts Outdated
Comment thread app/modules/organization/context.server.ts Outdated
Comment thread app/modules/organization/context.server.ts Outdated
Comment thread app/modules/organization/context.server.ts Outdated
Comment thread app/modules/organization/context.server.ts Outdated
Comment thread app/modules/organization/context.server.ts Outdated
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 11 out of 11 changed files in this pull request and generated 1 comment.

Comment thread app/utils/request-cache.server.ts Outdated
@DonKoko DonKoko merged commit c6e72d3 into main Jan 16, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants