<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Andrei Sergeev</title>
    <description>The latest articles on DEV Community by Andrei Sergeev (@anselvo).</description>
    <link>https://dev.to/anselvo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1104219%2Fe2f81f62-f8e7-4ffa-848e-e37227b0e7ec.png</url>
      <title>DEV Community: Andrei Sergeev</title>
      <link>https://dev.to/anselvo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/anselvo"/>
    <language>en</language>
    <item>
      <title>Troubleshoot MongoDB Replica Sets Easily with Ivory</title>
      <dc:creator>Andrei Sergeev</dc:creator>
      <pubDate>Thu, 05 Nov 2026 11:30:00 +0000</pubDate>
      <link>https://dev.to/anselvo/troubleshoot-mongodb-replica-sets-easily-with-ivory-2464</link>
      <guid>https://dev.to/anselvo/troubleshoot-mongodb-replica-sets-easily-with-ivory-2464</guid>
      <description>&lt;h2&gt;
  
  
  Primary, secondaries, heartbeats and lag of the whole replica set in one screen — plus a step-down and a config editor when you need them
&lt;/h2&gt;

&lt;p&gt;MongoDB is one of the easier databases to run highly available. A replica set elects its own primary, fails over by itself, and doesn't need a separate HA tool next to it.&lt;/p&gt;

&lt;p&gt;But "it fails over by itself" doesn't mean "you never need to look at it". You still need to know who's primary right now, whether the secondaries keep up, and why one member keeps missing heartbeats. That usually means &lt;code&gt;rs.status()&lt;/code&gt; — and a long JSON document to scroll through.&lt;/p&gt;

&lt;p&gt;So I taught &lt;a href="https://ivory.veegres.com" rel="noopener noreferrer"&gt;Ivory&lt;/a&gt; to read it for me.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problems
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;rs.status()&lt;/code&gt; is long.&lt;/strong&gt; The answer is in there, somewhere in a deeply nested document, one member at a time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Chained replication hides lag.&lt;/strong&gt; A secondary syncing from &lt;em&gt;another secondary&lt;/em&gt; inherits that secondary's lag, and nothing on the surface tells you why it's slow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Heartbeat failures depend on who's looking.&lt;/strong&gt; Member A can't reach member B, but B looks fine from C. You only see it from A's point of view.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Members in odd states.&lt;/strong&gt; &lt;code&gt;RECOVERING&lt;/code&gt;, &lt;code&gt;ROLLBACK&lt;/code&gt;, &lt;code&gt;STARTUP&lt;/code&gt; — each means something different, and each matters during an incident.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The wrong replica set.&lt;/strong&gt; Point a node at the wrong address, and you're looking at a perfectly healthy member of a &lt;em&gt;different&lt;/em&gt; replica set.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How Ivory solves them
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The whole replica set from one member
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;replSetGetStatus&lt;/code&gt; from any member returns the whole replica set, so Ivory can show everything from a single node. Add your cluster by typing its addresses, or give Ivory just &lt;strong&gt;one&lt;/strong&gt; node and let it &lt;strong&gt;detect&lt;/strong&gt; the rest.&lt;/p&gt;

&lt;p&gt;The overview shows every member:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Role&lt;/strong&gt; — &lt;code&gt;PRIMARY&lt;/code&gt; is the leader, &lt;code&gt;SECONDARY&lt;/code&gt; is a replica. &lt;code&gt;RECOVERING&lt;/code&gt; and &lt;code&gt;ROLLBACK&lt;/code&gt; are replicas still catching up, &lt;code&gt;STARTUP&lt;/code&gt; is starting, an arbiter is running with no data role, and a member that's &lt;code&gt;DOWN&lt;/code&gt; is unreachable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lag&lt;/strong&gt; — seconds a member is behind the primary. Ivory warns past &lt;strong&gt;30 seconds&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tags&lt;/strong&gt; — only what's worth your attention: the member state when it's anything but primary or secondary, the &lt;strong&gt;sync source&lt;/strong&gt; when a secondary replicates from another secondary, and the heartbeat ping.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That sync source tag is the one I like most. When a secondary is slow because it's chained behind another secondary, the answer is right on the row.&lt;/p&gt;

&lt;h3&gt;
  
  
  Warnings that say who saw what
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Failed heartbeats&lt;/strong&gt; — and &lt;em&gt;which member saw them&lt;/em&gt;. "Heartbeat from mongo1 failed" is a very different story from "mongo2 is down".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MongoDB's own info message&lt;/strong&gt; for a member, passed through as is, in MongoDB's own words.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And because every node reports its &lt;strong&gt;replica set name&lt;/strong&gt;, a node from another set is flagged right away.&lt;/p&gt;

&lt;h3&gt;
  
  
  Operations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Failover&lt;/strong&gt; — asks the current primary to step down (&lt;code&gt;replSetStepDown&lt;/code&gt;), so the set elects another one. Great before maintenance on the primary's host.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;View and edit&lt;/strong&gt; the replica set configuration (&lt;code&gt;replSetGetConfig&lt;/code&gt; / &lt;code&gt;replSetReconfig&lt;/code&gt;). Be careful here: an edit replaces the whole configuration document.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  A shell-style console
&lt;/h3&gt;

&lt;p&gt;Each node has a console that feels like the Mongo shell: &lt;code&gt;collection.find()&lt;/code&gt;, &lt;code&gt;findOne&lt;/code&gt;, &lt;code&gt;insertOne&lt;/code&gt;/&lt;code&gt;insertMany&lt;/code&gt;, &lt;code&gt;updateOne&lt;/code&gt;/&lt;code&gt;updateMany&lt;/code&gt;, &lt;code&gt;deleteOne&lt;/code&gt;/&lt;code&gt;deleteMany&lt;/code&gt;, &lt;code&gt;countDocuments&lt;/code&gt;, &lt;code&gt;distinct&lt;/code&gt;, &lt;code&gt;aggregate&lt;/code&gt; and &lt;code&gt;db.runCommand()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can browse databases and collections, &lt;strong&gt;list running operations and kill one&lt;/strong&gt;, and use &lt;strong&gt;saved queries&lt;/strong&gt; for server status, replica set status and config, current operations, index usage and the profiler.&lt;/p&gt;

&lt;h3&gt;
  
  
  The machine behind each node
&lt;/h3&gt;

&lt;p&gt;Give Ivory an SSH key and each node shows its host's CPU, memory, network, processes and any log file. If MongoDB runs in Docker, the Container tab has its logs, inspect, start, stop and restart. A secondary that's slow because of a full disk or a noisy neighbour shows up right there.&lt;/p&gt;

&lt;h2&gt;
  
  
  Need a new replica set?
&lt;/h2&gt;

