# Scaling & Provisioning ## Consumer Modes The projection supports two JetStream consumption modes (configured via `PROJECTION_CONSUMER_MODE`): - `single`: one durable consumer per projection process. Each message is processed once and the projection updates all `view_type`s defined in the manifest for that message. - `per_view`: one durable consumer per `view_type`. Each consumer processes all events, but only updates its own `view_type` (checkpoint isolation and independent scaling). In `per_view` mode, durable names are derived as: `{PROJECTION_DURABLE_NAME}_{view_type}` (with non `[A-Za-z0-9_-]` replaced by `_`). ## Replica Scaling To scale replicas, run multiple instances with the same durable name(s): - `single` mode: all replicas share one durable consumer and work-steal messages from that consumer. - `per_view` mode: all replicas share a durable consumer per `view_type`. ## Sharding JetStream subject filtering does not support “hash/range shard by aggregate_id” on the consumer side. If strict per-entity ordering is required across replicas, sharding must be encoded in the published subjects (for example `shard..tenant..aggregate..`), and each shard must run with a matching `PROJECTION_SUBJECT_FILTERS` value. Without subject-based sharding, multiple replicas can process events for the same `view_id` concurrently, which can break projections that depend on ordered read-modify-write updates.