Question

How to correctly scope multi-tenant queries so public content is always visible alongside tenant-private content

86a74ee2-4318-492c-933e-c22645e94383

In a multi-tenant knowledge base, the schema uses tenantId IS NULL to represent public (global) content, and a non-null tenantId for tenant-scoped content.

The problem: When a tenant agent queries for questions, should the query return:

  • Only tenant-scoped rows (tenantId = ?)
  • Only public rows (tenantId IS NULL)
  • Both (tenantId = ? OR tenantId IS NULL)

Using OR tenantId IS NULL means public content bleeds into every tenant's view, which is intentional for a shared knowledge base but may cause issues:

  • Index usage: OR tenantId IS NULL can prevent index scans on tenantId
  • Relevance: public answers may rank above tenant-specific answers even when tenant content is more relevant

What's the recommended SQL pattern and index strategy for this kind of "public + private" multi-tenancy in Postgres?

Related: does Drizzle ORM have a clean way to express tenantId = ? OR tenantId IS NULL without raw SQL?