&lt;p&gt;Ivory deploys one over plain SSH, from a template. Both templates run the official &lt;code&gt;mongo:7&lt;/code&gt; image as replica set members named after your Ivory cluster, and a &lt;strong&gt;post-script on the last node&lt;/strong&gt; runs &lt;code&gt;rs.initiate&lt;/code&gt; once all three are up. Access control is left off.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mongo (Multi Host)&lt;/strong&gt; — three nodes &lt;code&gt;mongo1&lt;/code&gt;–&lt;code&gt;mongo3&lt;/code&gt;, one per machine, on port &lt;code&gt;27017&lt;/code&gt;. Replace the example addresses in the &lt;code&gt;rs.initiate&lt;/code&gt; member list with your hosts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mongo (Single Host)&lt;/strong&gt; — all three on one machine on ports &lt;code&gt;27017&lt;/code&gt;–&lt;code&gt;27019&lt;/code&gt;. Perfect for a test environment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After a deploy, Ivory tells you how each node's &lt;strong&gt;deploy&lt;/strong&gt; and &lt;strong&gt;initialize&lt;/strong&gt; steps ended, so if &lt;code&gt;rs.initiate&lt;/code&gt; fails, you know exactly where.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ask your AI agent
&lt;/h2&gt;

&lt;p&gt;Connect Claude, Cursor or Codex to Ivory's built-in MCP server and ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Which node is the MongoDB primary, and is any secondary lagging?"&lt;/p&gt;

&lt;p&gt;"Why is mongo3 slow? Check its sync source and its machine."&lt;/p&gt;

&lt;p&gt;"Show me the current operations running longer than a minute."&lt;/p&gt;

&lt;p&gt;"Step the primary down so I can patch its host — check the secondaries are caught up first."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It works through Ivory, with your permissions. See the &lt;a href="https://ivory.veegres.com/docs/mcp" rel="noopener noreferrer"&gt;MCP docs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 80:80 &lt;span class="nt"&gt;--restart&lt;/span&gt; always veegres/ivory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;code&gt;http://localhost&lt;/code&gt;, finish the setup wizard and add your replica set. MongoDB support is in &lt;strong&gt;beta&lt;/strong&gt;: it works end to end, and your feedback will help make it stable.&lt;/p&gt;

&lt;p&gt;Let the replica set elect its leaders — you just keep an eye on it. 😉&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Useful links:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ivory.veegres.com/docs/databases/mongodb" rel="noopener noreferrer"&gt;Ivory MongoDB docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ivory.veegres.com" rel="noopener noreferrer"&gt;Website&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/veegres/ivory" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://anselvo.medium.com/troubleshoot-postgres-clusters-easily-with-ivory-eb0a6d61695a" rel="noopener noreferrer"&gt;Troubleshoot Postgres clusters easily with Ivory&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>mongodb</category>
      <category>database</category>
      <category>devops</category>
      <category>ai</category>
    </item>
    <item>
      <title>I Built DTDb — An IMDb for Developer Tools</title>
      <dc:creator>Andrei Sergeev</dc:creator>
      <pubDate>Sat, 31 Oct 2026 22:05:09 +0000</pubDate>
      <link>https://dev.to/anselvo/i-built-dtdb-an-imdb-for-developer-tools-1gkp</link>
      <guid>https://dev.to/anselvo/i-built-dtdb-an-imdb-for-developer-tools-1gkp</guid>
      <description>&lt;p&gt;We developers have strong opinions about the tools we use every day.&lt;/p&gt;

&lt;p&gt;Vim vs. VS Code. PostgreSQL vs. MySQL. Ubuntu vs. Arch. Python vs. Go. And now, with AI coding agents becoming part of everyday development, there are even more tools to compare.&lt;/p&gt;

&lt;p&gt;But where can you actually see what developers think about these tools?&lt;/p&gt;

&lt;p&gt;There are plenty of comparison articles, sponsored rankings, benchmarks, and opinionated blog posts. But I wanted something a little different.&lt;/p&gt;

&lt;p&gt;So I built DTDb — Developer Tools Database.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://dtdb.dev" rel="noopener noreferrer"&gt;https://dtdb.dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What's the idea?&lt;/p&gt;

&lt;p&gt;Think of IMDb, but instead of movies, we're ranking developer tools.&lt;/p&gt;

&lt;p&gt;The concept is simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Developers rate the tools they actually use.&lt;/li&gt;
&lt;li&gt;Tools are organized into categories.&lt;/li&gt;
&lt;li&gt;Each month, ratings are frozen into a ranking.&lt;/li&gt;
&lt;li&gt;You can follow how rankings change over time and see which tools are gaining or losing popularity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is to create a community-driven picture of the developer tools ecosystem.&lt;/p&gt;

&lt;p&gt;What can you find there?&lt;/p&gt;

&lt;p&gt;I've started with several categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Database engines — PostgreSQL, MySQL, Oracle Database, and others.&lt;/li&gt;
&lt;li&gt;Linux distributions — Ubuntu, Debian, Arch Linux, etc.&lt;/li&gt;
&lt;li&gt;Programming languages — Python, JavaScript, Java, and more.&lt;/li&gt;
&lt;li&gt;AI coding agents — Claude Code, GitHub Copilot, OpenAI Codex, etc.&lt;/li&gt;
&lt;li&gt;IDEs and code editors — VS Code, Visual Studio, Notepad++, and others.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is just the beginning. There are plenty of categories and tools I'd like to add.&lt;/p&gt;

&lt;p&gt;Why monthly rankings?&lt;/p&gt;

&lt;p&gt;I didn't want DTDb to become just another leaderboard where positions constantly fluctuate.&lt;/p&gt;

&lt;p&gt;Freezing ratings into monthly snapshots makes it possible to look back and understand how developer preferences evolve.&lt;/p&gt;

&lt;p&gt;For example, it'll be interesting to see how AI coding agents compete over the coming months, or whether developers' preferences for programming languages and databases actually change.&lt;/p&gt;

&lt;p&gt;What's next?&lt;/p&gt;

&lt;p&gt;There are plenty of things I'd like to improve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More categories and developer tools.&lt;/li&gt;
&lt;li&gt;Better ways to explore historical rankings.&lt;/li&gt;
&lt;li&gt;More community participation.&lt;/li&gt;
&lt;li&gt;Improvements based on actual user feedback.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But before going too far, I'd love to hear what other developers think.&lt;/p&gt;

&lt;p&gt;I'd love your feedback!&lt;/p&gt;

&lt;p&gt;A few questions I'm particularly interested in:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Does the IMDb analogy make sense for developer tools?&lt;/li&gt;
&lt;li&gt;What categories would you like to see?&lt;/li&gt;
&lt;li&gt;Which tools do you think are missing?&lt;/li&gt;
&lt;li&gt;Would you actually use something like this to discover or compare developer tools?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is an independent project, and I'm still figuring out the best direction for it.&lt;/p&gt;

&lt;p&gt;Check it out: &lt;a href="https://dtdb.dev" rel="noopener noreferrer"&gt;https://dtdb.dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Any feedback, criticism, or suggestions are very welcome!&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>webdev</category>
      <category>programming</category>
      <category>database</category>
    </item>
    <item>
      <title>Troubleshoot etcd Clusters Easily with Ivory</title>
      <dc:creator>Andrei Sergeev</dc:creator>
      <pubDate>Sat, 31 Oct 2026 12:25:00 +0000</pubDate>
      <link>https://dev.to/anselvo/troubleshoot-etcd-clusters-easily-with-ivory-4ib</link>
      <guid>https://dev.to/anselvo/troubleshoot-etcd-clusters-easily-with-ivory-4ib</guid>
      <description>&lt;h2&gt;
  
  
  See the leader, the Raft lag and the alarms of every etcd member in one screen — and move the leader with one click
&lt;/h2&gt;

&lt;p&gt;etcd is one of those databases you don't think about. It sits quietly under your Patroni cluster, or under your Kubernetes control plane, and keeps everyone agreeing on who the leader is.&lt;/p&gt;

&lt;p&gt;Until it doesn't. When etcd hurts, everything built on top of it hurts too. Patroni can't renew its leader lock, the Postgres primary demotes itself, and suddenly your "database incident" is actually an etcd incident.&lt;/p&gt;

&lt;p&gt;I added etcd support to &lt;a href="https://ivory.veegres.com" rel="noopener noreferrer"&gt;Ivory&lt;/a&gt; for exactly this reason. Patroni uses etcd as its coordination store, so if Ivory looks after Patroni, it should look after etcd too.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problems
&lt;/h2&gt;

&lt;p&gt;Here's what troubleshooting etcd usually looks like for me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;etcdctl&lt;/code&gt; needs a lot of flags.&lt;/strong&gt; Endpoints, certificates, &lt;code&gt;--write-out=table&lt;/code&gt;, &lt;code&gt;--cluster&lt;/code&gt;… Every time, I have to remember the exact incantation, and type it on the right host.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Who is the leader?" is a three-endpoint question.&lt;/strong&gt; &lt;code&gt;etcdctl endpoint status&lt;/code&gt; against every member, then reading a wide table to find the one that says &lt;code&gt;true&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Alarms are silent.&lt;/strong&gt; When etcd runs out of space it raises a &lt;code&gt;NOSPACE&lt;/code&gt; alarm and stops accepting writes. Nobody tells you unless you ask with &lt;code&gt;alarm list&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A member from another cluster looks perfectly healthy.&lt;/strong&gt; If you add the wrong address, it responds, it has a leader, and everything looks fine — it's just not &lt;em&gt;your&lt;/em&gt; cluster.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lag is hidden in Raft indexes.&lt;/strong&gt; A slow member falls behind on applied entries, and you only notice when requests start failing.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How Ivory solves them
&lt;/h2&gt;

&lt;h3&gt;
  
  
  One overview for the whole cluster
&lt;/h3&gt;

&lt;p&gt;Add your etcd cluster to Ivory by typing the node addresses, or just give it &lt;strong&gt;one&lt;/strong&gt; node and let Ivory &lt;strong&gt;detect&lt;/strong&gt; the rest — etcd's member list is the same from whichever node you ask.&lt;/p&gt;

&lt;p&gt;The overview shows every member at once:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Role&lt;/strong&gt; — the member etcd names as leader is the leader, the rest are replicas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State&lt;/strong&gt; — whether the member is actually running, observed, not assumed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lag&lt;/strong&gt; — how many Raft entries a member is behind the leader. Ivory warns past &lt;strong&gt;1000 entries&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tags&lt;/strong&gt; — the etcd version, the Raft term, and whether a member is a learner.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each member keeps its etcd name, so what you see in Ivory is exactly what etcd calls it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Warnings that actually tell you something
&lt;/h3&gt;

&lt;p&gt;Ivory shows two kinds of warnings, labelled separately so you always know who's talking:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What etcd itself reports&lt;/strong&gt; — alarms like &lt;code&gt;NOSPACE&lt;/code&gt;, a lost leader, and a backlog of committed but not yet applied entries big enough for etcd to start refusing requests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What Ivory notices&lt;/strong&gt; — a member it can't reach (naming the address it tried, so a routing problem reads differently from a dead member), a node that isn't in the cluster's member list, or a lag past the threshold.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And because every node reports its &lt;strong&gt;etcd cluster id&lt;/strong&gt;, a member from a different cluster is flagged right away instead of rendering as a happy, healthy node.&lt;/p&gt;

&lt;h3&gt;
  
  
  Move the leader
&lt;/h3&gt;

&lt;p&gt;etcd elects its leader by itself, so there's no failover or restart to manage. But sometimes you want the leader somewhere else — before maintenance on its host, for example. Ivory offers a &lt;strong&gt;switchover&lt;/strong&gt;: pick the member that should lead, and it moves leadership there.&lt;/p&gt;

&lt;h3&gt;
  
  
  A console without the flags
&lt;/h3&gt;

&lt;p&gt;Every node has an &lt;code&gt;etcdctl&lt;/code&gt;-style console: &lt;code&gt;get&lt;/code&gt; (with &lt;code&gt;--prefix&lt;/code&gt;, &lt;code&gt;--limit&lt;/code&gt;, &lt;code&gt;--keys-only&lt;/code&gt;), &lt;code&gt;put&lt;/code&gt;, &lt;code&gt;del&lt;/code&gt;, &lt;code&gt;member list&lt;/code&gt;, &lt;code&gt;endpoint status&lt;/code&gt;, &lt;code&gt;endpoint health&lt;/code&gt; and &lt;code&gt;alarm list&lt;/code&gt;. No endpoints, no certificates to type — Ivory already knows them.&lt;/p&gt;

&lt;p&gt;There are also &lt;strong&gt;saved queries&lt;/strong&gt; for the things you check most: the member list, endpoint status and health, alarms — and the keys &lt;strong&gt;Patroni&lt;/strong&gt; stores for its clusters. That last one is a lifesaver when you need to know which Postgres node Patroni &lt;em&gt;thinks&lt;/em&gt; is the leader.&lt;/p&gt;

&lt;h3&gt;
  
  
  The machine behind each node
&lt;/h3&gt;

&lt;p&gt;Give Ivory an SSH key, and each node also shows the machine it runs on: CPU, memory, network, the process list and any log file on the host. If etcd runs in Docker, the Container tab shows its logs, lets you inspect, start, stop or restart it. Most etcd problems are disk or network problems, and this is where you see them — no extra SSH session needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Need a new etcd cluster?
&lt;/h2&gt;

&lt;p&gt;Ivory can deploy one for you over plain SSH, from a template:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Etcd (Multi Host)&lt;/strong&gt; — three nodes &lt;code&gt;etcd1&lt;/code&gt;–&lt;code&gt;etcd3&lt;/code&gt;, one per machine, client port &lt;code&gt;2379&lt;/code&gt; and peer port &lt;code&gt;2380&lt;/code&gt;. Replace the example addresses in the member list with your hosts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Etcd (Single Host)&lt;/strong&gt; — all three on one machine on client ports &lt;code&gt;2479&lt;/code&gt;, &lt;code&gt;2481&lt;/code&gt; and &lt;code&gt;2483&lt;/code&gt;. Perfect for a test environment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both leave authentication off on purpose: that's what lets Ivory's &lt;strong&gt;Patroni&lt;/strong&gt; templates use the cluster as their coordination store right away. Deploy etcd first, then Patroni on top of it, and you have a full high-availability Postgres setup in a few clicks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ask your AI agent
&lt;/h2&gt;

