NetBox ↔ PostgreSQL Read‑Only Replica: Offloading Reads for Low‑Traffic Workloads
0 reputation · 11 May 2022, 02:57 UTC
0 reputation · 11 May 2022, 02:57 UTC
The goal is to determine whether NetBox can automatically direct read‑only SQL traffic to a PostgreSQL replica without requiring administrators to define a custom database router, thereby lowering hardware or managed‑service costs for low‑traffic deployments.
NetBox documentation shows that a read‑only replica can be used, but it requires setting DATABASES with a READ_REPLICA_URL and enabling DATABASE_ROUTERS, leaving it unclear if the framework supplies a built‑in router for this pattern. Concerns include replication lag causing stale UI data and the operational overhead of maintaining a replica, which may offset savings in very small environments. Does NetBox provide a built‑in database router that routes SELECT queries to a read‑only replica, or must a custom router be implemented? What performance impact does a custom router have compared with native connection pooling? How much replication lag is acceptable before UI inconsistency becomes a concern for change‑management workflows?
As of the current NetBox releases, the framework provides no automatic router that directs SELECT statements to a PostgreSQL replica. You must define a custom database router class and add it to DATABASE_ROUTERS while setting READ_REPLICA_URL in DATABASES.
DATABASES (e.g., replica) with the READ_REPLICA_URL pointing to the standby.class ReadReplicaRouter:
def db_for_read(self, model, **hints):
return 'replica' if settings.READ_REPLICA_URL else 'default'
def db_for_write(self, model, **hints):
return 'default'
def allow_relation(self, obj1, obj2, **hints):
db_set = {'default', 'replica'}
return obj1._state.db in db_set and obj2._state.db in db_set
def allow_migrate(self, db, app_label, model_name=None, **hints):
return db == 'default'
DATABASE_ROUTERS in configuration.py.The router adds only a few attribute look‑ups per request (typically db_for_read and db_for_write). This overhead is far below the cost of establishing a database connection and is negligible compared with query execution time. It does not interfere with Django’s native connection pooling.
For change‑management views that tolerate brief staleness, a lag of roughly 2‑5 seconds is generally acceptable. UI elements may show recently created or updated objects slightly delayed, but core functionality remains intact. Monitor lag with PostgreSQL’s pg_stat_replication or tools like check_postgres replication lag.
If your workflow requires sub‑second consistency (e.g., real‑time validation of newly created devices), please confirm that tolerance, as a replica may not be suitable in that case.
Use comments to ask for clarification. Post a solution as an answer.
34,775 reputation · 11 May 2022, 14:42 UTC
NetBox’s DATABASES configuration accepts a readonly flag that can direct connections to a configured PostgreSQL read‑only replica without implementing a custom router. The flag relies on PostgreSQL’s default_transaction_read_only session setting, which prevents write operations at the database level. For low‑traffic deployments, pairing this with pgbouncer in transaction pool mode reduces connection overhead. However, replication lag remains the primary risk; monitoring pg_stat_replication and enforcing a lag threshold (e.g., <5 seconds) before serving UI changes helps avoid stale data in change‑management workflows.