From 96e6bb23472735d4d1dec299d41e19a38f63adbd Mon Sep 17 00:00:00 2001 From: Ellie Huxtable Date: Thu, 18 Dec 2025 16:12:39 -0500 Subject: feat: add support for read replicas to postgres (#3029) Support for routing read queries to read replicas for Postgres We have very high database usage these days, and now run shell history sync off of [Planetscale](https://planetscale.com/) This setup gives us 2x read replicas, meaning we can reduce load on the primary I doubt this is required for anyone else's setup - lmk if so. --- crates/atuin-server-database/src/lib.rs | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'crates/atuin-server-database/src/lib.rs') diff --git a/crates/atuin-server-database/src/lib.rs b/crates/atuin-server-database/src/lib.rs index e70c755c..db170b50 100644 --- a/crates/atuin-server-database/src/lib.rs +++ b/crates/atuin-server-database/src/lib.rs @@ -51,6 +51,8 @@ pub enum DbType { #[derive(Clone, Deserialize, Serialize)] pub struct DbSettings { pub db_uri: String, + /// Optional URI for read replicas. If set, read-only queries will use this connection. + pub read_db_uri: Option, } impl DbSettings { @@ -65,22 +67,29 @@ impl DbSettings { } } +fn redact_db_uri(uri: &str) -> String { + url::Url::parse(uri) + .map(|mut url| { + let _ = url.set_password(Some("****")); + url.to_string() + }) + .unwrap_or_else(|_| uri.to_string()) +} + // Do our best to redact passwords so they're not logged in the event of an error. impl Debug for DbSettings { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { if self.db_type() == DbType::Postgres { - let redacted_uri = url::Url::parse(&self.db_uri) - .map(|mut url| { - let _ = url.set_password(Some("****")); - url.to_string() - }) - .unwrap_or(self.db_uri.clone()); + let redacted_uri = redact_db_uri(&self.db_uri); + let redacted_read_uri = self.read_db_uri.as_ref().map(|uri| redact_db_uri(uri)); f.debug_struct("DbSettings") .field("db_uri", &redacted_uri) + .field("read_db_uri", &redacted_read_uri) .finish() } else { f.debug_struct("DbSettings") .field("db_uri", &self.db_uri) + .field("read_db_uri", &self.read_db_uri) .finish() } } -- cgit v1.3.1