&lt;p&gt;Ivory has a built-in MCP server, so you can also connect Claude, Cursor or Codex and simply ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Is my etcd cluster healthy? Any alarms?"&lt;/p&gt;

&lt;p&gt;"Which etcd member is the leader, and is any member behind?"&lt;/p&gt;

&lt;p&gt;"What does Patroni store in etcd for the prod cluster?"&lt;/p&gt;

&lt;p&gt;"Move the etcd leader to etcd2 — check that it's caught up first."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The agent works through Ivory, with exactly the permissions your user has. Details are in the &lt;a href="https://ivory.veegres.com/docs/mcp" rel="noopener noreferrer"&gt;MCP docs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 80:80 &lt;span class="nt"&gt;--restart&lt;/span&gt; always veegres/ivory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;code&gt;http://localhost&lt;/code&gt;, go through the setup wizard, and add your etcd cluster. etcd support is currently in &lt;strong&gt;beta&lt;/strong&gt; — it works end to end, but it has had less time in the field than Postgres, so feedback and issues are very welcome.&lt;/p&gt;

&lt;p&gt;Keep your Raft afloat, and it will keep everything above it standing. 😉&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Useful links:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ivory.veegres.com/docs/databases/etcd" rel="noopener noreferrer"&gt;Ivory etcd docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ivory.veegres.com" rel="noopener noreferrer"&gt;Website&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/veegres/ivory" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://anselvo.medium.com/troubleshoot-postgres-clusters-easily-with-ivory-eb0a6d61695a" rel="noopener noreferrer"&gt;Troubleshoot Postgres clusters easily with Ivory&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>etcd</category>
      <category>distributedsystems</category>
      <category>devops</category>
      <category>database</category>
    </item>
    <item>
      <title>Stop SSH-ing at 3 A.M. — Just Ask Your Database Cluster What's Wrong</title>
      <dc:creator>Andrei Sergeev</dc:creator>
      <pubDate>Mon, 26 Oct 2026 10:02:00 +0000</pubDate>
      <link>https://dev.to/anselvo/stop-ssh-ing-at-3-am-just-ask-your-database-cluster-whats-wrong-l4l</link>
      <guid>https://dev.to/anselvo/stop-ssh-ing-at-3-am-just-ask-your-database-cluster-whats-wrong-l4l</guid>
      <description>&lt;h2&gt;
  
  
  How to connect Claude, Cursor or Codex to Ivory and let an AI agent troubleshoot PostgreSQL, Redis, MongoDB and more — safely, under your own permissions
&lt;/h2&gt;

&lt;p&gt;It's 3 a.m. Your phone buzzes: &lt;em&gt;replication lag on prod&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;You know the drill. Open the laptop. SSH into the first node. &lt;code&gt;patronictl list&lt;/code&gt;. Open &lt;code&gt;psql&lt;/code&gt; on the leader. Query &lt;code&gt;pg_stat_replication&lt;/code&gt;. SSH into the replica. &lt;code&gt;top&lt;/code&gt;. &lt;code&gt;df -h&lt;/code&gt;. &lt;code&gt;tail&lt;/code&gt; the log. Back to the leader. Is something holding a lock? Another query. Copy a PID. Five terminals later, you finally have a picture of what's going on — and you're wide awake for the rest of the night.&lt;/p&gt;

&lt;p&gt;Now imagine you type one sentence instead:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Why is the replica in prod lagging?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;…and an AI agent checks the cluster, reads the lag, looks at the replica's machine, runs the right diagnostic query on the leader and tells you: &lt;em&gt;a long-running transaction on the leader is holding back replay; here's its PID — do you want me to cancel it?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That's what Ivory does now. Let me show you how.&lt;/p&gt;

&lt;h2&gt;
  
  
  The idea: don't give your AI the keys — give it Ivory
&lt;/h2&gt;

&lt;p&gt;You &lt;em&gt;could&lt;/em&gt; give an AI agent SSH access and a database password. Please don't. 🙂&lt;/p&gt;

&lt;p&gt;It would have every secret in its context, no idea which cluster is which, and no limits at all — &lt;code&gt;DROP TABLE&lt;/code&gt; is just as easy to type as &lt;code&gt;SELECT&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ivory.veegres.com" rel="noopener noreferrer"&gt;Ivory&lt;/a&gt; is an open-source tool to deploy, watch and fix database clusters — PostgreSQL with Patroni, plain PostgreSQL, etcd, Redis, ClickHouse, MongoDB and ZooKeeper. Since v2.1.0 it has a built-in &lt;strong&gt;MCP server&lt;/strong&gt; (Model Context Protocol, the standard way AI agents call tools). So instead of raw access to your infrastructure, the agent gets Ivory:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It already knows your clusters.&lt;/strong&gt; Names, nodes, roles, which engine, which keeper — no need to explain your topology.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It sees only what you allow.&lt;/strong&gt; An agent sees &lt;em&gt;only the tools its user has permission for&lt;/em&gt;. No permission for a switchover? The switchover tool doesn't even exist for it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secrets never pass through it.&lt;/strong&gt; Passwords and SSH keys stay in Ivory's vault. The agent refers to them by id and never sees them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dangerous tools are labelled.&lt;/strong&gt; Read-only tools are marked read-only, destructive ones are marked destructive, so your client asks you before running them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvz8dg9ch07sdng1mjrcu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvz8dg9ch07sdng1mjrcu.png" alt="An AI agent answering questions about database clusters through Ivory" width="799" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"Show me all active queries" — the agent checks six Postgres nodes, finds a long pg_sleep on one replica and offers to cancel or terminate it&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Set it up in two minutes
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Run Ivory&lt;/strong&gt; (skip this if you already have it):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 80:80 &lt;span class="nt"&gt;--restart&lt;/span&gt; always veegres/ivory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Generate a token.&lt;/strong&gt; In Ivory, open &lt;strong&gt;Settings → Integrations → MCP Server&lt;/strong&gt;. Pick how long the token should live — 1 hour, 6 hours, 1 day, 15 days or 30 days — and press generate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Copy the config for your client.&lt;/strong&gt; The same screen has a ready-made config for Claude Code, Cursor, VS Code, Codex, Antigravity, IntelliJ IDEA and Claude Desktop, with the endpoint and token already filled in. For Claude Code it's one command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude mcp add &lt;span class="nt"&gt;--transport&lt;/span&gt; http ivory http://localhost/api/mcp &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$TOKEN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. Ask your agent &lt;em&gt;"What clusters do I have in Ivory?"&lt;/em&gt; to make sure it works.&lt;/p&gt;

&lt;h2&gt;
  
  
  10 things to ask your cluster
&lt;/h2&gt;

&lt;p&gt;Here's where it gets fun. These are real prompts that work today, and what the agent does behind the scenes.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The morning check
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;"Check all my clusters and tell me if anything needs attention."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The agent lists every cluster and reads each one's overview: roles, states, lag, pending restarts and warnings. You get one short summary instead of clicking through every cluster. My favourite way to start the day.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Why is my replica lagging?
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;"Why is replica 2 in prod lagging?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It reads the lag (in the engine's own unit — bytes for Postgres, seconds for Redis and MongoDB, Raft entries for etcd), checks the replica machine's CPU, memory and network, and runs the replication queries on the leader.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. What is blocking my queries?
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;"What is blocking queries on the prod leader? Don't kill anything, just explain."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It looks at the active queries and locks and points to the blocker. When you're ready: &lt;em&gt;"Cancel it"&lt;/em&gt; — and it uses &lt;code&gt;ivory_query_cancel&lt;/code&gt;, or &lt;code&gt;ivory_query_terminate&lt;/code&gt; if cancel isn't enough.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Is it down, or can I just not reach it?
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;"Node patroni3 is red. Is it actually down?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;ivory_cluster_check&lt;/code&gt; tests every node at once — keeper, machine and database connections — and tells you whether it breaks at the vault, the certificate or the network itself. That's the difference between "the database crashed" and "someone rotated the password".&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Read the logs for me
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;"Show me the last errors in the logs of the etcd leader container."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It pulls the last lines of the container log — or any log file on the machine — and summarizes what matters. No &lt;code&gt;ssh&lt;/code&gt;, no &lt;code&gt;docker logs&lt;/code&gt;, no scrolling.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Is the machine OK?
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;"Is anything else eating CPU on the mongo2 host?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The agent reads the machine's metrics and process list over SSH, through Ivory. Great for the classic "it's not the database, it's the backup job running on the same box".&lt;/p&gt;

&lt;h3&gt;
  
  
  7. A planned switchover, done carefully
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;"I want to switch the leader to node 3. Check that it's healthy and caught up first, then ask me before doing it."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It checks lag and state, explains what will happen, and waits for your go. Ivory even supports scheduling a switchover for later on Patroni: &lt;em&gt;"…and schedule it for 2 a.m."&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Explain a warning
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;"Ivory shows a warning on clickhouse2. What does it mean and how do I fix it?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ivory has two kinds of warnings: its own (a node that isn't in the cluster, lag past the threshold, an unreachable node) and the ones the engine reports itself (etcd alarms, failed MongoDB heartbeats, stuck ClickHouse replication tasks). The agent knows which is which and explains both.&lt;/p&gt;

&lt;h3&gt;
  
  
  9. Run the right diagnostic query
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;"Run the table bloat query on the analytics database and tell me the top 5 tables."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ivory ships saved diagnostic queries for every engine. The agent can find the right one and run it, so you don't have to remember which &lt;code&gt;pg_stat_*&lt;/code&gt; view to join with which.&lt;/p&gt;

&lt;h3&gt;
  
  
  10. Spin up a test cluster
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;"Deploy a test Redis cluster on 10.0.0.4 from the single-host template. Use the 'test-ssh' vault for SSH and the 'redis-test' vault for the password."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The agent picks the template and deploys all three nodes — then reports how each node's deploy and initialize steps ended. Credentials are always named by vault, never typed into the chat, so no password ever lands in the agent's context.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep it safe: the 3-rule setup
&lt;/h2&gt;

&lt;p&gt;Giving an AI agent power over production deserves a moment of thought. Here's how I set it up:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rule 1: Give your agent its own user.&lt;/strong&gt; Create a user in Ivory just for your agent and grant it only &lt;code&gt;view.*&lt;/code&gt; permissions. It can diagnose everything and change nothing — the tools that change something simply won't appear in its list. When you need it to act, use a different user with the &lt;code&gt;manage.*&lt;/code&gt; permissions you're comfortable with.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rule 2: Use short-lived tokens.&lt;/strong&gt; Tokens can't be revoked: Ivory doesn't store them, so a token stays valid until it expires. A 1-hour token for an incident, a 1-day token for a working session. Treat a 30-day token like a password you can't change for a month.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rule 3: Keep the approval prompts on.&lt;/strong&gt; Most MCP clients ask before running a tool, and Ivory marks the dangerous ones as destructive. Read before you click "allow" — especially for failover, reinitialize, removing a container and the raw query console.&lt;/p&gt;

&lt;p&gt;Some things an agent can never do through Ivory, whatever its permissions: erase data, export backups, or manage vaults, certificates, users and permissions. An agent should never be able to widen its own access.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tips for better answers
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name the cluster.&lt;/strong&gt; "Prod" is better than "my database".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ask it to explain before it acts.&lt;/strong&gt; "Diagnose, don't fix" is a great default.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ask for the evidence.&lt;/strong&gt; "Show me the query you ran and the numbers" keeps the answer honest.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Chain it.&lt;/strong&gt; "Check all clusters, then dig into the worst one" works surprisingly well.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Bonus: let AI add your favourite database
&lt;/h2&gt;

&lt;p&gt;Ivory's engines are plugins. If your database isn't supported yet, the repository ships a Claude Code agent called &lt;code&gt;keeper-database-plugin&lt;/code&gt; that writes a new plugin — both halves, the tests and the UI wiring — following the project's own checklist. Then open a pull request. 🧩&lt;/p&gt;

&lt;h2&gt;
  
  
  The point
&lt;/h2&gt;

&lt;p&gt;AI won't replace knowing your databases. But it removes the boring part — the five terminals, the copy-pasted PIDs, the "which host was the leader again?" — and leaves you with the decision. And because it works through Ivory, it does that with exactly the permissions you gave it and nothing more.&lt;/p&gt;

&lt;p&gt;Next time your phone buzzes at 3 a.m., try asking first. 😉&lt;/p&gt;

&lt;p&gt;If you like the idea, give Ivory a ⭐ on GitHub — it really helps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Useful links:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ivory.veegres.com/docs/mcp" rel="noopener noreferrer"&gt;MCP server docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ivory.veegres.com/docs/getting-started" rel="noopener noreferrer"&gt;Getting started&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ivory.veegres.com" rel="noopener noreferrer"&gt;Website&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/veegres/ivory" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/veegres/ivory/releases/tag/v2.1.0" rel="noopener noreferrer"&gt;Release v2.1.0&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>database</category>
      <category>devops</category>
      <category>mcp</category>
    </item>
    <item>
      <title>Troubleshoot Postgres Clusters With Ease Using Ivory</title>
      <dc:creator>Andrei Sergeev</dc:creator>
      <pubDate>Mon, 19 Oct 2026 08:09:00 +0000</pubDate>
      <link>https://dev.to/anselvo/troubleshoot-postgres-clusters-with-ease-using-ivory-18hf</link>
      <guid>https://dev.to/anselvo/troubleshoot-postgres-clusters-with-ease-using-ivory-18hf</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;This is a rewrite of my earlier article, &lt;a href="https://anselvo.medium.com/troubleshoot-postgres-clusters-easily-with-ivory-eb0a6d61695a" rel="noopener noreferrer"&gt;Troubleshoot Postgres clusters easily with Ivory&lt;/a&gt;, first published on Medium.&lt;/strong&gt; Ivory has changed a lot since then, so I've brought the whole story up to date with what it can do today.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When your elephant suddenly takes a nap, you rush to its side to make sure it's doing okay. 🐘&lt;/p&gt;

&lt;p&gt;That's how my original article started, when I first introduced &lt;strong&gt;Ivory&lt;/strong&gt; — a tool to get to your elephant's side as fast as possible. Back then it was a small helper for Postgres clusters running Patroni: an overview, a few Patroni buttons, some saved queries and pgcompacttable. Some things in that article are simply not true anymore — Ivory supports Postgres TLS now, it watches plain Postgres replication too, and it now reads the machine behind each node too, so the extra SSH session is gone. So here's the same story, retold the way Ivory looks today.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Ivory exists
&lt;/h2&gt;

&lt;p&gt;I'm a developer who supports Postgres clusters with Patroni as the failover system, and managing many of them in different places was exhausting. So I built the tool I wanted to use in my daily work.&lt;/p&gt;

&lt;p&gt;These are the problems it set out to solve, and they haven't gone anywhere:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Patroni's CLI and API are hard to remember.&lt;/strong&gt; &lt;code&gt;patronictl&lt;/code&gt; on the right host, the right config file, the right flags — every time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Troubleshooting Postgres means running specific queries.&lt;/strong&gt; Which &lt;code&gt;pg_stat_*&lt;/code&gt; view was it again, and what do I join it with?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Many clusters means many terminals.&lt;/strong&gt; Copy-pasting the same commands between hosts and clusters is slow and error-prone.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And a few more I've collected over the years:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;"Is it Postgres, or the machine?"&lt;/strong&gt; Half the incidents are a full disk, a busy CPU or a noisy neighbour — and checking that means yet another SSH session.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not every cluster runs Patroni.&lt;/strong&gt; Sometimes it's a plain primary with a couple of standbys, and you still want to see it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Setting up a test cluster takes too long.&lt;/strong&gt; Three nodes, etcd, Patroni config, replication… just to try something.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  So, how does Ivory solve them?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyug6fpyxu78qkztaz1l1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyug6fpyxu78qkztaz1l1.png" alt="Ivory: the cluster list, the overview of every node and the machine behind it" width="800" height="817"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  First: one overview of every cluster
&lt;/h3&gt;

&lt;p&gt;Ivory shows all your clusters in one list, each node coloured by its role — green for the leader, blue for replicas — with warning icons when something's off. Tag your clusters (&lt;code&gt;prod&lt;/code&gt;, &lt;code&gt;staging&lt;/code&gt;, &lt;code&gt;team-a&lt;/code&gt;…) and filter by them.&lt;/p&gt;

&lt;p&gt;Adding a cluster takes seconds. Type its nodes, or give Ivory &lt;strong&gt;just one node&lt;/strong&gt; and let it &lt;strong&gt;detect&lt;/strong&gt; the rest: one call to Patroni's &lt;code&gt;/cluster&lt;/code&gt; returns every member, with the names Patroni gives them.&lt;/p&gt;

&lt;p&gt;Open a cluster and you get the overview of every node:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Role&lt;/strong&gt; — leader or replica, with synchronous replicas marked&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State&lt;/strong&gt; — running, streaming, stopped, failed…&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lag&lt;/strong&gt; — bytes behind the leader, with a warning past &lt;strong&gt;50 MiB&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pending restart&lt;/strong&gt;, &lt;strong&gt;scheduled&lt;/strong&gt; restart or switchover, the timeline, whether the cluster is paused&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tags&lt;/strong&gt; — everything you set on the member in Patroni's own config&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And &lt;strong&gt;warnings&lt;/strong&gt; that actually catch mistakes. A node that's in your config but not in Patroni's answer is flagged. So is a member Patroni reports that you never configured. And because each node reports its Patroni &lt;code&gt;scope&lt;/code&gt;, a node that belongs to a &lt;em&gt;different&lt;/em&gt; cluster is flagged too — instead of looking like a perfectly healthy member of yours.&lt;/p&gt;

&lt;h3&gt;
  
  
  Secondly: HA operations in one click
&lt;/h3&gt;

&lt;p&gt;Every Patroni operation is a button:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;When to use&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Switchover&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Planned leader change — to a replica you pick, or one Patroni picks. Can be &lt;strong&gt;scheduled&lt;/strong&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Failover&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Forced promotion when the leader is gone.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Restart&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Restart Postgres on a node. Can be &lt;strong&gt;scheduled&lt;/strong&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Reinitialise&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Wipe a replica and re-clone it from the leader.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Reload&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Apply config changes that don't need a restart.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Pause / Resume&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Switch Patroni's automatic failover off for maintenance, and back on.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Patroni's &lt;strong&gt;dynamic configuration&lt;/strong&gt; is editable right there too, as a partial patch: change only what you need, and the Pending Restart flag shows you which nodes need a restart to apply it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No Patroni?&lt;/strong&gt; Ivory also supports &lt;strong&gt;plain Postgres streaming replication&lt;/strong&gt; — a primary and its standbys, no HA tool in between. It reads roles with &lt;code&gt;pg_is_in_recovery()&lt;/code&gt;, replication from &lt;code&gt;pg_stat_replication&lt;/code&gt; and &lt;code&gt;pg_stat_wal_receiver&lt;/code&gt;, and warns about a standby that isn't streaming or a replication slot that's about to lose its WAL. You can promote a standby (&lt;code&gt;pg_promote()&lt;/code&gt;), reload and view the config. Switchover, restart and pause need an HA tool, so for those there's Patroni.&lt;/p&gt;

&lt;h3&gt;
  
  
  Third: the right query, without remembering it
&lt;/h3&gt;

