PSA vs PSS Replica Set Configurations in MongoDB: A Complete Guide
PSA (Primary-Secondary-Arbiter) uses two data-bearing nodes plus a voting arbiter to save storage, while PSS (Primary-Secondary-Secondary) uses three data-bearing nodes for full redundancy and better read scaling.
Choosing the right replica set topology is critical when deploying MongoDB clusters with Docker Compose. The minhhungit/mongodb-cluster-docker-compose repository demonstrates both patterns, showing how PSA configurations minimize disk usage for development environments while PSS configurations provide production-grade fault tolerance.
What Are PSA and PSS Replica Set Configurations in MongoDB?
MongoDB replica sets maintain multiple copies of data across nodes to ensure high availability and automatic failover. The PSA and PSS acronyms describe the composition of three-member replica sets:
- PSA: One Primary (accepts writes), one Secondary (replicates data), and one Arbiter (votes in elections but stores no data).
- PSS: One Primary and two Secondary members, all of which store the complete dataset.
These configurations are implemented in the repository's Docker Compose files, with the root docker-compose.yml defining the PSS topology and PSA/docker-compose.yml defining the PSA variant.
Key Differences Between PSA and PSS Architectures
Node Composition and Data Bearing Members
The fundamental distinction lies in how the third member participates in the cluster. In a PSA configuration, the arbiter maintains only replica set metadata—roughly a few kilobytes—while the primary and secondary each hold the full data volume. Conversely, PSS requires three times the base storage since shard01-b and shard01-c (in the repository's naming convention) both maintain complete replication copies.
Failover Behavior and Voting Mechanics
Both configurations require a majority of votes (two out of three) to elect a primary. However, failover resilience differs:
- PSA: If the primary fails, the secondary and arbiter can elect a new primary. If the secondary fails, the primary and arbiter maintain quorum, but there is no remaining data-bearing backup until recovery.
- PSS: Any two surviving nodes can elect a primary, and with two secondaries, the cluster can survive the loss of any single node while maintaining both quorum and data redundancy.
Storage Requirements and Resource Utilization
The PSA pattern reduces storage costs by approximately 33% compared to PSS, making it suitable for resource-constrained environments. The arbiter container in PSA/docker-compose.yml uses minimal CPU and memory since it does not process replication batches or serve queries. PSS consumes three full storage allocations but provides better data durability through triple replication.
Read Scaling Capabilities
PSS configurations enable superior read distribution. MongoDB drivers can route read operations to secondary members using read preferences. With two secondaries available in PSS, the cluster handles twice the read throughput compared to PSA, which offers only one secondary for read scaling. The arbiter in PSA contributes zero query capacity.
Implementation Examples from the Source Code
PSA Configuration: Primary-Secondary-Arbiter
The PSA/docker-compose.yml file defines containers for shard01-a (primary), shard01-b (secondary), and shard01-x (arbiter). Initialization requires explicitly adding the arbiter after shard setup:
# Navigate to the PSA directory
cd PSA
docker-compose up -d
# Initialize config servers and shards
docker-compose exec configsvr01 sh -c "mongosh < /scripts/init-configserver.js"
docker-compose exec shard01-a sh -c "mongosh < /scripts/init-shard01.js"
# Add the arbiter to achieve PSA topology
docker-compose exec shard01-a mongosh --port 27017 -e 'rs.addArb("shard01-x:27017")'
The rs.addArb() command registers the arbiter in PSA/readme.md (lines 30-35), allowing the replica set to maintain quorum without storing data on the third node.
PSS Configuration: Primary-Secondary-Secondary
The root docker-compose.yml implements the PSS pattern using three data-bearing members per shard (e.g., shard01-a, shard01-b, shard01-c). Initialization is straightforward since all nodes are full secondaries:
# From the repository root (PSS is default)
docker-compose up -d
# Initialize config server and shards
docker-compose exec configsvr01 sh -c "mongosh < /scripts/init-configserver.js"
docker-compose exec shard01-a sh -c "mongosh < /scripts/init-shard01.js"
docker-compose exec shard02-a sh -c "mongosh < /scripts/init-shard02.js"
docker-compose exec shard03-a sh -c "mongosh < /scripts/init-shard03.js"
# Initialize routers
docker-compose exec router01 sh -c "mongosh < /scripts/init-router.js"
As noted in readme.md (lines 9, 57-61), this configuration provides full redundancy with no arbiter containers, ensuring every node can serve reads and participate in failover elections as a potential primary.
When to Choose PSA vs PSS
Select PSA when:
- Storage costs must be minimized and you can tolerate reduced redundancy.
- The environment is resource-constrained (development or testing clusters).
- You need voting quorum for failover but do not require additional read capacity.
Select PSS when:
- Production workloads demand high availability with full data redundancy.
- Read scaling is critical, and you need to distribute query load across multiple secondaries.
- Disaster recovery requirements mandate that any two nodes contain the complete dataset.
Summary
- PSA (Primary-Secondary-Arbiter) uses two data-bearing nodes and one voting arbiter to reduce storage costs while maintaining failover capability.
- PSS (Primary-Secondary-Secondary) employs three full data-bearing nodes for maximum redundancy, read scaling, and disaster recovery.
- The
minhhungit/mongodb-cluster-docker-composerepository implements both patterns, with PSA defined inPSA/docker-compose.ymlrequiringrs.addArb()initialization, and PSS defined in the rootdocker-compose.ymlwith three standard secondary members. - Choose PSA for cost-sensitive development environments and PSS for production workloads requiring robust fault tolerance.
Frequently Asked Questions
Can an arbiter in a PSA configuration become a primary?
No, an arbiter cannot become a primary or hold data. According to the repository's PSA implementation in PSA/readme.md, the arbiter node (shard01-x) participates only in election voting to help achieve a majority quorum. If both the primary and secondary fail, the arbiter alone cannot elect itself or maintain database availability.
Does a PSA configuration provide the same data redundancy as PSS?
No, PSA provides less data redundancy than PSS. In the PSA topology demonstrated in PSA/docker-compose.yml, only two nodes store data, meaning if both the primary and secondary fail simultaneously, data becomes unavailable despite the arbiter maintaining quorum. The PSS configuration in the root docker-compose.yml stores the full dataset on three nodes, allowing the cluster to survive the loss of any single node without data loss.
How do I verify which replica set configuration my MongoDB shard is using?
Run the rs.status() command from any member to inspect the replica set composition. As shown in the repository's verification examples, execute:
docker exec -it shard-01-node-a bash -c "echo 'rs.status()' | mongosh --port 27017"
Look for the "stateStr" field in the members array. If one member reports "ARBITER", you are running a PSA configuration. If all members report "PRIMARY" or "SECONDARY", you are running a PSS configuration.
What happens if the arbiter fails in a PSA configuration?
If the arbiter fails in a PSA deployment, the replica set loses its voting majority capability if one data-bearing node also fails. According to the failover behavior documented in the repository, the surviving primary and secondary can continue operating, but if the secondary subsequently fails, the primary would step down because it cannot achieve a majority (two of three votes) alone. The cluster would then become read-only until the arbiter or secondary is restored.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →