Article

Per-User Projections: Advantages, Disadvantages, and When They're Worth It

Per-user projections are one of the most powerful (and most misunderstood) ideas in event-driven, collaboration-heavy systems. This article explains what they are, why they exist, their advantages and disadvantages, and when they're worth the cost.

Jorge Leal Portela
Jorge Leal PortelaDecember 10, 2025
Dashboard timeout error showing rendering failure - illustrating what happens when projections lag or fail to update synchronously

Per-user projections are one of the most powerful (and most misunderstood) ideas in event-driven, collaboration-heavy systems.

The core idea is simple:

A projection is not just DashboardProjection — it is DashboardProjection(userId).

Instead of building one global read model and filtering at query time, the system maintains materialized views per user: each user gets a precomputed slice of the world that already reflects visibility rules, relevance, and workflow context.

This approach fits naturally with systems where collaboration is driven by:

  • entity state (where the work is)
  • roles and responsibilities (who is involved)
  • policies (who can see/do what)
  • notifications (who should be informed)

It also introduces real cost, especially at scale. This article explains both sides.

What is a Per-User Projection?

A per-user projection is a read model keyed by user context:

  • (projectionName, userId)
    e.g. ("my-dashboard", 123)
  • (projectionName, tenantId, userId)
    e.g. ("my-inbox", "acme", 123)

Typical examples:

  • My Dashboard (counts, KPIs, state distributions relevant to the user)
  • My Inbox / My Queue (entities waiting for my action)
  • My Approvals (items requiring my approval)
  • My Work / Assigned to Me
  • Watched / Followed Entities
  • Notifications Feed / Unread Counts

Instead of computing these views at query time (filtering + ACL checks + joins), the system computes them as events arrive and stores them for fast lookup.

Why Per-User Projections Exist

Per-user projections exist because policy-driven collaboration systems must answer questions fast and consistently:

  • Who can see this entity?
  • What actions are allowed for this user right now?
  • What should this user work on next?
  • Who should be notified when this changes?
  • What should this user's dashboard show immediately after they act?

If these answers are computed dynamically on every UI request, the system tends to become slow and inconsistent:

  • expensive permission checks at query time
  • duplicated policy logic across services
  • dashboards that lag or disagree with detail views
  • "button appears but action is rejected" UX

Per-user projections turn these "policy outcomes" into materialized data the UI can use instantly.

Advantages

1) Excellent read performance

A user opens a dashboard or inbox and the system fetches a small set of precomputed records. No expensive filtering, joins, or repeated policy checks.

This makes homepages, dashboards, and "my work" views feel instant.

2) Policies become materialized

Visibility, relevance, and user-specific rules can be applied during projection building.

Instead of filtering forbidden entities at read time, the read model already contains only what the user is allowed to see.

This reduces both complexity and risk.

3) Consistency across UI, backend, and notifications

If the same projection logic drives:

  • dashboard contents
  • inbox/work queues
  • notification audiences
  • allowed actions shown in the UI

…then the system becomes consistent by construction.

Per-user projections help avoid the common drift where different parts of the product interpret policies differently.

4) Great support for notifications and "unread" semantics

Per-user projections naturally store:

  • unread counts
  • badge indicators
  • last-seen markers
  • per-user relevance

This makes notification UX easy and predictable without heavy runtime computation.

5) Simplifies complex read logic

If relevance depends on:

  • entity state
  • assignments
  • watchers/followers
  • role membership
  • participation history

…computing that dynamically becomes expensive.

Per-user projections move the complexity into one place: the projection engine.

6) Great fit for state-driven collaboration

In state-based systems, users do not want "all entities." They want entities that matter to them in the current lifecycle stage.

Per-user projections align naturally with work queues like:

  • "waiting for my approval"
  • "assigned to me"
  • "blocked items I own"
  • "items in review for my team"

7) Enables synchronous UX when needed

Per-user projections make it feasible to update only the requesting user's view synchronously.

This is crucial for dashboards and other interactive screens where the user expects immediate consistency after acting.

The Critical UX Pattern: Synchronous Projection Update (When Needed)

Most projections should update asynchronously, driven by the event stream. But interactive dashboards are different.

If a user changes an entity and immediately looks at their dashboard, a lagging projection feels like the system is broken.

A pragmatic pattern:

  1. The UI knows which projection powers the current dashboard/view.
  2. The UI sends the command with a projectionName hint.
  3. The command handler processes the command and commits events.
  4. Immediately after commit, the command handler triggers a synchronous projection update for:
    • the affected entity
    • that specific projection
    • the requesting user context
  5. The updated projection result is returned immediately to the UI.

This is intentionally narrow: it updates only what the user is looking at, not all projections.

The event-driven asynchronous pipeline still updates everything else normally.

Disadvantages and Tradeoffs

1) Projection instance explosion (U × P)

If you have:

  • U users
  • P per-user projection types

Then you maintain up to:

  • U × P projection instances

Example:

10,000 users × 5 projections = 50,000 projection instances

This can be perfectly manageable, but it requires thoughtful storage and lifecycle management.

2) Fan-out on events (E × F × P)

Per-user projections introduce a fan-out factor.

Let:

  • E = events per second
  • F = average number of users affected by an entity change
  • P = per-user projections impacted per user

Then the update rate is roughly:

Async projection updates per second ≈ E × F × P

This is the core cost of per-user projections: not storage, but update volume.

3) You must determine the "audience" of each change

To update per-user projections, the system must know who is affected:

  • assignee
  • owner
  • reporter/requester
  • watchers/followers
  • team members
  • role holders

This "who cares?" logic becomes central.

4) Stronger requirements for ordering and idempotency

Projection processing must be robust:

  • idempotent event handling
  • consistent event ordering (or compensating logic)
  • offsets / checkpoints per projection stream

Otherwise user views drift, and the system loses trust.

5) More work on writes to make reads effortless

Per-user projections shift cost from reads to writes.

This is a great tradeoff when:

  • reads are frequent
  • UX must feel instant
  • policy logic is complex

But it must be designed intentionally, not accidentally.

When Per-User Projections Are Worth It

They are usually worth it when:

  • the product is collaboration-heavy
  • policy logic is complex (visibility + actions + assignment + notifications)
  • dashboards and "my work" queues are central to user experience
  • you want consistent behavior across UI/backend/notifications
  • you have a high read-to-write ratio

They are often not worth it when:

  • user views are mostly the same (shared/global read models are enough)
  • the system is low-scale and simple
  • policies are trivial and can be evaluated cheaply at query time
  • event fan-out would be extreme and cannot be controlled

Summary

Per-user projections are a powerful architectural choice for policy-driven collaboration systems.

They make the user experience fast and coherent by materializing:

  • visibility
  • relevance
  • action availability
  • assignment context
  • notification targeting
  • dashboards and work queues

The cost is real:

  • more projection instances
  • fan-out on updates
  • more responsibility in the projection engine

But when collaboration is the product, per-user projections often turn "policy chaos" into a predictable, scalable system.

The key is to treat them as a deliberate design tool—not a side effect.

Related content

Explore these related topics:

Explore more articles

This article is part of a series exploring collaboration patterns and practices. Check out other articles or dive into the framework components.