&lt;p&gt;Every node has a &lt;strong&gt;query builder&lt;/strong&gt; with saved troubleshooting queries, organised by category: &lt;strong&gt;Activity&lt;/strong&gt; (long-running queries, locks, idle connections), &lt;strong&gt;Replication&lt;/strong&gt; (lag, slots, WAL senders and receivers), &lt;strong&gt;Bloat&lt;/strong&gt;, &lt;strong&gt;Statistics&lt;/strong&gt; (autovacuum, cache hit ratio…) and more. Switch between nodes and clusters, and send the same query with one click.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi75lchku7fepd3imtmpd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi75lchku7fepd3imtmpd.png" alt="Ivory's query builder with saved diagnostic queries" width="800" height="631"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Some nice details:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Labels&lt;/strong&gt; tell you where a query belongs: &lt;em&gt;Database Sensitive&lt;/em&gt;, &lt;em&gt;Master Only&lt;/em&gt;, or &lt;em&gt;Replica Recommended&lt;/em&gt; for the heavy ones you shouldn't run on the leader.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prepared statements&lt;/strong&gt; — put &lt;code&gt;$1&lt;/code&gt;, &lt;code&gt;$2&lt;/code&gt; in your SQL, name them, and fill in values at run time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your own queries&lt;/strong&gt; — create custom ones, or edit a system query to fit your setup.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A free console&lt;/strong&gt; for anything ad hoc, plus a &lt;strong&gt;history&lt;/strong&gt; of your recent queries.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Running queries&lt;/strong&gt; with &lt;strong&gt;cancel&lt;/strong&gt; and &lt;strong&gt;terminate&lt;/strong&gt; buttons — for that one &lt;code&gt;SELECT&lt;/code&gt; that's been running since lunch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A dashboard&lt;/strong&gt; with databases, connections, sizes and uptime.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Fourth: pgcompacttable, built in
&lt;/h3&gt;

&lt;p&gt;Ivory still ships &lt;a href="https://github.com/dataegret/pgcompacttable" rel="noopener noreferrer"&gt;pgcompacttable&lt;/a&gt; to clean up bloated tables. It compacts tables and rebuilds indexes in small batches with only &lt;code&gt;ROW EXCLUSIVE&lt;/code&gt; locks — unlike &lt;code&gt;VACUUM FULL&lt;/code&gt;, it's safe on a busy production database.&lt;/p&gt;

&lt;p&gt;Ivory runs it as a background job on the leader: pick the database, filter the tables, set a delay between batches, and watch its output live. The bloat estimation queries sit right next to it, so you can measure before and after.&lt;/p&gt;

&lt;h2&gt;
  
  
  Moreover, Ivory simplifies…
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The machine behind each node.&lt;/strong&gt; Give Ivory an SSH key and every node shows its VM: CPU, memory, network, processes, and any log file streamed live. No agent on your hosts — just SSH.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Containers.&lt;/strong&gt; If Postgres runs in Docker, see its logs, inspect it, start, stop or restart it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deploying a new cluster.&lt;/strong&gt; Pick a template, fill in the hosts, press Deploy. The shipped templates run Zalando's Spilo (PostgreSQL 18 with Patroni) on three machines — or all three nodes on one machine for a test environment. Need etcd for Patroni? There's a template for that too. Plain Postgres replication templates are included as well.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Password and key management.&lt;/strong&gt; Passwords and SSH keys live in Ivory's vault, encrypted, and are reused across clusters.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Certificates and TLS.&lt;/strong&gt; Add certificates once and use them for both Patroni's API and the Postgres connection, including mutual TLS.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Teams.&lt;/strong&gt; Sign in with Basic, LDAP or OIDC, and give every user exactly the permissions they need — one permission per action.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your phone.&lt;/strong&gt; The UI works on mobile, so the 3 a.m. check doesn't need a laptop.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backups of Ivory itself.&lt;/strong&gt; Export your clusters, queries and permissions and import them on another instance.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  And now, your AI agent can help too 🤖
&lt;/h2&gt;

&lt;p&gt;Ivory has a built-in &lt;strong&gt;MCP server&lt;/strong&gt;. Connect Claude, Cursor, Codex or any MCP client, and ask in plain words:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Why is replica 2 in prod lagging?"&lt;/p&gt;

&lt;p&gt;"What is blocking queries on the leader? Don't kill anything, just explain."&lt;/p&gt;

&lt;p&gt;"Switch the leader to patroni3 — check it's caught up first, and ask me before doing it."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The agent works through Ivory, so it sees only the tools your user has permission for, and your passwords never pass through its context. A view-only user gets an agent that can diagnose everything and change nothing. Setup takes two minutes: &lt;strong&gt;Settings → Integrations → MCP Server&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvz8dg9ch07sdng1mjrcu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvz8dg9ch07sdng1mjrcu.png" alt="An AI agent finding a long-running query across six Postgres nodes through Ivory" width="799" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;Ivory is one Docker container with no dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 80:80 &lt;span class="nt"&gt;--restart&lt;/span&gt; always veegres/ivory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;code&gt;http://localhost&lt;/code&gt;, go through the setup wizard, and add your first cluster. Use it as a personal tool on your laptop, or run it on a VM as a shared service for your whole team.&lt;/p&gt;

&lt;p&gt;Ivory has also grown beyond Postgres — it now looks after &lt;strong&gt;etcd, Redis, ClickHouse, MongoDB and ZooKeeper&lt;/strong&gt; the same way. But Postgres is where it started, and it's still where it's strongest.&lt;/p&gt;

&lt;p&gt;If Ivory saves you some time, give it a ⭐ on &lt;a href="https://github.com/veegres/ivory" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; — it helps other people find it and keeps me building it. Feedback, issues and ideas are always welcome.&lt;/p&gt;

&lt;p&gt;Treat your elephants with kindness and respect, and they will show you the way 😉 — that was the last line of the original article, and it still is.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Useful links:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://anselvo.medium.com/troubleshoot-postgres-clusters-easily-with-ivory-eb0a6d61695a" rel="noopener noreferrer"&gt;The original article on Medium&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ivory.veegres.com" rel="noopener noreferrer"&gt;Website &amp;amp; docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ivory.veegres.com/docs/getting-started" rel="noopener noreferrer"&gt;Getting started&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ivory.veegres.com/docs/databases/patroni" rel="noopener noreferrer"&gt;PostgreSQL + Patroni docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ivory.veegres.com/docs/mcp" rel="noopener noreferrer"&gt;MCP server docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/veegres/ivory" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/veegres/ivory/releases" rel="noopener noreferrer"&gt;Releases&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>postgres</category>
      <category>database</category>
      <category>devops</category>
      <category>patroni</category>
    </item>
    <item>
      <title>Ivory Has a New Home — and the Elephant Grew Wings</title>
      <dc:creator>Andrei Sergeev</dc:creator>
      <pubDate>Fri, 16 Oct 2026 06:55:21 +0000</pubDate>
      <link>https://dev.to/anselvo/ivory-has-a-new-home-and-the-elephant-grew-wings-3kgh</link>
      <guid>https://dev.to/anselvo/ivory-has-a-new-home-and-the-elephant-grew-wings-3kgh</guid>
      <description>&lt;h2&gt;
  
  
  Meet ivory.veegres.com: the website, the docs and a new logo for the open-source tool that deploys, watches and fixes your database clusters
&lt;/h2&gt;

&lt;p&gt;For a long time, Ivory lived in exactly one place: a GitHub repository. If you wanted to learn about it, you opened the README, clicked through a folder of Markdown files and hoped you'd find the right one.&lt;/p&gt;

&lt;p&gt;That worked while Ivory was a small Postgres and Patroni helper. It doesn't work anymore. Ivory now manages seven kinds of clusters, deploys them, watches the machines behind them and has an MCP server for AI agents. That deserves a proper home.&lt;/p&gt;

