# PSA vs PSS Replica Set Configurations in MongoDB: A Complete Guide

> Understand the differences between PSA and PSS replica set configurations in MongoDB. Learn how PSA uses an arbiter for storage savings and PSS offers full redundancy and read scaling.

- Repository: [Jin/mongodb-cluster-docker-compose](https://github.com/minhhungit/mongodb-cluster-docker-compose)
- Tags: deep-dive
- Published: 2026-03-07

---

**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`](https://github.com/minhhungit/mongodb-cluster-docker-compose/blob/main/docker-compose.yml) defining the PSS topology and [`PSA/docker-compose.yml`](https://github.com/minhhungit/mongodb-cluster-docker-compose/blob/main/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`](https://github.com/minhhungit/mongodb-cluster-docker-compose/blob/main/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`](https://github.com/minhhungit/mongodb-cluster-docker-compose/blob/main/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:

```bash

# 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`](https://github.com/minhhungit/mongodb-cluster-docker-compose/blob/main/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`](https://github.com/minhhungit/mongodb-cluster-docker-compose/blob/main/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:

```bash

# 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`](https://github.com/minhhungit/mongodb-cluster-docker-compose/blob/main/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-compose` repository implements both patterns, with PSA defined in [`PSA/docker-compose.yml`](https://github.com/minhhungit/mongodb-cluster-docker-compose/blob/main/PSA/docker-compose.yml) requiring `rs.addArb()` initialization, and PSS defined in the root [`docker-compose.yml`](https://github.com/minhhungit/mongodb-cluster-docker-compose/blob/main/docker-compose.yml) with 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`](https://github.com/minhhungit/mongodb-cluster-docker-compose/blob/main/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`](https://github.com/minhhungit/mongodb-cluster-docker-compose/blob/main/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`](https://github.com/minhhungit/mongodb-cluster-docker-compose/blob/main/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:

```bash
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.