Dynatroni (Patroni DynamoDB DCS)
Dynatroni is a DynamoDB-based Distributed Configuration Store (DCS) backend for Patroni PostgreSQL HA.
Features
- DynamoDB as arbiter: leader election via DynamoDB atomic operations
- No quorum requirement: a single surviving node can operate
- AWS-native: IAM auth, managed service
- Cost-effective: pay‑per‑request pricing for small clusters
- Highly available: DynamoDB's built‑in multi‑AZ replication
Docs
- Docs index
- Install & quickstart
- DynamoDB setup
- Configuration & environment
- Multi‑AZ & cold start
- Break‑glass promotion
- Operations & troubleshooting
Installation
python -m pip install --upgrade 'dynatroni>=0.1.1' 'patroni[psycopg3]'
Install into the same virtual environment that runs Patroni. Version 0.1.1 includes the discovery fix for issue #2. See Install & quickstart for the discovery check, source installation, and troubleshooting.
DynamoDB Table Setup
Create a DynamoDB table with:
- Partition Key:
cluster_name(String) - Sort Key:
key(String) - TTL attribute:
ttl
aws dynamodb create-table \
--table-name patroni-dynamodb \
--attribute-definitions \
AttributeName=cluster_name,AttributeType=S \
AttributeName=key,AttributeType=S \
--key-schema \
AttributeName=cluster_name,KeyType=HASH \
AttributeName=key,KeyType=RANGE \
--billing-mode PAY_PER_REQUEST
aws dynamodb update-time-to-live \
--table-name patroni-dynamodb \
--time-to-live-specification "Enabled=true,AttributeName=ttl"
Patroni Configuration
In your patroni.yml:
scope: my-cluster
name: node1
dynamodb:
region: us-east-1
table_name: patroni-dynamodb
# Single dial for cost vs responsiveness tradeoff:
# 15s = fast failover, ~24 DynamoDB ops/min
# 60s = balanced (default), ~6 ops/min
# 180s = cost optimized, ~2 ops/min
failover_time: 60
# Optional: for local testing with DynamoDB Local
# endpoint_url: http://localhost:8000
# Timing values are derived from failover_time:
# ttl = failover_time
# loop_wait = failover_time / 3
# retry_timeout = failover_time / 3
# ... rest of patroni config
IAM Permissions
The EC2 instance role needs:
{
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:UpdateItem",
"dynamodb:DeleteItem",
"dynamodb:Query",
"dynamodb:BatchWriteItem"
],
"Resource": "arn:aws:dynamodb:REGION:ACCOUNT:table/patroni-dynamodb"
}
How It Works
Dynatroni uses DynamoDB as a distributed lock service for PostgreSQL leader election.
Leader Election (Atomic Operations)
All leader operations use conditional writes to ensure exactly one leader:
| Operation | Condition | Guarantees |
|---|---|---|
| Acquire (new cluster) | attribute_not_exists |
Only one node creates the lock |
| Renew (current leader) | session = :mine |
Only the holder can extend |
| Takeover (expired TTL) | ttl < :now |
Only one node wins the race |
| Release (step down) | session = :mine |
Only the holder can release |
The lock has a TTL (default 60s). If not renewed, it expires and another node can take over atomically.
Boundaries
- Single leader guarantee: Conditional writes prevent split-brain
- Leader lease: Bounded by TTL; leader must renew before expiry
- Failure detection:
failover_timebounds how long a dead leader blocks promotion - No fencing tokens: Relies on session IDs and TTL; applications should use PostgreSQL's own fencing
See docs/dynamodb.md for implementation details.
License
MIT
Metadata
Release files for dynatroni 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| dynatroni-0.1.1.tar.gz | 15.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| dynatroni-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 29.1 kB
Release files / dynatroni-0.1.1.tar.gz
| Download URL | dynatroni-0.1.1.tar.gz |
|---|---|
| Size | 15.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9145d7efe342e05cac07df605b4c1a9694fa7a1f65e5601d2ee069a796810351
|
|
BLAKE2b-256 checksum How to use checksums |
8c640dc704bd32a8f7884ee2e7817515d9b68887b65bddab65bc213e6da02673
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.
Transparency logRelease files / dynatroni-0.1.1-py3-none-any.whl
| Download URL | dynatroni-0.1.1-py3-none-any.whl |
|---|---|
| Size | 13.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
91c292a038e6ecde0c5ee72914d7523ade06c1197d115c19309d254dd626af07
|
|
BLAKE2b-256 checksum How to use checksums |
ea24c5d5f421c89d0d42800d997fb131c69a830bce3df65a1e7d3d284eaa3687
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.
Transparency log