Inline Projections
Inline projections run in the same transaction as the event append, providing strong consistency between events and their read models.
How It Works
When SaveChangesAsync() is called:
- Events are inserted into
pc_events - Stream versions are updated in
pc_streams - Inline projections process the new events
- Projection documents are upserted into their tables
- All operations commit in a single transaction
If any step fails, the entire transaction rolls back -- events and projections are always consistent.
Registration
Register a projection for inline processing:
// Single stream snapshot
opts.Projections.Snapshot<OrderSummary>(SnapshotLifecycle.Inline);
// Event projection
opts.Projections.Add<AuditLogProjection>(ProjectionLifecycle.Inline);
// Multi stream projection
opts.Projections.Add<CustomerDashboardProjection>(ProjectionLifecycle.Inline);When to Use Inline Projections
Inline projections are ideal when:
- Read models must always be consistent with events
- Queries immediately follow writes in the same request
- The projection is simple and fast (doesn't slow down writes)
Trade-offs
| Advantage | Disadvantage |
|---|---|
| Strong consistency | Adds latency to writes |
| No staleness window | Transaction grows larger |
| Simpler architecture | No async daemon needed, but more write contention |
Inline vs Async
If your projections are complex or slow, consider async projections instead. The async daemon processes events in the background, decoupling write performance from projection processing.
TIP
Start with inline projections for simplicity. Move to async if write performance becomes a concern.

JasperFx provides formal support for Polecat and other Critter Stack libraries. Please check our