&lt;p&gt;So here it is: &lt;strong&gt;&lt;a href="https://ivory.veegres.com" rel="noopener noreferrer"&gt;ivory.veegres.com&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv3jpe0o0beofb0gsg9hb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv3jpe0o0beofb0gsg9hb.png" alt="Ivory — Deploy. Watch. Fix. Anywhere." width="800" height="817"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ivory's UI: every cluster, the health of every node and the machine behind each one, in one screen&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploy. Watch. Fix. Anywhere.
&lt;/h2&gt;

&lt;p&gt;That's the tagline on top of the page, and it's the shortest description of Ivory I've ever managed to write:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Deploy&lt;/strong&gt; a cluster from a template over plain SSH.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Watch&lt;/strong&gt; its health: roles, replication lag, pending restarts and warnings for every node.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fix&lt;/strong&gt; it: switchover, failover, restart, reinitialize, run a diagnostic query, read a log.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anywhere&lt;/strong&gt;: from your browser, from your phone, or from your AI agent.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What you'll find on the site
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Why Ivory, in three sentences
&lt;/h3&gt;

&lt;p&gt;The landing page starts with the three reasons Ivory exists:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Nothing to install.&lt;/strong&gt; Ivory reaches your machines over plain SSH and talks to each database in its own protocol. No agent beside every node, no Kubernetes, no Ansible, no cloud account — one Docker container and you're done.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One workflow, every engine.&lt;/strong&gt; PostgreSQL, etcd, Redis, ClickHouse, MongoDB and ZooKeeper look and behave the same: the same health view, the same switchover button, the same console. Learn it once, use it everywhere.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fix it from anywhere.&lt;/strong&gt; A UI that works on your phone for the 3 a.m. page, and a built-in MCP server so your AI agent can dig into a cluster with you — under exactly the permissions you have.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Every supported database, at a glance
&lt;/h3&gt;

&lt;p&gt;PostgreSQL with Patroni and plain PostgreSQL replication are &lt;strong&gt;stable&lt;/strong&gt;. etcd, Redis, ClickHouse, MongoDB and ZooKeeper are in &lt;strong&gt;beta&lt;/strong&gt;. And there's one more card: &lt;em&gt;"Yours next?"&lt;/em&gt; Every engine in Ivory is a self-contained plugin, and the repository even ships an AI agent that writes a new one for your database by the project's own checklist.&lt;/p&gt;

&lt;h3&gt;
  
  
  Real documentation, with search
&lt;/h3&gt;

&lt;p&gt;This is the part I'm happiest about. The docs are finally easy to read and easy to search:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Getting started&lt;/strong&gt; — from &lt;code&gt;docker run&lt;/code&gt; to your first cluster&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clusters, Overview and Node&lt;/strong&gt; — everything the UI does, screen by screen&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deployment&lt;/strong&gt; — templates, variables and the shipped templates for every engine&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A page for every database&lt;/strong&gt; — what Ivory reads, which operations it offers, how lag is measured and when it warns&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP server&lt;/strong&gt; — connecting an agent, permissions and every tool it can call&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comparison tables&lt;/strong&gt; — operations, lag thresholds and console features for every engine, side by side&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A small detail for fellow maintainers: the docs are still the same Markdown files in the repository's &lt;code&gt;.doc&lt;/code&gt; folder. The site copies them in at build time, so there's one source of truth, and the docs keep rendering on GitHub exactly as before. The site itself is built with Rspress and served as static files from Cloudflare.&lt;/p&gt;

&lt;h3&gt;
  
  
  "Just ask your cluster"
&lt;/h3&gt;

&lt;p&gt;The site has a whole section on Ivory being AI-ready, with the kind of questions you can now ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Why is replica 2 lagging?"&lt;/p&gt;

&lt;p&gt;"What is blocking my queries?"&lt;/p&gt;

&lt;p&gt;"Switch the leader to node 3."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I'll write a separate article on how to make the most of it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Up and running in a minute
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 80:80 &lt;span class="nt"&gt;--restart&lt;/span&gt; always veegres/ivory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the container, open the setup wizard at &lt;code&gt;http://localhost&lt;/code&gt;, choose how people sign in, and add a cluster: type its node addresses, let Ivory detect the rest from one node, or deploy a brand-new one.&lt;/p&gt;

&lt;h3&gt;
  
  
  Coming soon: a Playground
&lt;/h3&gt;

&lt;p&gt;There's a &lt;strong&gt;Playground&lt;/strong&gt; link in the menu. It's not live yet, but it will be: a real Ivory with a real high-availability cluster behind it, right in your browser — no install at all. Watch the repository on GitHub to know when it opens.&lt;/p&gt;

&lt;h2&gt;
  
  
  And about that butterfly… 🦋
&lt;/h2&gt;

&lt;p&gt;You may have noticed Ivory has a new logo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9nbkcdubm82aq7t5mxcx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9nbkcdubm82aq7t5mxcx.png" alt="The new Ivory logo" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Look closely 😉&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It's a butterfly. But look at it again: the wings are a pair of big ears, and the tail curls down like a trunk. The elephant is still there.&lt;/p&gt;

&lt;p&gt;Ivory started as a tool for Postgres — and Postgres is an elephant. In my very first article I wrote &lt;em&gt;"When your elephant suddenly takes a nap, you rush to his side."&lt;/em&gt; That's still true. But Ivory isn't only about one elephant anymore. It looks after etcd, Redis, ClickHouse, MongoDB and ZooKeeper too, and it can reach them from a browser, a phone or an AI agent.&lt;/p&gt;

&lt;p&gt;So the elephant didn't go anywhere. It just grew wings. 🐘➡️🦋&lt;/p&gt;

&lt;h2&gt;
  
  
  Get involved
&lt;/h2&gt;

&lt;p&gt;Ivory is free, open source under GPL-3.0, and built in my spare time. If you'd like to help:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⭐ &lt;strong&gt;Star it on GitHub&lt;/strong&gt; — one click that helps other people find it.&lt;/li&gt;
&lt;li&gt;🧩 &lt;strong&gt;Add your database&lt;/strong&gt; — every engine is a plugin, and there's an AI agent to help you write one.&lt;/li&gt;
&lt;li&gt;❤️ &lt;strong&gt;Support the project&lt;/strong&gt; — sponsorship funds new database plugins and features.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Treat your clusters with kindness, and they'll show you the way. 😉&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Useful links:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ivory.veegres.com" rel="noopener noreferrer"&gt;Website&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ivory.veegres.com/docs/getting-started" rel="noopener noreferrer"&gt;Getting started&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ivory.veegres.com/docs/databases" rel="noopener noreferrer"&gt;Supported databases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/veegres/ivory" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ivory.veegres.com/support" rel="noopener noreferrer"&gt;Support Ivory&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>opensource</category>
      <category>database</category>
      <category>devops</category>
      <category>selfhosted</category>
    </item>
  </channel>
</rss>
