<?xml version="1.0" encoding="UTF-8"?><rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title>Cockroach Labs Blog - engineering</title><link>https://www.cockroachlabs.com/blog/engineering/</link><atom:link href="http://rss.144-124-237-35.sslip.io/cockroachlabs/blog/engineering" rel="self" type="application/rss+xml"></atom:link><description>Cockroach Labs Blog - Powered by AtomRSS</description><generator>AtomRSS</generator><webMaster>contact@atomgroup.dev (AtomRSS)</webMaster><language>en</language><lastBuildDate>Sat, 08 Aug 2026 10:26:39 GMT</lastBuildDate><ttl>5</ttl><item><title>The Database at 550 Kilometers: What Orbital Computing Means for Distributed Databases</title><description>&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/6JohbnbfGNqTeehQ2NacIW/4cdbf62db6d72eaabfdc45d175620f11/CockroachDB_Orbital_Computing_and_Distributed_Databases_SOCIAL_webp.webp&quot;&gt;&lt;img alt=&quot;Satellites connected across Earth by illuminated data pathways, representing distributed database coordination, resilience, and data movement in orbital computing.&quot; loading=&quot;lazy&quot; width=&quot;1200&quot; height=&quot;675&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/6JohbnbfGNqTeehQ2NacIW/4cdbf62db6d72eaabfdc45d175620f11/CockroachDB_Orbital_Computing_and_Distributed_Databases_SOCIAL_webp.webp&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;I.-The-hum-of-modern-data-centers&quot;&gt;&lt;b&gt;I. The hum of modern data centers&amp;nbsp;&lt;/b&gt;&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;In Ashburn, Virginia, a row of servers draws 40 megawatts from the grid and exhales it as heat. Chilled water circulates through copper pipes at 2,800 liters per minute to carry that heat away. Outside, cooling towers the height of apartment buildings return it to the atmosphere. Ashburn now consumes more electricity than some nations. The machines inside process queries. They store application state.&lt;/p&gt;&lt;p&gt;This is a data center and there are thousands like it. They account for 4.4 percent of the electricity consumed in the United States, a figure that will double before the end of the decade. Concerns about their environmental impact and energy costs led &lt;a href=&quot;https://www.cnbc.com/2026/07/14/new-york-ai-data-center-ban.html&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;New York to pass a one-year ban&lt;/u&gt;&lt;/a&gt; on the construction of new hyperscaler data centers in July 2026. 14 other states have also introduced bills to restrict new data center construction.&lt;/p&gt;&lt;h2 id=&quot;II.-Why-are-companies-planning-data-centers-in-space?&quot;&gt;&lt;b&gt;II. Why are companies planning data centers in space?&amp;nbsp;&lt;/b&gt;&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;In January 2026, SpaceX filed an application with the Federal Communications Commission &lt;a href=&quot;https://spacenews.com/spacex-files-plans-for-million-satellite-orbital-data-center-constellation/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;for one million satellites&lt;/u&gt;&lt;/a&gt;. These are not communication satellites, but data centers. At the World Economic Forum in Davos, Elon Musk stated that the &lt;a href=&quot;https://fortune.com/2026/02/19/ai-data-centers-in-space-elon-musk-power-problems/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;lowest-cost location for AI computation would be in space&lt;/u&gt;&lt;/a&gt; within two to three years.&lt;/p&gt;&lt;p&gt;Separately, a company called &lt;a href=&quot;https://tech.yahoo.com/science/articles/data-center-space-race-heats-192503777.html&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;Starcloud filed for 88,000 satellites of its own&lt;/u&gt;&lt;/a&gt;. Starcloud had already placed a single Nvidia H100 GPU into low Earth orbit and run a Gemini inference workload on it. The chip functioned and the workload completed.&lt;/p&gt;&lt;p&gt;The combined investment required to deploy these constellations exceeds one trillion dollars. The economics rest on three substitutions:&amp;nbsp;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Solar power replaces grid electricity&lt;/b&gt;, and in orbit it is five to seven times more productive than on the surface. No atmosphere absorbs it. No clouds block it.&amp;nbsp;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Radiator panels replace cooling water&lt;/b&gt;. Heat leaves the satellite by emission into the cosmic microwave background at 2.7 Kelvin, the residual temperature of the universe itself. The reservoir is free. The panels are not. Vacuum is also an excellent insulator, and a 700-watt chip must shed every joule through radiation alone, into a sky that contains the Earth and, half the time, the Sun.&amp;nbsp;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Lastly, &lt;b&gt;open orbit replaces land and zoning&lt;/b&gt;. While several U.S. states are currently considering legislation to pause terrestrial data center construction, there are no neighbors in orbit to object. Well, none that we know of!&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Until now, most discussion of orbital infrastructure has focused on compute: how to power GPUs, cool them, and connect them across space. However, every stateful application also depends on a database. If space-based computing becomes practical, &lt;a href=&quot;https://www.cockroachlabs.com/blog/distributed-database-architecture/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;distributed databases&lt;/u&gt;&lt;/a&gt; will face an entirely new operating environment: one where latency, topology, failure domains, and even jurisdiction are constantly in motion. This article explores what those challenges might look like, and why some of the architectural principles developed for terrestrial distributed systems may prove unexpectedly relevant beyond Earth.&lt;/p&gt;&lt;h2 id=&quot;III.-What-happens-when-databases-move-to-space?&quot;&gt;&lt;b&gt;III. What happens when databases move to space?&lt;/b&gt;&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;Moving databases into space introduces a different set of engineering challenges than moving compute. While most of the orbital computing conversation is about GPUs, inference, training runs, and floating-point operations per second per dollar per kilowatt, every stateful application ultimately depends on a distributed database to persist state, coordinate work, and maintain consistency. These are important quantities, and the engineers working on them are solving genuinely difficult problems in thermal management, power delivery, and radiation hardening.&lt;/p&gt;&lt;p&gt;Compute is stateless, however. A GPU performs a matrix multiplication, returns a result, and retains nothing. It has no memory of the previous calculation and no obligation to the next one. Every application that persists data, coordinates work, or maintains a record of what has happened requires a database to store that information. A database must survive node failure, tolerate &lt;a href=&quot;https://www.cockroachlabs.com/blog/disaster-prevention-not-disaster-recovery/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;network partitions&lt;/u&gt;&lt;/a&gt;, and maintain &lt;a href=&quot;https://www.cockroachlabs.com/docs/v26.2/architecture/replication-layer&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;consistency across replicas&lt;/u&gt;&lt;/a&gt; that may disagree about the order of events.&lt;/p&gt;&lt;p&gt;One million satellites will run computations. Some of those computations will need to remember their results. Where does that memory live and how will it be managed?&lt;/p&gt;&lt;p&gt;That question shifts the conversation from orbital compute to orbital data infrastructure. Solving one without the other would leave many real-world applications incomplete.&amp;nbsp;&lt;/p&gt;&lt;h2 id=&quot;IV.-How-do-distributed-databases-already-solve-part-of-the-problem?&quot;&gt;&lt;b&gt;IV. How do distributed databases already solve part of the problem?&lt;/b&gt;&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://www.cockroachlabs.com/product/overview/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;CockroachDB&lt;/u&gt;&lt;/a&gt; was designed for a scenario that, at the time of its creation, was entirely terrestrial: a database distributed across multiple data centers, in &lt;a href=&quot;https://www.cockroachlabs.com/blog/cloud-journey-multi-region-distributed-sql/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;multiple geographic regions&lt;/u&gt;&lt;/a&gt; around the world, that &lt;a href=&quot;https://www.cockroachlabs.com/blog/surviving-application-database-failures/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;survives the loss of any node&lt;/u&gt;&lt;/a&gt;, any rack, or any entire data center without human intervention and without losing a single committed transaction.&lt;/p&gt;&lt;p&gt;One of the mechanisms that drives this behavior is a &lt;a href=&quot;https://www.cockroachlabs.com/glossary/distributed-db/raft-consensus-protocol/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;consensus protocol called Raft&lt;/u&gt;&lt;/a&gt;. Every write is proposed to a group of replicas. A majority must agree before the write is committed. If a replica fails to respond, whether because of a network partition, a hardware fault, or atmospheric reentry, the remaining replicas continue without it. No operator is paged. The system just handles it.&lt;/p&gt;&lt;p&gt;On the ground, this architecture protects against power outages, fiber cuts, and the occasional backhoe. The nodes sit in racks, the racks sit in buildings, and the buildings sit on foundations that don’tt move. In orbit, the foundations move at 7.66 kilometers per second and instead of backhoes or water leaks, there are meteor showers.&lt;/p&gt;&lt;h2 id=&quot;V.-How-would-a-distributed-database-work-across-a-satellite-constellation?&quot;&gt;&lt;b&gt;V. How would a distributed database work across a satellite constellation?&amp;nbsp;&lt;/b&gt;&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;Consider a cluster of 300 CockroachDB nodes distributed across a constellation in low Earth orbit at 550 kilometers altitude. Each node is contained in a satellite, and each satellite communicates with its neighbors via optical laser links. The constellation is arranged in orbital planes, each plane containing several dozen satellites that trace the same ground track, offset by time. (An orbital plane is a flat surface that passes through the center of the Earth: The orbital plane contains the satellite&#39;s orbit, every orbit traces an ellipse, and that ellipse is contained within that single flat surface. It’s like sliding a cardboard sheet through the center of an orange.)&lt;/p&gt;&lt;p&gt;A CockroachDB cluster on the ground uses a concept called &lt;a href=&quot;https://www.cockroachlabs.com/docs/v26.2/multiregion-overview&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;localities&lt;/u&gt;&lt;/a&gt; to describe its topology. A node might declare itself as &lt;code&gt;--locality=region=us-east,zone=us-east-1a&lt;/code&gt;. The database uses this information to place data near the users who access it and to ensure that replicas are spread across failure domains. If us-east goes down, an application can use the data copies in us-west and eu-central.&lt;/p&gt;&lt;p&gt;An orbital node might declare itself as&lt;code&gt; --locality=shell=leo-550,plane=47,position=12&lt;/code&gt;. The database would distribute replicas across planes, ensuring that no single orbital plane is a single point of failure. A micrometeorite strike that disables three satellites in Plane 47 does not affect replicas in Planes 23 and 68. A &quot;shell&quot; is a spherical surface at a given altitude, a soap bubble at a certain altitude above the Earth. Orbital planes intersect the Earth and the shells. The satellite travels across the shell where it intersects with the orbital plane.&lt;/p&gt;&lt;p&gt;This much is straightforward. CockroachDB already knows how to do this. The localities are strings. The replication logic is the same whether the string says &lt;code&gt;us-east&lt;/code&gt; or &lt;code&gt;plane-47&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;The problems begin when the strings start to move.&lt;/p&gt;&lt;hr&gt;&lt;h6&gt;&lt;b&gt;Related&lt;/b&gt;&lt;/h6&gt;&lt;p&gt;&lt;a href=&quot;https://www.cockroachlabs.com/guides/the-state-of-resilience-2025/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;i&gt;&lt;u&gt;State of Resilience 2025: Confronting Outages, Downtime, and Enterprise Readiness&lt;/u&gt;&lt;/i&gt;&lt;/a&gt;&lt;i&gt; — a 2025 report on operational resilience across 1,000 global enterprises and how distributed SQL combats costly downtime. &lt;/i&gt;&lt;/p&gt;&lt;hr&gt;&lt;h2 id=&quot;VI.-Should-data-live-in-orbit-or-on-Earth?&quot;&gt;&lt;b&gt;VI. Should data live in orbit or on Earth?&amp;nbsp;&lt;/b&gt;&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;Whether data should live in orbit or on Earth depends on a tradeoff between autonomy and economics. Understanding that tradeoff starts with an important difference between compute and storage.&amp;nbsp;&lt;/p&gt;&lt;p&gt;A GPU is an extraordinary value per kilogram. An Nvidia H100 weighs approximately 3 kilograms and, in a terrestrial data center, generates revenue measured in thousands of dollars per hour. At the current &lt;a href=&quot;https://orbitalradar.com/space-economy/launch-cost-trends&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;Falcon 9 launch cost of roughly $3,300 per kilogram&lt;/u&gt;&lt;/a&gt;, the launch expense is a rounding error against the card&#39;s lifetime earnings. The economics of space-based&amp;nbsp; compute work because compute is dense in value per unit mass. Storage is not.&lt;/p&gt;&lt;p&gt;An enterprise NVMe SSD stores four terabytes in about 200 grams. The launch cost for the drive itself is trivial: less than a dollar per terabyte to put it in orbit. But the drive requires a satellite. The satellite requires a chassis, solar panels, thermal radiators, a laser communication terminal, and a station-keeping propulsion system. The total mass per node is measured in hundreds of kilograms. At $3,300 per kilogram, each satellite costs several hundred thousand dollars to launch before it stores a single byte.&lt;/p&gt;&lt;p&gt;And storage, unlike compute, does not earn its keep through activity. A GPU performs work. It multiplies matrices, runs inference, returns results. Its value is measured per hour. A disk holds state. It persists a row that was written once and may be read four times over the next year, or four million times. Its value is measured per year of durability, not per cycle of computation.&lt;/p&gt;&lt;p&gt;This creates a question that the compute-focused orbital industry has not yet confronted: Is it cheaper to store data in orbit or to transmit it to the ground?&lt;/p&gt;&lt;p&gt;The answer has implications beyond infrastructure costs. It affects how autonomous an orbital platform can become, how resilient it remains during network disruptions, and which categories of applications, from scientific research to defense to AI inference, can operate without depending on continuous connectivity to Earth.&amp;nbsp;&lt;/p&gt;&lt;p&gt;The argument for orbital storage is autonomy. A database that keeps its state on the satellites can operate independently of ground stations. If the laser link to the surface is interrupted by weather, orbital mechanics, or geopolitics, the constellation continues serving queries from local replicas. The data is co-located with the compute, for low latency low and high availability.&lt;/p&gt;&lt;p&gt;The argument for ground storage is economics. Terrestrial storage costs approximately $20 per terabyte per year. Space-based storage, once satellite and launch costs are amortized, costs orders of magnitude more. A hybrid architecture that runs compute in orbit but persists durable state to ground stations would minimize the mass in orbit and the cost of the constellation.&lt;/p&gt;&lt;p&gt;However, a hybrid architecture reintroduces the very dependency that orbital computing was meant to eliminate. If the database is on the ground, every orbital query must wait for a round trip through the atmosphere. At 550 kilometers, that is 3.67 milliseconds each way. That may be acceptable for a single query. For a write that must be acknowledged before the next computation proceeds, it is a bottleneck that compounds with every dependent operation.&lt;/p&gt;&lt;p&gt;The likely answer is the same one that distributed databases have always given: It depends on the workload. Hot data that is frequently accessed and latency-sensitive, lives near the compute. Cold data that is archival, compliance-driven and infrequently read sinks to the cheapest storage available. On the ground, that means SSDs for hot data and object storage for cold. In orbit, it means satellite storage for hot data and ground stations for cold.&lt;/p&gt;&lt;h2 id=&quot;VII.-How-do-latency-and-consensus-change-in-orbit?&quot;&gt;&lt;b&gt;VII. How do latency and consensus change in orbit?&amp;nbsp;&lt;/b&gt;&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;A signal traveling from a satellite at 550 kilometers altitude to a ground station directly below requires 1.83 milliseconds. The round trip takes 3.67 milliseconds. This is fast enough for most database operations. A Raft consensus round among three replicas on the same orbital plane, separated by a few hundred kilometers of laser link, might complete in under 5 milliseconds.&lt;/p&gt;&lt;p&gt;But not all replicas will be on the same plane. The entire purpose of distributing replicas across failure domains is that they are physically separated. A satellite in Plane 12 communicating with a satellite in Plane 47 on the opposite side of the constellation may need to route through five or six intermediate satellites, each adding its processing and propagation delay. A consensus round across the constellation could take 30 to 80 milliseconds.&lt;/p&gt;&lt;p&gt;On the ground, this would be unremarkable. A CockroachDB cluster spanning US-East and EU-West routinely completes consensus in 70 to 90 milliseconds. The database is designed for it.&lt;/p&gt;&lt;p&gt;In orbit, the latency is not constant: Since the satellites are moving, the routing topology changes with every orbit. A consensus round that takes 30 milliseconds at time T may take 65 milliseconds at time T plus twelve minutes, when the orbital geometry has shifted and the optimal laser path now transits through a different set of relay nodes.&lt;/p&gt;&lt;p&gt;CockroachDB handles this. Its &lt;a href=&quot;https://www.cockroachlabs.com/docs/v26.2/architecture/reads-and-writes-overview&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;leaseholder mechanism&lt;/u&gt;&lt;/a&gt; assigns a single node as the coordinator for each range of data. Reads are served locally from the leaseholder. Writes go through Raft consensus but require only a majority quorum. If one replica is temporarily further away due to orbital mechanics, the other two can still commit the write.&lt;/p&gt;&lt;p&gt;However, optimal leaseholder placement on the ground is a function of user geography: Place the leaseholder near the users who read the data most frequently. In orbit, &quot;near&quot; is not a fixed concept. The leaseholder that is closest to the ground station in Singapore right now will be over the Indian Ocean in twelve minutes and over East Africa in twenty-four.&lt;/p&gt;&lt;p&gt;More broadly, orbital computing transforms what &quot;local&quot; means. On Earth, locality is primarily geographic. In orbit, locality becomes temporal as well, because the optimal location for serving data changes continuously as satellites move. Database architecture must adapt to both dimensions.&amp;nbsp;&lt;/p&gt;&lt;h2 id=&quot;VIII.-Does-relativity-matter-for-an-orbital-database?&quot;&gt;&lt;b&gt;VIII. Does relativity matter for an orbital database?&amp;nbsp;&lt;/b&gt;&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;Surprisingly, relativity is not the primary engineering challenge for an orbital database. A satellite at 550 kilometers altitude moves at 7.66 kilometers per second through a gravitational field weaker than the one on the surface below. The reader familiar with GPS will expect this to matter: GPS satellites carry atomic clocks that drift 38 microseconds per day due to relativistic effects, and the system would be useless without corrections. Surely a database in orbit must contend with the same physics.&lt;/p&gt;&lt;p&gt;At 550 kilometers, general relativity causes the onboard clock to run approximately five microseconds per day fast, because gravity is weaker and time passes more quickly further from the mass. Special relativity causes it to run approximately 28 microseconds per day slow, because the satellite is moving at orbital velocity and moving clocks run slow. The net drift is roughly 23 microseconds per day. The orbital clock falls behind the ground clock by about 0.27 nanoseconds every second.&lt;/p&gt;&lt;p&gt;CockroachDB does not use atomic clocks. It uses &lt;a href=&quot;https://www.cockroachlabs.com/glossary/distributed-db/hybrid-logical-clock-hlc-timestamps/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;hybrid logical clocks&lt;/u&gt;&lt;/a&gt;, a mechanism that combines a physical timestamp with a logical counter to establish a consistent ordering of events across nodes. The system is designed to tolerate &lt;a href=&quot;https://www.cockroachlabs.com/blog/living-without-atomic-clocks/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;clock skew&lt;/u&gt;&lt;/a&gt;. Its default maximum offset is 500 milliseconds. The relativistic drift across the duration of a database transaction, which completes in milliseconds, is on the order of picoseconds. That’s smaller than the tolerance by a factor of roughly one trillion.&lt;/p&gt;&lt;p&gt;The physics that the public associates with space, the curvature of spacetime, the dilation of clocks, the warping of simultaneity, is irrelevant to the engineering of an orbital database. The physics that matters is far more mundane: the propagation delay of light across a laser link, the changing topology of a constellation as it rotates, and the three-millisecond penalty for every message that must traverse the atmosphere. Einstein is not the problem. Newton is the problem.&lt;/p&gt;&lt;p&gt;In other words, the limiting factor isn’t exotic physics. It’s the practical realities of moving data across a changing network fast enough to maintain consistency.&amp;nbsp;&lt;/p&gt;&lt;h2 id=&quot;IX.-How-should-databases-adapt-to-moving-satellite-networks?&quot;&gt;&lt;b&gt;IX. How should databases adapt to moving satellite networks?&amp;nbsp;&lt;/b&gt;&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;Databases operating across satellite constellations must continuously adapt to a network whose topology is always changing. The challenge of optimal &lt;a href=&quot;https://www.cockroachlabs.com/blog/multi-region-database-architecture-sql-placement-locality/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;leaseholder placement&lt;/u&gt;&lt;/a&gt; in an orbital constellation is about geometry, not databases. A constellation of satellites forms a mesh, which is embedded on a set of orbital shells. Each shell is a sphere at a fixed altitude, and the satellites trace geodesics on that sphere, which is to say, great circles. The mesh is not static; it rotates, and the relative distances between nodes on different orbital planes change continuously as the planes &lt;a href=&quot;https://en.wikipedia.org/wiki/Precession&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;precess&lt;/u&gt;&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The latency between any two nodes is a function of the geodesic distance on the mesh at a given moment, modified by the routing topology of the laser links. The optimal leaseholder placement for a given range of data is the node that minimizes the expected latency to the set of clients accessing that range.&lt;/p&gt;&lt;p&gt;On the ground, this optimization is performed periodically and produces a static assignment: leaseholder for range R goes to node N in region X. In orbit, the optimal assignment drifts continuously. The leaseholder that minimizes latency at minute zero is suboptimal by minute six and possibly the worst choice by minute forty-seven.&lt;/p&gt;&lt;p&gt;A simple approximation may suffice for early deployments: Precompute a periodic leaseholder schedule based on the known orbital elements. The constellation repeats its geometry every orbital period, roughly 95 minutes for a 550-kilometer orbit. The leaseholder placement repeats with it. The database could carry a timetable, like a train schedule, rotating leaseholders through a predetermined sequence.&lt;/p&gt;&lt;p&gt;This would not be optimal. However, it would be correct, and correctness – at 550 kilometers –&amp;nbsp; matters more than optimality.&lt;/p&gt;&lt;h2 id=&quot;X.-How-does-data-sovereignty-work-in-orbit?&quot;&gt;&lt;b&gt;X. How does data sovereignty work in orbit?&amp;nbsp;&lt;/b&gt;&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;Data sovereignty becomes significantly more complex in orbit because satellites routinely cross national jurisdictions. A satellite in low Earth orbit at 550 kilometers altitude completes one orbit in approximately 95 minutes. In that time, it crosses over dozens of national jurisdictions. The ground track of a single orbit might pass over Canada, the Atlantic Ocean, Portugal, Algeria, Niger, Chad, the Central African Republic, the Democratic Republic of Congo, Zambia, Mozambique, the Indian Ocean, and Australia before the satellite has completed half its circuit.&lt;/p&gt;&lt;p&gt;Data sovereignty laws are defined by terrestrial borders. The European Union&#39;s &lt;a href=&quot;https://www.cockroachlabs.com/blog/multi-region-serverless-data-residency/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;General Data Protection Regulation&lt;/u&gt;&lt;/a&gt; applies to the personal data of EU residents, regardless of where the data is physically stored. But &quot;where the data is physically stored&quot; has always meant a building with an address. A rack with a serial number. A jurisdiction with a court.&lt;/p&gt;&lt;p&gt;A satellite over Portugal holds a copy of a row written by a user in Frankfurt. Ninety-five minutes later, that satellite and that row are over the Pacific. Does this constitute a cross-border data transfer? That’s a question that no existing regulation was written to answer. However those questions are ultimately resolved, they will influence far more than database design. They’ll shape where regulated industries can deploy orbital applications, how global services satisfy regional compliance requirements, and which governance models emerge for computing beyond terrestrial infrastructure.&amp;nbsp;&lt;/p&gt;&lt;p&gt;CockroachDB&#39;s zone configurations allow operators to &lt;a href=&quot;https://www.cockroachlabs.com/docs/v26.2/data-domiciling&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;pin data to specific localities&lt;/u&gt;&lt;/a&gt;. On the ground, this means constraining replicas to specific regions: EU data stays in EU data centers. In orbit, the &quot;EU data center&quot; is an EU data center for approximately eight minutes per orbit. Then it’s an Atlantic data center,&amp;nbsp; then an African data center...&lt;/p&gt;&lt;p&gt;The database can be configured to replicate data only to satellites that are currently over approved jurisdictions. But &quot;currently&quot; changes every few minutes, and re-replicating data at orbital velocity would generate more network traffic than the laser links could carry.&lt;/p&gt;&lt;p&gt;The more practical approach: define sovereignty by the satellite&#39;s registration, not its position. A satellite registered in the EU and operated by an EU entity could be considered EU territory for data purposes, much as a ship flying a flag is subject to the laws of its flag state regardless of its location at sea.&lt;/p&gt;&lt;h2 id=&quot;XI.-What-happens-when-an-orbital-database-node-disappears?&quot;&gt;&lt;b&gt;XI. What happens when an orbital database node disappears?&amp;nbsp;&lt;/b&gt;&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;An orbital database must distinguish between nodes that are temporarily unreachable and those that are permanently lost. On the ground, when a CockroachDB node fails, an operator investigates. The node might be restarted, its disk replaced, its data rebalanced to surviving nodes.&lt;/p&gt;&lt;p&gt;CockroachDB&#39;s &lt;a href=&quot;https://www.cockroachlabs.com/docs/v26.2/node-shutdown&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;decommission process&lt;/u&gt;&lt;/a&gt; is designed for planned removals. An operator marks a node as decommissioning, and the database migrates its data to other nodes before shutting it down cleanly. This process assumes the node is reachable and cooperative.&lt;/p&gt;&lt;p&gt;But there is a subtlety. On the ground, a failed node might come back. The operator reboots it, and it rejoins the cluster with its data intact. The database reconciles the returning node&#39;s state with the current state and continues. In orbit, a node that goes silent might return after a brief communication blackout caused by orbital geometry, or it might never return because it has reentered the atmosphere.&lt;/p&gt;&lt;p&gt;The database can’t distinguish between these cases in real time. The Raft protocol doesn’t include a field for &quot;this node is burning up over the South Pacific.&quot; The liveness timeout must be tuned carefully: too short, and the database will replicate data unnecessarily every time a satellite passes behind the Earth relative to its peers; too long, and the cluster operates with reduced redundancy while waiting for a node that will never return.&lt;/p&gt;&lt;p&gt;Hardware obsolescence introduces another dimension. For example, Nvidia releases new GPU architectures faster than satellites can be manufactured and launched. A constellation deployed in 2028 may contain hardware that is two generations behind by 2030. Rolling upgrades, the standard method for updating CockroachDB, require taking nodes offline and replacing the binary. In orbit, &quot;replacing the binary&quot; is possible through software updates. Replacing the hardware is not. The node&#39;s CPU, memory, and storage are fixed for the lifetime of the satellite, which may be five to ten years.&lt;/p&gt;&lt;p&gt;CockroachDB has always been hardware-agnostic. It runs on whatever the operating system provides. In orbit, this property becomes essential: The database must continue to operate on aging hardware while newer satellites join the constellation with faster processors and larger storage. The cluster must absorb heterogeneous nodes gracefully, routing more work to the faster nodes and less to the older ones.&lt;/p&gt;&lt;p&gt;This is, again, something CockroachDB already does. It just hasn’t done it at orbital timescales.&lt;/p&gt;&lt;p&gt;&lt;!--$!--&gt;&lt;template data-dgst=&quot;BAILOUT_TO_CLIENT_SIDE_RENDERING&quot;&gt;&lt;/template&gt;&lt;!--/$--&gt; &lt;/p&gt;&lt;h2 id=&quot;XII.-What-would-orbital-databases-still-need?&quot;&gt;&lt;b&gt;XII. What would orbital databases still need?&amp;nbsp;&lt;/b&gt;&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;Existing distributed databases could operate in orbit today, but they would require new capabilities to become truly orbital-aware. CockroachDB would function in an orbital constellation today. It would get there and survive. It would not be optimized for the environment, however.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Many of these capabilities would have value beyond orbital computing. As infrastructure becomes increasingly dynamic, whether because of mobile edge deployments, autonomous systems, or future space-based platforms, the ability for distributed databases to adapt automatically to changing topology, latency, and failure domains becomes broadly applicable.&amp;nbsp;&lt;/p&gt;&lt;p&gt;The features that a space-based database deployment would require don’t yet exist, including:&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Dynamic localities.&lt;/b&gt; The current locality system assumes that a node&#39;s position in the topology is fixed. A node in us-east stays in us-east. An orbital node&#39;s effective locality changes continuously. The database would need a locality system that accepts position updates and adjusts replica placement accordingly, or a higher-level abstraction that treats orbital shells and planes as stable localities while acknowledging that their relationship to the ground shifts with time.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Orbital-aware leaseholder policies.&lt;/b&gt; Leaseholder placement today is driven by access patterns observed over time. In orbit, the access patterns are predictable from physics. The database should accept an orbital model and pre-compute leaseholder schedules, rather than discovering the optimal placement reactively through latency observations.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Autonomous decommission.&lt;/b&gt; The current decommission workflow requires an operator to initiate the process. An orbital node that is clearly failing should be able to trigger its own decommission and migrate its data to surviving nodes without waiting for humans or agents to issue a command from the ground.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Jurisdiction-aware replication.&lt;/b&gt; Zone configurations would need a temporal dimension: “This data may reside on this node only while the node is over an approved jurisdiction.” That’s likely impractical at fine granularity, but the framework for expressing the constraint should exist, even if the initial implementation uses flag-state semantics rather than real-time position.&lt;/p&gt;&lt;p&gt;History suggests that infrastructure evolves by solving tomorrow&#39;s problems before they become mainstream. Distributed databases were built to tolerate failures across regions and continents long before anyone imagined constellations of orbital data centers. If computing continues to expand beyond Earth&#39;s surface, the next generation of distributed systems may prove that some of today&#39;s most resilient architectures were already pointing in that direction.&amp;nbsp;&lt;/p&gt;&lt;p&gt;These are engineering problems and they are solvable. Orbital engineering is dominated by considerations of weight. Data doesn&#39;t have physical weight, but it does have operational weight. It must be replicated. It must be consistent. It must survive.&lt;/p&gt;&lt;hr&gt;&lt;h6&gt;&lt;b&gt;Related&amp;nbsp;&lt;/b&gt;&lt;/h6&gt;&lt;p&gt;&lt;a href=&quot;https://www.cockroachlabs.com/guides/oreilly-cockroachdb-the-definitive-guide/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;i&gt;&lt;u&gt;CockroachDB: The Definitive Guide, 2nd Edition (O&#39;Reilly)&lt;/u&gt;&lt;/i&gt;&lt;/a&gt;&lt;i&gt; — a practical deep dive into multi-region deployment, survival goals, and resilience for readers who want to go from thought experiment to production.&lt;/i&gt;&amp;nbsp;&lt;/p&gt;&lt;hr&gt;&lt;p&gt;This post draws on reporting by Eric Berger in&lt;a href=&quot;https://arstechnica.com/space/2026/03/orbital-data-centers-part-1-theres-no-way-this-is-economically-viable-right/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt; &lt;u&gt;Ars Technica&lt;/u&gt;&lt;/a&gt;, March 2026.&lt;/p&gt;&lt;hr&gt;&lt;p&gt;&lt;a href=&quot;https://www.linkedin.com/in/wongisaac/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;i&gt;&lt;u&gt;Isaac Wong&lt;/u&gt;&lt;/i&gt;&lt;/a&gt;&lt;i&gt; is EVP of Research &amp;amp; Development at Cockroach Labs, where he leads the engineering organization behind CockroachDB to shape the company&#39;s long-term technical vision. He oversees the teams driving the database&#39;s core architecture, reliability, and continued innovation.&lt;/i&gt;&lt;/p&gt;</description><link>https://www.cockroachlabs.com/blog/orbital-computing-distributed-databases/</link><guid isPermaLink="false">https://www.cockroachlabs.com/blog/orbital-computing-distributed-databases/</guid></item><item><title>Vehicle Search with SQL and Vector Embeddings</title><description>&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/7hXcz7jPQm5jDmTcLO2zJK/82ba160f7e2b3e535c1492c65eba11c7/vehicle-search-sql-vector-embeddings-thumbnail.png&quot;&gt;&lt;img alt=&quot;Three cars on the road&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1080&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/7hXcz7jPQm5jDmTcLO2zJK/82ba160f7e2b3e535c1492c65eba11c7/vehicle-search-sql-vector-embeddings-thumbnail.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&quot;I&#39;ll know it when I see it&quot; is the classic car buyer&#39;s line, but it&#39;s also the one thing old-school search bars totally fail to deliver.&lt;/p&gt;&lt;p&gt;Traditional keyword search fails when a customer wants a car that &quot;&lt;b&gt;looks like this photo from &lt;/b&gt;&lt;b&gt;&lt;i&gt;Fast and Furious&lt;/i&gt;&lt;/b&gt;&lt;b&gt;.&lt;/b&gt;&quot; This is where vector search comes in, transforming unstructured data into mathematical vectors to find semantically similar items.&lt;/p&gt;&lt;p&gt;In this blog I’ll walk you through a fun little demo I cooked up called &quot;Cockroach Cars.&quot; I use a combination of Python and SQL to find cars currently available for purchase. We&#39;ll check out how to use CockroachDB as a spot to stash vectors, make embeddings, peek at the vector space, and even do cool image-to-image similarity searches—all right inside the database just using SQL.&lt;/p&gt;&lt;h2 id=&quot;1.-Visual-Search:-Finding-That-&amp;quot;Fast-and-Furious&amp;quot;-Look&quot;&gt;1. Visual Search: Finding That &quot;Fast and Furious&quot; Look&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;Time to talk about the main attraction: finding a car just from a picture! This is the cool part. There is no need to sift through lists, hoping the seller provided the right keywords in their description, like &quot;vintage muscle&quot; or &quot;street racer.&quot; Just paste the photo, the app turns it into a vector, and then asks &lt;a href=&quot;https://www.cockroachlabs.com/product/overview/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;CockroachDB&lt;/u&gt;&lt;/a&gt; to find the most similar cars.&amp;nbsp;&lt;/p&gt;&lt;h3 id=&quot;The-Process&quot;&gt;The Process&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Input:&lt;/b&gt; The user copies an image to their clipboard.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Embedding:&lt;/b&gt; In the program, a vector embedding is generated for that image using the loaded CLIP model.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;SQL Query:&lt;/b&gt; We run a &lt;b&gt;K-Nearest Neighbors (KNN)&lt;/b&gt; search directly in CockroachDB using the &lt;code&gt;&amp;lt;-&amp;gt;&lt;/code&gt; (L2 Distance/Euclidean) operator.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Provide filters like the number of items returned within a price range.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The user copies an image of their ideal &quot;Fast and Furious&quot; vehicle to the clipboard, along with the quantity of cars found in the search results and the desired price range.&lt;/p&gt;&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/6Q0Ohypva5VTQn87TSwexH/636cfaa513a13823850d4a71521e2958/cockroach-cars-app-screenshot.png&quot;&gt;&lt;img alt=&quot;Screenshot of an app that lets you visually search cars using an image. There are toggles for the number of cars to show in the results as well as a price range in USD.&quot; loading=&quot;lazy&quot; width=&quot;752&quot; height=&quot;335&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/6Q0Ohypva5VTQn87TSwexH/636cfaa513a13823850d4a71521e2958/cockroach-cars-app-screenshot.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Check out the SQL query that makes this semantic magic happen to find the ride you &lt;i&gt;actually&lt;/i&gt; want.&lt;/p&gt;&lt;div class=&quot;blog-codeblock mb-4 font-roboto-mono&quot;&gt;&lt;button class=&quot;w-full bg-[#6933ff] p-4 text-sm text-white hover:underline focus:outline-none&quot;&gt;Show code &lt;/button&gt;&lt;/div&gt;&lt;p&gt;The query filters by price range (a standard scalar filter) &lt;i&gt;and&lt;/i&gt; sorts by vector similarity (distance) simultaneously.&lt;/p&gt;&lt;h3 id=&quot;The-Results&quot;&gt;The Results&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;p&gt;In our example search, we used an input image of a classic muscle car. The search returned:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;1969 Pontiac Firebird&lt;/b&gt; ($46k)&amp;nbsp;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;1969 Chevrolet Camaro&lt;/b&gt; ($335k)&amp;nbsp;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;1966 Chevrolet Sport&lt;/b&gt; ($41k)&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;1968 Pontiac GTO&lt;/b&gt; ($45k)&amp;nbsp;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;1964 Oldsmobile Jetstar 88 Holiday Coupe&lt;/b&gt; ($33k)&amp;nbsp;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;1967 Pontiac Firebird &lt;/b&gt;($29k) &lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/6EX1VvasmGWEo6MFI6kMPy/e68304996f8a5aa099eb7539aa65f84f/cockroach-cars-results-screenshot.png&quot;&gt;&lt;img alt=&quot;6 cars are pictured: 
1969 Pontiac Firebird ($46k) 
1969 Chevrolet Camaro ($335k) 
1966 Chevrolet Sport ($41k)
1968 Pontiac GTO ($45k) 
1964 Oldsmobile Jetstar 88 Holiday Coupe ($33k) 
1967 Pontiac Firebird ($29k)&quot; loading=&quot;lazy&quot; width=&quot;1665&quot; height=&quot;778&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/6EX1VvasmGWEo6MFI6kMPy/e68304996f8a5aa099eb7539aa65f84f/cockroach-cars-results-screenshot.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The results are remarkably consistent. Despite different makes and models, all returned vehicles share the distinctive visual characteristics of late-60s American muscle cars (boxy hoods, circular headlights, chrome bumpers).&lt;/p&gt;&lt;h2 id=&quot;2.-Under-the-Hood&quot;&gt;2. Under the Hood&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;To bring &quot;Cockroach Cars&quot; to life, we need a setup that can handle both standard relational data and high-dimensional vector operations without getting bogged down. A stack that is developer-friendly, and capable of executing complex similarity searches right inside the database. Here is the specific toolkit I used to build this engine.&lt;/p&gt;&lt;h3 id=&quot;The-Tech-Stack&quot;&gt;The Tech Stack&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;CockroachDB&lt;/b&gt; &lt;b&gt;Database:&lt;/b&gt; With distributed SQL and vector search, all in one.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Language:&lt;/b&gt; Python (Jupyter Notebook environment)&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Python Libraries:&lt;/b&gt; &lt;code&gt;sentence-transformers&lt;/code&gt; (CLIP model), &lt;code&gt;scikit-learn&lt;/code&gt; (PCA/KMeans), &lt;code&gt;plotly&lt;/code&gt; (3D visualization)&amp;nbsp;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Database Driver:&lt;/b&gt; &lt;code&gt;psycopg&lt;/code&gt; (PostgreSQL adapter)&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I’m using the &lt;b&gt;CLIP (Contrastive Language-Image Pre-training)&lt;/b&gt; model (the &lt;a href=&quot;https://huggingface.co/sentence-transformers/clip-ViT-B-32&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;clip-ViT-B-32 version&lt;/u&gt;&lt;/a&gt; from sentence-transformers). CLIP is perfect for this because it puts both images and text in the same &quot;vector space,&quot; which lets you search with either text-to-image or image-to-image.&lt;/p&gt;&lt;div class=&quot;blog-codeblock mb-4 font-roboto-mono&quot;&gt;&lt;div class=&quot; [&amp;amp;&gt;div&gt;span&gt;code]:bg-transparent [&amp;amp;&gt;div&gt;span&gt;code]:text-white&quot;&gt;&lt;div class=&quot;sc-gsDLFA oicjj&quot;&gt;&lt;span style=&quot;font-size:inherit;font-family:inherit;background:#282a36;color:#f8f8f2;border-radius:3px;display:flex;line-height:1.4285714285714286;overflow-x:auto;white-space:pre&quot;&gt;&lt;code style=&quot;white-space:pre;font-size:inherit;font-family:inherit;line-height:1.6666666666666667;padding:8px&quot;&gt;    # Load the model
    from sentence_transformers import SentenceTransformer
    model = SentenceTransformer(&#39;clip-ViT-B-32&#39;)&lt;/code&gt;&lt;/span&gt;&lt;button aria-label=&quot;Copy Code&quot; type=&quot;button&quot; class=&quot;sc-bdvvNz SnCde&quot;&gt;&lt;svg class=&quot;icon&quot; viewBox=&quot;0 0 384 512&quot; width=&quot;16pt&quot; height=&quot;16pt&quot; fill=&quot;#f8f8f2&quot;&gt;&lt;path d=&quot;M280 240H168c-4.4 0-8 3.6-8 8v16c0 4.4 3.6 8 8 8h112c4.4 0 8-3.6 8-8v-16c0-4.4-3.6-8-8-8zm0 96H168c-4.4 0-8 3.6-8 8v16c0 4.4 3.6 8 8 8h112c4.4 0 8-3.6 8-8v-16c0-4.4-3.6-8-8-8zM112 232c-13.3 0-24 10.7-24 24s10.7 24 24 24 24-10.7 24-24-10.7-24-24-24zm0 96c-13.3 0-24 10.7-24 24s10.7 24 24 24 24-10.7 24-24-10.7-24-24-24zM336 64h-80c0-35.3-28.7-64-64-64s-64 28.7-64 64H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM192 48c8.8 0 16 7.2 16 16s-7.2 16-16 16-16-7.2-16-16 7.2-16 16-16zm144 408c0 4.4-3.6 8-8 8H56c-4.4 0-8-3.6-8-8V120c0-4.4 3.6-8 8-8h40v32c0 8.8 7.2 16 16 16h160c8.8 0 16-7.2 16-16v-32h40c4.4 0 8 3.6 8 8v336z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Then connect to a CockroachDB cluster using a connection string formatted for &lt;code&gt;psycopg&lt;/code&gt;.&amp;nbsp;&lt;/p&gt;&lt;h3 id=&quot;The-Data&quot;&gt;The Data&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;p&gt;I collected the vehicle image dataset from various internet sources, including Kaggle and GitHub. To create the corresponding synthetic metadata, I developed a Python script leveraging the Faker package. The complete process involved three steps:&amp;nbsp;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Loading the images into a staging table&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Generating both the image embeddings and the metadata&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Inserting this information into the &lt;code&gt;for_sale_inventory&lt;/code&gt; table&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;This final table holds the vehicle metadata alongside their respective image embeddings.&lt;/p&gt;&lt;div class=&quot;blog-codeblock mb-4 font-roboto-mono&quot;&gt;&lt;button class=&quot;w-full bg-[#6933ff] p-4 text-sm text-white hover:underline focus:outline-none&quot;&gt;Show code &lt;/button&gt;&lt;/div&gt;&lt;h2 id=&quot;3.-Data-Exploration&quot;&gt;3. Data Exploration&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;Before diving into vectors, let’s do some standard SQL analysis to get a feel for the dataset. We&#39;re working with &lt;b&gt;4,597 vehicles&lt;/b&gt; and &lt;b&gt;19 columns&lt;/b&gt; with images, embeddings, and metadata.&lt;/p&gt;&lt;p&gt;A quick look at the data reveals columns like &lt;code&gt;vin&lt;/code&gt;, &lt;code&gt;make&lt;/code&gt;, &lt;code&gt;model&lt;/code&gt;, &lt;code&gt;price_in_usd&lt;/code&gt;, &lt;code&gt;registration_date&lt;/code&gt;, &lt;code&gt;fuel_type&lt;/code&gt; and &lt;code&gt;image_embedding&lt;/code&gt;.&lt;/p&gt;&lt;div class=&quot;blog-codeblock mb-4 font-roboto-mono&quot;&gt;&lt;div class=&quot; [&amp;amp;&gt;div&gt;span&gt;code]:bg-transparent [&amp;amp;&gt;div&gt;span&gt;code]:text-white&quot;&gt;&lt;div class=&quot;sc-gsDLFA oicjj&quot;&gt;&lt;span style=&quot;font-size:inherit;font-family:inherit;background:#282a36;color:#f8f8f2;border-radius:3px;display:flex;line-height:1.4285714285714286;overflow-x:auto;white-space:pre&quot;&gt;&lt;code style=&quot;white-space:pre;font-size:inherit;font-family:inherit;line-height:1.6666666666666667;padding:8px&quot;&gt;result = %sql SELECT vin, make, model, price_in_usd, registration_date, fuel_type, image_embedding FROM for_sale_inventory;                                     
df = result.DataFrame()        # Convert to Pandas DataFrame
df.head(5)                     # Preview 5 data rows&lt;/code&gt;&lt;/span&gt;&lt;button aria-label=&quot;Copy Code&quot; type=&quot;button&quot; class=&quot;sc-bdvvNz SnCde&quot;&gt;&lt;svg class=&quot;icon&quot; viewBox=&quot;0 0 384 512&quot; width=&quot;16pt&quot; height=&quot;16pt&quot; fill=&quot;#f8f8f2&quot;&gt;&lt;path d=&quot;M280 240H168c-4.4 0-8 3.6-8 8v16c0 4.4 3.6 8 8 8h112c4.4 0 8-3.6 8-8v-16c0-4.4-3.6-8-8-8zm0 96H168c-4.4 0-8 3.6-8 8v16c0 4.4 3.6 8 8 8h112c4.4 0 8-3.6 8-8v-16c0-4.4-3.6-8-8-8zM112 232c-13.3 0-24 10.7-24 24s10.7 24 24 24 24-10.7 24-24-10.7-24-24-24zm0 96c-13.3 0-24 10.7-24 24s10.7 24 24 24 24-10.7 24-24-10.7-24-24-24zM336 64h-80c0-35.3-28.7-64-64-64s-64 28.7-64 64H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM192 48c8.8 0 16 7.2 16 16s-7.2 16-16 16-16-7.2-16-16 7.2-16 16-16zm144 408c0 4.4-3.6 8-8 8H56c-4.4 0-8-3.6-8-8V120c0-4.4 3.6-8 8-8h40v32c0 8.8 7.2 16 16 16h160c8.8 0 16-7.2 16-16v-32h40c4.4 0 8 3.6 8 8v336z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Upon execution of the code above, the query successfully retrieved 4,597 records from the inventory table, which are now stored in our DataFrame (see below).&lt;/p&gt;&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/5BWmI2ybWBQHaUiiSEjirP/3a779a5ae77aa50028d6fd5a0902fe1b/cockroach-cars-data-subset.png&quot;&gt;&lt;img alt=&quot;First 5 rows of a car dataset, including columns vin, make, model, price_in_usd, registration_date, fuel_type, and image_embedding.&quot; loading=&quot;lazy&quot; width=&quot;977&quot; height=&quot;182&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/5BWmI2ybWBQHaUiiSEjirP/3a779a5ae77aa50028d6fd5a0902fe1b/cockroach-cars-data-subset.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3 id=&quot;Visualizing-Inventory-Distribution&quot;&gt;Visualizing Inventory Distribution&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;p&gt;I use &lt;code&gt;matplotlib&lt;/code&gt; and &lt;code&gt;seaborn&lt;/code&gt; to whip up a dashboard for visualizing the inventory from the Pandas dataframe (&lt;code&gt;result&lt;/code&gt;) created in the sample code above.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Price Distribution:&lt;/b&gt; A histogram shows the price spread, likely right-skewed with a long tail of luxury vehicles.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Fuel Type:&lt;/b&gt; A pie chart reveals a diverse mix of Electric (21.9%), Hybrid (22.1%), Petrol (33.2%), and Diesel (22.8%) vehicles.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Inventory Cloud:&lt;/b&gt; Word clouds for &quot;Make&quot; and &quot;Model&quot; highlight dominant brands like Volkswagen, Acura, and Pontiac.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/3T4n7gsiApe0gkYx9JG7hH/28069f1ca8cd407ce59e0246f7ff0c89/visualizing-inventory-distribution.png&quot;&gt;&lt;img alt=&quot;Matplotlib and seaborn dashboard including
Price Distribution: A histogram shows the price spread, likely right-skewed with a long tail of luxury vehicles.
Fuel Type: A pie chart reveals a diverse mix of Electric (21.9%), Hybrid (22.1%), Petrol (33.2%), and Diesel (22.8%) vehicles.
Inventory Cloud: Word clouds for &amp;quot;Make&amp;quot; and &amp;quot;Model&amp;quot; highlight dominant brands like Volkswagen, Acura, and Pontiac.&quot; loading=&quot;lazy&quot; width=&quot;1131&quot; height=&quot;805&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/3T4n7gsiApe0gkYx9JG7hH/28069f1ca8cd407ce59e0246f7ff0c89/visualizing-inventory-distribution.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;4.-Visualizing-the-Vector-Space&quot;&gt;4. Visualizing the Vector Space&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;CockroachDB&#39;s C-SPANN vector indexing is super smart! It uses a hierarchical k-means tree (see figure below) to organize vector data for very efficient similarity searches. Basically, it grabs your categorized data (like, all the Toyota models), groups them using k-means (think of it like sorting them into handy 3D clusters), and then makes a map of all that complex high-dimensional info. This organized tree lets the database zoom right to the closest matches without having to look through &lt;i&gt;everything&lt;/i&gt;.&lt;/p&gt;&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/7MgxZ9L711btb1evJ6Su03/59fca894ab1a60fbc0b0622fd615bdc2/k-means-tree-powering-cspann-cockroachdb-vector-indexing.png&quot;&gt;&lt;img alt=&quot;The core data structure powering C-SPANN is the K-means tree. Within the tree, vectors are grouped into partitions, which can contain anywhere from dozens to hundreds of vectors. Each partition has a centroid vector, which is the average of the vectors in that partition, and represents their “center of mass”.&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1171&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/7MgxZ9L711btb1evJ6Su03/59fca894ab1a60fbc0b0622fd615bdc2/k-means-tree-powering-cspann-cockroachdb-vector-indexing.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;i&gt;Image Caption: &lt;/i&gt;&lt;i&gt;&lt;b&gt;Hierarchical K-means Tree&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;&lt;p&gt;For more information see:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;a href=&quot;https://www.cockroachlabs.com/blog/distributed-vector-indexing-cockroachdb/#C-SPANN:-A-new-distributed-vector-indexing-algorithm&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;Introducing Distributed Vector Indexing to CockroachDB&lt;/u&gt;&lt;/a&gt; by David Bressler&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href=&quot;https://www.cockroachlabs.com/blog/cspann-real-time-indexing-billions-vectors/#Introducing-C-SPANN&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;Real-Time Indexing for Billions of Vectors: How we built fast, fresh vector indexing at scale in CockroachDB&lt;/u&gt;&lt;/a&gt; by Andy Kimball&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;hr&gt;&lt;p&gt;&lt;b&gt;RELATED:&lt;/b&gt; Check out this video by Technical Evangelist Rob Reid, who explains why having vectors in the same database as your relational data is a modern-day super power.&lt;/p&gt;&lt;p&gt;&lt;!--$!--&gt;&lt;template data-dgst=&quot;BAILOUT_TO_CLIENT_SIDE_RENDERING&quot;&gt;&lt;/template&gt;&lt;!--/$--&gt;&lt;/p&gt;&lt;hr&gt;&lt;p&gt;Okay, so those car image vectors are 512-dimension arrays of numbers, which, let&#39;s be honest, don&#39;t make much sense to us humans. To help us &lt;i&gt;see&lt;/i&gt; how the images relate to each other, we shrink those super-high-dimensional vectors down to a simple 3-dimensions. In this example we only do this dimensionality reduction for the bottom, or &#39;leaf,&#39; nodes, though.&lt;/p&gt;&lt;h3 id=&quot;The-Pipeline&quot;&gt;The Pipeline&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Fetch Embeddings:&lt;/b&gt; We retrieve the raw vector strings from CockroachDB.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Parse &amp;amp; Standardize:&lt;/b&gt; Convert strings to &lt;code&gt;float32&lt;/code&gt; arrays and normalize them using &lt;code&gt;StandardScaler&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Dimensionality Reduction (PCA):&lt;/b&gt; We use Principal Component Analysis (PCA) to reduce the 512 dimensions down to just 3 components. This retains the most significant variance in the data.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Clustering (K-Means):&lt;/b&gt; We group the vehicles into 50 clusters (representing different car makes) to color-code the visualization.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h3 id=&quot;The-3D-Plot&quot;&gt;The 3D Plot&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;p&gt;Using &lt;code&gt;plotly&lt;/code&gt;, we plot the vehicles in 3D space.&lt;/p&gt;&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/5WVdvlui4f0llnFa41we33/3333089500b844387d828f7fa1e9105e/cockroach-cars-3d-plot.png&quot;&gt;&lt;img alt=&quot;In the interactive plot provided, visually similar vehicles are naturally grouped together. The red diamonds, highlighted on the left side of the figure above, represent the centroids, such as the coordinates for Toyota. The right side of the figure displays the vector coordinates (a car image) corresponding to a selected embedding.&quot; loading=&quot;lazy&quot; width=&quot;1257&quot; height=&quot;636&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/5WVdvlui4f0llnFa41we33/3333089500b844387d828f7fa1e9105e/cockroach-cars-3d-plot.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;In the interactive plot provided, visually similar vehicles are naturally grouped together. The red diamonds, highlighted on the left side of the figure above, represent the centroids, such as the coordinates for Toyota. The right side of the figure displays the vector coordinates (a car image) corresponding to a selected embedding.&lt;/p&gt;&lt;h2 id=&quot;Conclusion&quot;&gt;Conclusion&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;So, the &quot;Cockroach Cars&quot; walkthrough shows how awesome it is when you blend vector search right into standard SQL. You ditch the need for separate embedding services or vector databases, which means you can build smart apps that filter data and find similar stuff semantically with just one quick, easy query.&amp;nbsp; We can query metadata (&lt;code&gt;WHERE price &amp;gt; 50000&lt;/code&gt;) and vectors (&lt;code&gt;WHERE image_embedding &amp;lt;-&amp;gt; query&lt;/code&gt;) in a single, ACID-compliant SQL statement.&lt;/p&gt;&lt;p&gt;This doesn&#39;t just make the whole setup and your data pipeline simpler; you also get all that legendary CockroachDB resilience, easy scaling and multi-region capabilities. So, even the craziest &quot;fast and furious&quot; searches stay efficient, reliable, and available everywhere.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.cockroachlabs.com/solutions/verticals/ai-innovators/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;Learn more&lt;/u&gt;&lt;/a&gt; about how top AI Innovators are achieving success with CockroachDB&lt;/p&gt;&lt;p&gt;&lt;i&gt;Alejandro Infanzon is a Solutions Architect at Cockroach Labs.&lt;/i&gt;&lt;/p&gt;</description><link>https://www.cockroachlabs.com/blog/vehicle-search-sql-vector-embeddings/</link><guid isPermaLink="false">https://www.cockroachlabs.com/blog/vehicle-search-sql-vector-embeddings/</guid></item><item><title>Value Separation in Pebble: Storage Engine Optimization</title><description>&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/6lb4k4FKkZJDtna56DucKH/aa955df68f06d42bbeee9657fc2cd290/value-separation-pebble.png&quot;&gt;&lt;img alt=&quot;A background of pebbles&quot; loading=&quot;lazy&quot; width=&quot;1422&quot; height=&quot;800&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/6lb4k4FKkZJDtna56DucKH/aa955df68f06d42bbeee9657fc2cd290/value-separation-pebble.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;Motivation&quot;&gt;&lt;b&gt;Motivation&lt;/b&gt;&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;At its foundation, CockroachDB depends on a key-value storage engine called &lt;a href=&quot;https://www.cockroachlabs.com/blog/pebble-rocksdb-kv-store/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;Pebble&lt;/u&gt;&lt;/a&gt;. In CockroachDB v25.4, the storage team introduced &lt;b&gt;value separation&lt;/b&gt; within Pebble: an optimization that improves compaction efficiency for many workloads. Value separation increases the throughput of the core of CockroachDB, the storage engine, by up to ~50%, depending on the workload, through algorithmic improvements. It reduces redundant I/O, reducing cost-to-serve at scale. We’ll look at how Pebble represents data today, what’s changed, and how that translates to database efficiency.&lt;/p&gt;&lt;h2 id=&quot;Background&quot;&gt;&lt;b&gt;Background&lt;/b&gt;&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;The higher layers of CockroachDB write key-value (KV) pairs to Pebble, and the storage engine persists them durably while maintaining organization to efficiently service reads. Internally, Pebble implements a &lt;a href=&quot;https://www.cockroachlabs.com/docs/v25.4/architecture/storage-layer.html#log-structured-merge-trees&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;log-structured merge-tree (LSM)&lt;/u&gt;&lt;/a&gt;: a data structure that organizes KV pairs into key-sorted runs. Asynchronous compactions continuously rewrite data in the background, sorting KVs to keep up with incoming writes.&amp;nbsp;&lt;/p&gt;&lt;p&gt;During these compactions, a selection of input &lt;a href=&quot;https://www.cockroachlabs.com/docs/v25.4/architecture/storage-layer.html#ssts&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;SSTables (SSTs)&lt;/u&gt;&lt;/a&gt; are read, merge-sorted by key, and written to new SSTs in sorted order. Compactions reduce the cost of reads by reducing the number of read I/O operations performed per logical read operation (called &lt;i&gt;read amplification&lt;/i&gt;). But compactions come with tradeoffs. Namely, compactions consume CPU, read bandwidth, and substantial write bandwidth.&lt;/p&gt;&lt;p&gt;Workloads with large values (e.g. wide rows or JSONB documents) especially incur the overhead of compactions since these operations must read and rewrite substantial data. The sorting that compactions perform is a function of keys only; not values. Based on this observation, significant research (notably the &lt;a href=&quot;https://www.usenix.org/system/files/conference/fast16/fast16-papers-lu.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;WiscKey paper&lt;/u&gt;&lt;/a&gt;) has explored the concept of &lt;i&gt;value separation&lt;/i&gt;, storing values out-of-band, physically separated from the corresponding keys, allowing compactions to sort keys without repeatedly rewriting values. This physical separation of keys and values provides additional flexibility in the tradeoff between read performance, space amplification, and write amplification.&lt;/p&gt;&lt;p&gt;In this blog post, we’ll examine the tradeoffs involved in value separation, the unique design of Pebble’s implementation, and the empirical benefits we’ve observed.&lt;/p&gt;&lt;h2 id=&quot;Impact&quot;&gt;&lt;b&gt;Impact&lt;/b&gt;&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;Cockroach Labs runs regular benchmarks of various workloads against nightly builds of CockroachDB to track the performance of the database over time and catch regressions early. The below graph plots the throughput of a simple workload upserting key-value pairs with small keys (&lt;code&gt;BIGINT&lt;/code&gt; primary key) and 4 KiB values. Value separation was enabled in this benchmark at the end of June, resulting in a ~47% increase in throughput on the same hardware.&lt;/p&gt;&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/2Wu8D80xvdXOKR34UkOHRA/b785b3d3562c10b1e9eb58daa40a6d53/throughput-over-time-with-value-separation.png&quot;&gt;&lt;img alt=&quot;Plots the throughput of a simple workload upserting key-value pairs with small keys (BIGINT primary key) and 4 KiB values. Value separation was enabled in this benchmark at the end of June, resulting in a ~47% increase in throughput on the same hardware.&quot; loading=&quot;lazy&quot; width=&quot;1000&quot; height=&quot;618&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/2Wu8D80xvdXOKR34UkOHRA/b785b3d3562c10b1e9eb58daa40a6d53/throughput-over-time-with-value-separation.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;i&gt;Image Caption: kv0/values=4096 benchmark throughput over time (2025)&lt;/i&gt;&lt;/p&gt;&lt;p&gt;This benchmark demonstrates this feature’s significant impact on efficiency and cost-to-serve. Workloads with smaller values see less pronounced impact. Various heuristics determine which values are physically separated and allow even small-valued workloads to benefit.&lt;/p&gt;&lt;h2 id=&quot;Prior-art&quot;&gt;&lt;b&gt;Prior art&lt;/b&gt;&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;Value separation is a frequently examined topic in log-structured merge tree storage systems. Projects like &lt;b&gt;WiscKey&lt;/b&gt; (&lt;a href=&quot;https://www.usenix.org/system/files/conference/fast16/fast16-papers-lu.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;Lu et al., FAST 2016&lt;/u&gt;&lt;/a&gt;) and &lt;b&gt;LavaStore&lt;/b&gt; (&lt;a href=&quot;https://dl.acm.org/doi/pdf/10.14778/3685800.3685807&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;Wang et al., VLDB 2024&lt;/u&gt;&lt;/a&gt;) demonstrated that significant reductions in write amplification are possible through storing values out-of-band. However, separation of values comes with its own tradeoffs, and none of these published implementations were appropriate for CockroachDB’s workloads.&lt;/p&gt;&lt;p&gt;Pebble sits at the core of CockroachDB’s storage layer where correctness, performance, and a reasonable cost-to-serve all have to coexist. Much of the complexity in external value separation lies within the heuristics of when to compact values to ensure reads remain performant, space amplification is minimal, while still realizing the write-amplification advantages.&lt;/p&gt;&lt;h2 id=&quot;Mechanics&quot;&gt;&lt;b&gt;Mechanics&lt;/b&gt;&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;Pebble’s implementation of value separation introduces a new type of file to the storage engine called a &lt;i&gt;blob file&lt;/i&gt;. A blob file stores values that have been separated, independent from the corresponding key. Physically, a blob file consists of a series of value blocks, containing values, an index describing where the value blocks begin and end, and a footer of metadata.&lt;/p&gt;&lt;div class=&quot;blog-codeblock mb-4 font-roboto-mono&quot;&gt;&lt;button class=&quot;w-full bg-[#6933ff] p-4 text-sm text-white hover:underline focus:outline-none&quot;&gt;Show code &lt;/button&gt;&lt;/div&gt;&lt;p&gt;Both index blocks and value blocks are encoded in Pebble’s &lt;a href=&quot;https://github.com/cockroachdb/pebble/tree/455e559/sstable/colblk&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;columnar-block format&lt;/u&gt;&lt;/a&gt; (similar to &lt;a href=&quot;https://www.vldb.org/conf/2001/P169.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;PAX&lt;/u&gt;&lt;/a&gt;) allowing constant time lookup of a block by its &lt;i&gt;block ID&lt;/i&gt; and a value by its &lt;i&gt;value ID&lt;/i&gt;. When a key’s value is separated into a blob file, the SSTable KV encodes a concise &lt;a href=&quot;https://github.com/cockroachdb/pebble/blob/2d1c267ca8d0bf430791c3e14e863e6c60703334/sstable/blob/handle.go#L33-L41&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;i&gt;&lt;u&gt;value handle&lt;/u&gt;&lt;/i&gt;&lt;/a&gt;:&lt;/p&gt;&lt;div class=&quot;blog-codeblock mb-4 font-roboto-mono&quot;&gt;&lt;div class=&quot; [&amp;amp;&gt;div&gt;span&gt;code]:bg-transparent [&amp;amp;&gt;div&gt;span&gt;code]:text-white&quot;&gt;&lt;div class=&quot;sc-gsDLFA oicjj&quot;&gt;&lt;span style=&quot;font-size:inherit;font-family:inherit;background:#282a36;color:#f8f8f2;border-radius:3px;display:flex;line-height:1.4285714285714286;overflow-x:auto;white-space:pre&quot;&gt;&lt;code style=&quot;white-space:pre;font-size:inherit;font-family:inherit;line-height:1.6666666666666667;padding:8px&quot;&gt;    // Handle describes the location of a value stored within a blob file.
    type Handle struct {
      BlobFileID base.BlobFileID
      ValueLen   uint32
      // BlockID identifies the block within the blob file containing the value.
      BlockID BlockID
      // ValueID identifies the value within the block identified by BlockID.
      ValueID BlockValueID
    }&lt;/code&gt;&lt;/span&gt;&lt;button aria-label=&quot;Copy Code&quot; type=&quot;button&quot; class=&quot;sc-bdvvNz SnCde&quot;&gt;&lt;svg class=&quot;icon&quot; viewBox=&quot;0 0 384 512&quot; width=&quot;16pt&quot; height=&quot;16pt&quot; fill=&quot;#f8f8f2&quot;&gt;&lt;path d=&quot;M280 240H168c-4.4 0-8 3.6-8 8v16c0 4.4 3.6 8 8 8h112c4.4 0 8-3.6 8-8v-16c0-4.4-3.6-8-8-8zm0 96H168c-4.4 0-8 3.6-8 8v16c0 4.4 3.6 8 8 8h112c4.4 0 8-3.6 8-8v-16c0-4.4-3.6-8-8-8zM112 232c-13.3 0-24 10.7-24 24s10.7 24 24 24 24-10.7 24-24-10.7-24-24-24zm0 96c-13.3 0-24 10.7-24 24s10.7 24 24 24 24-10.7 24-24-10.7-24-24-24zM336 64h-80c0-35.3-28.7-64-64-64s-64 28.7-64 64H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM192 48c8.8 0 16 7.2 16 16s-7.2 16-16 16-16-7.2-16-16 7.2-16 16-16zm144 408c0 4.4-3.6 8-8 8H56c-4.4 0-8-3.6-8-8V120c0-4.4 3.6-8 8-8h40v32c0 8.8 7.2 16 16 16h160c8.8 0 16-7.2 16-16v-32h40c4.4 0 8 3.6 8 8v336z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;A value handle compactly describes where a reader should look to find the value. When a compaction encounters a separated value, most of the time it simply copies the value handle as-is to the new output SSTable. For large values, the value handle is orders of magnitude smaller than the value itself, and compactions that copy just the handle conserve read and write bandwidth.&lt;/p&gt;&lt;p&gt;When a reader needs to access a value, it uses the handle to load the identified file, block and finally value. This indirection introduces additional read I/O, so separating a value is a tradeoff. Infrequently retrieved values or large values are better candidates for separation. Iterators cache blob files and their blocks over the lifetime of an iterator to avoid duplicate lookups.&lt;/p&gt;&lt;h2 id=&quot;Tradeoffs&quot;&gt;&lt;b&gt;Tradeoffs&lt;/b&gt;&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;h3 id=&quot;Locality&quot;&gt;Locality&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;p&gt;When CockroachDB rewrites blob files during flushes or compactions, the process initially establishes a simple relationship: each new blob file corresponds directly to a single output SSTable. However over time, as the LSM evolves through subsequent compactions, these once clean one-to-one relationships begin to fragment. A side effect of this is that the values referenced by SSTs become increasingly scattered across more and more blob files. This loss of locality slows scans, as caching of recently accessed blob file blocks becomes less effective.&lt;/p&gt;&lt;p&gt;In order to mitigate this effect, pebble maintains a per-SSTable property called the &lt;i&gt;blob reference depth&lt;/i&gt;. The reference depth is the maximum number of blob files in the working set of a scan across an SST. For example an SST in which keys within the range &lt;code&gt;[a,f)&lt;/code&gt; reference one blob file and keys within the range &lt;code&gt;[f,z)&lt;/code&gt; reference a distinct blob file has a reference depth of 1. When a compaction’s output SSTables would have a large blob reference depth due to the increasing interleaving of blob file references, Pebble instead writes new blob files. Writing new blob files copies the referenced values to new files and results in output SSTs with a reference depth of 1 again. Bounding the reference depth bounds the overhead incurred by reads.&lt;/p&gt;&lt;h3 id=&quot;Space-Amplification&quot;&gt;Space Amplification&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;p&gt;The increasing fragmentation of references to blob files has another negative effect: space amplification. Compactions may eliminate keys that reference blob values. This occurs when a key is overwritten by a newer version or deleted by a tombstone. Additionally, when the reference depth heuristic triggers a compaction to write new blob files, the compaction eliminates references to many values in blob files at once. Over time, these effects accumulate. Each blob file increasingly consists of a mix of &lt;b&gt;live&lt;/b&gt; data: values still referenced by SSTables in the current LSM version and &lt;b&gt;dead&lt;/b&gt; data: values that have been logically deleted or superseded.&lt;/p&gt;&lt;p&gt;This gradual divergence between total blob file size and the volume of live data stored within it leads to blob file space amplification. Managing and mitigating this amplification efficiently is key to keeping storage utilization under control and maintaining predictable performance at scale. Notably, in workloads with high value homogeneity, this amplification is less pronounced because the resulting blob files and SSTables tend to compress more effectively.&lt;/p&gt;&lt;h4&gt;&lt;b&gt;Blob File Rewrites&lt;/b&gt;&lt;/h4&gt;&lt;p&gt;To keep blob file space amplification in check, Pebble introduces a new compaction type: blob file rewrite compactions. Over time, as keys are overwritten or deleted, blob files accumulate a mix of live and dead values. These rewrite compactions reclaim that space by copying only still-referenced values into new blob files.&lt;/p&gt;&lt;p&gt;Each SSTable that points to external blob values carries a small &lt;i&gt;blob-reference index block&lt;/i&gt; containing a run-length encoded bitmap per referenced blob file recording which values within a blob file are still live:&lt;/p&gt;&lt;div class=&quot;blog-codeblock mb-4 font-roboto-mono&quot;&gt;&lt;button class=&quot;w-full bg-[#6933ff] p-4 text-sm text-white hover:underline focus:outline-none&quot;&gt;Show code &lt;/button&gt;&lt;/div&gt;&lt;p&gt;When Pebble’s heuristics decide to rewrite a blob file, Pebble collects all the SSTs that reference that file and unions their bitmaps together, OR-ing them into a single view of which values remain in use. Values not referenced by any SSTable are dropped during the rewrite.&lt;/p&gt;&lt;p&gt;Blob file rewrite compactions move and reorganize values that still have outstanding references, but they do not rewrite the referencing SSTables. Doing so would be expensive and reduce the write-bandwidth savings of value separation. Instead, Pebble’s &lt;i&gt;value handles&lt;/i&gt; are designed to continue to identify the correct value across blob file rewrites through additional indirection:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;The handle’s &lt;code&gt;BlobFileID&lt;/code&gt; is a stable identifier for a logical blob file. The LSM maintains a &lt;a href=&quot;https://github.com/cockroachdb/pebble/blob/36cb7a24d3952b7e86061131d4ef4bf7e7d2fd8d/internal/manifest/blob_metadata.go#L351-L458&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;mapping&lt;/u&gt;&lt;/a&gt; from &lt;code&gt;BlobFileID&lt;/code&gt; to a physical blob file.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The handle’s &lt;code&gt;BlockID&lt;/code&gt; is an index into the original blob file’s value blocks. A blob file that is produced by a blob-file rewrite compaction includes a &lt;a href=&quot;https://github.com/cockroachdb/pebble/blob/36cb7a24d3952b7e86061131d4ef4bf7e7d2fd8d/sstable/blob/blocks.go#L141-L149&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;special column&lt;/u&gt;&lt;/a&gt; within the index block remapping the original blob file’s &lt;code&gt;BlockID&lt;/code&gt; to the index of the physical block in the rewritten blob file.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The handle’s &lt;code&gt;ValueID&lt;/code&gt; is an index into the original blob file’s value block. In order for the value index to remain correct within the rewritten blob file, we cannot remove values altogether, but we can replace them with empty values (effectively storing a single&lt;a href=&quot;https://github.com/cockroachdb/pebble/blob/36cb7a24d3952b7e86061131d4ef4bf7e7d2fd8d/sstable/colblk/raw_bytes.go#L18-L53&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt; offset , typically 2 bytes &lt;/u&gt;&lt;/a&gt;per absent value). As an additional optimization, when re-mapping the above &lt;code&gt;BlockID&lt;/code&gt;, we also include a value ID offset allowing us to avoid storing empty values for the first &lt;i&gt;n&lt;/i&gt; empty values within the block.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Blob file rewrites allow Pebble to reclaim disk space storing garbage. They prevent unreferenced data from lingering indefinitely, keeping space amplification low while preserving the performance and efficiency benefits of separating values from keys.&lt;/p&gt;&lt;h2 id=&quot;CockroachDB-separation-heuristics&quot;&gt;&lt;b&gt;CockroachDB separation heuristics&lt;/b&gt;&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;Workloads with large values reliably benefit from value separation and by default CockroachDB in v25.4+ will separate values 256 bytes and larger automatically. CockroachDB can realize benefits more broadly too. Some regions of the storage engine’s keyspace are rarely read and more latency tolerant (for example, the Raft log which is typically held in-memory until fully replicated). CockroachDB stores these values out-of-band too, even if they’re smaller than 256 bytes, thereby avoiding pulling them into compactions unnecessarily, reducing write amplification without affecting read-path latency where it matters.&lt;/p&gt;&lt;p&gt;CockroachDB uses &lt;a href=&quot;https://www.cockroachlabs.com/docs/stable/architecture/storage-layer#mvcc&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;multi-version concurrency control (MVCC)&lt;/u&gt;&lt;/a&gt; to negotiate concurrent transaction commits. MVCC preserves obsolete versions of rows for transaction isolation and powering &lt;a href=&quot;https://www.cockroachlabs.com/docs/stable/as-of-system-time&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;code&gt;&lt;u&gt;AS OF SYSTEM TIME&lt;/u&gt;&lt;/code&gt;&lt;/a&gt; (AOST) queries. In practice, most queries execute at current timestamps and only read the most recent version of a row. CockroachDB eagerly separates the values corresponding to MVCC garbage, improving the locality for reads at recent timestamps and reducing the impact of compactions through value separation. However, some nuances higher in the system currently prevent CockroachDB from fully realizing this benefit.&lt;/p&gt;&lt;p&gt;Notably, CockroachDB&#39;s SQL optimizer issues a significant number of &lt;code&gt;AS OF SYSTEM TIME&lt;/code&gt; queries to maintain accurate statistics, and these queries intentionally scan across MVCC history. As a result, these scans and their retrievals of separated values can dominate read bandwidth, offsetting much of the theoretical benefit of separating historical values. Balancing these competing behaviors – reducing unnecessary I/O while still supporting efficient AOST scans – will guide future work.&amp;nbsp;&lt;/p&gt;&lt;p&gt;The concept of blob files could also allow us to explore the idea of enabling the automatic and cost-effective placement of data onto appropriate storage tiers. Less frequently accessed data could be moved to inexpensive storage tiers by classifying it based on data age, while maintaining frequently accessed data on fast, expensive storage.&lt;/p&gt;&lt;div class=&quot;mb-8 rounded-3xl border border-solid border-[#D2D2D5] bg-[#F1F1F1] p-7&quot;&gt;&lt;h2 class=&quot;mb-4 text-display-md font-semibold text-electric-purple-500&quot;&gt;Try CockroachDB Today&lt;/h2&gt;&lt;p class=&quot;mb-4&quot;&gt;Spin up your first CockroachDB Cloud cluster in minutes. Start with $400 in free credits.
Or get a free 30-day trial of CockroachDB Enterprise on self-hosted environments.&lt;/p&gt;&lt;div&gt;&lt;a href=&quot;https://cockroachlabs.cloud/signup&quot;&gt;&lt;button class=&quot;inline-flex justify-center items-center gap-2 disabled:cursor-not-allowed border border-solid border-electric-purple-500 bg-electric-purple-500 text-white hover:bg-white hover:text-electric-purple-500 active:border-electric-purple-100 active:bg-electric-purple-100 active:text-white px-6 py-2.5 leading-tight rounded-full&quot;&gt;Try Cloud Today&lt;/button&gt;&lt;/a&gt;&lt;a href=&quot;https://cockroachlabs.cloud/signup?experience=enterprise&quot;&gt;&lt;button class=&quot;inline-flex justify-center items-center gap-2 disabled:cursor-not-allowed border border-solid border-electric-purple-500 bg-electric-purple-500 text-white hover:bg-white hover:text-electric-purple-500 active:border-electric-purple-100 active:bg-electric-purple-100 active:text-white px-6 py-2.5 leading-tight rounded-full&quot;&gt;Try Self-Hosted Today&lt;/button&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;</description><link>https://www.cockroachlabs.com/blog/value-separation-pebble-optimization/</link><guid isPermaLink="false">https://www.cockroachlabs.com/blog/value-separation-pebble-optimization/</guid></item><item><title>Real-Time Indexing for Billions of Vectors: How we built fast, fresh vector indexing at scale in CockroachDB</title><description>&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/43s7L8XHxSh23lJa12LLmh/81d1a7c3a5c55937f4e3be631c2c6a77/Cockroach_Labs_Vector_Search_AI_workflow.png&quot;&gt;&lt;img alt=&quot;A simple diagram demonstrating CockroachDB&#39;s Vector Search function.&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1080&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/43s7L8XHxSh23lJa12LLmh/81d1a7c3a5c55937f4e3be631c2c6a77/Cockroach_Labs_Vector_Search_AI_workflow.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;In a past life, I worked on an app that let users upload and share photos with friends and family. I’m amazed at how far technology has progressed since that time. It feels like magic that AI can “look” at a set of photos and “know” that they were taken at a child’s first birthday party or on a hike in the mountains. Natural language queries like &lt;i&gt;“show me photos from my trip to the Statue of Liberty”&lt;/i&gt; or even &lt;i&gt;“find that photo where I’m about to collide on the soccer field with another player”&lt;/i&gt; are no longer science fiction.&lt;/p&gt;&lt;p&gt;Our photo-sharing startup never reached millions of users, but I suspect that many of you reading this are working on systems that have. At that scale, it’s surprisingly easy to find yourself managing billions, or even tens of billions of user-generated items. If it’s a photo app, most users will have hundreds or thousands of photos. Power users or organizations might have tens or hundreds of thousands. If it’s not photos, it might be documents, notes, videos, or audio. The type of content varies, but the math is the same: millions of users, each contributing hundreds or thousands of items, and you’re quickly operating at billions-scale.&lt;/p&gt;&lt;p&gt;Even with just a few hundred items, users expect fast, accurate search. If they upload something, they want to find it immediately. If they search, they want results in the blink of an eye. Increasingly, basic keyword search isn’t enough. In the age of ChatGPT, users expect &lt;i&gt;semantic&lt;/i&gt; search, with results based on the &lt;i&gt;meaning&lt;/i&gt; of the content, not just filenames, metadata, keywords, or tags.&lt;/p&gt;&lt;p&gt;Some solutions to this problem assume that the entire dataset fits into memory on a single machine. Or, at most, they rely on a fast local SSD. Many of them don’t expect your data to be distributed across regions, or to be constantly changing, or to be part of a transactional system where consistency and freshness actually matter. They often come with significant limitations, like requiring writes to be batched, returning stale results, or needing specialized hardware to perform well.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.cockroachlabs.com/product/overview/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;CockroachDB&lt;/u&gt;&lt;/a&gt; was built with a different set of assumptions. As a distributed database, it expects data to live across multiple machines, which may span availability zones or even regions. It’s designed to scale linearly, so that adding more machines leads to proportionally higher throughput. And as a transactional SQL database, it prioritizes returning fresh data and supporting real-time updates. All of that has to be resilient to machine, disk, and network failures.&lt;/p&gt;&lt;p&gt;Read on to learn how we combined recent academic research with practical engineering to solve the semantic search problem at massive scale, with fresh, real-time results, by leveraging CockroachDB’s unique distributed architecture.&lt;/p&gt;&lt;h2 id=&quot;Embedding-Meaning-into-Vectors&quot;&gt;Embedding Meaning into Vectors&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;To start, it’s important to understand how systems can make sense of photos or search documents by meaning. Companies like &lt;a href=&quot;https://www.cockroachlabs.com/blog/openai-iam-architecture-ory-cockroachdb/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;OpenAI&lt;/u&gt;&lt;/a&gt; offer &lt;i&gt;embedding&lt;/i&gt; models that convert an image, document, or other media into a long list of floating-point numbers – a vector – that captures its meaning. If two photos or documents are similar, say two beach photos, they’ll be mapped to vectors that are near each other in high-dimensional space.&lt;/p&gt;&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/1prH0d8BALwMReMnu93lit/28faf7fefcfc05d7ff9fc45a82e861b3/example-vector-space.png&quot;&gt;&lt;img alt=&quot;An illustration of a multi-dimensional vector space with the following terms: wolf, dog, cat, banana, apple.&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1170&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/1prH0d8BALwMReMnu93lit/28faf7fefcfc05d7ff9fc45a82e861b3/example-vector-space.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Embedding meaning into vectors reduces complex problems like image recognition and semantic search into a simpler one: finding nearby vectors. These models are built on the same deep learning techniques that power systems like &lt;a href=&quot;https://www.cockroachlabs.com/blog/openai-modern-iam-cockroachdb-ory/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;ChatGPT&lt;/u&gt;&lt;/a&gt; – large neural networks trained to capture meaning and context across many kinds of data.&lt;/p&gt;&lt;p&gt;This even works across media types. Multimodal models embed text and images into the same vector space. So the word “beach” and an actual beach photo end up in the same region. When a user types “beach,” we can embed that query into a vector and search for nearby photo vectors. The closest matches are very likely to be related to the beach.&lt;/p&gt;&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/70SjGpVnBJ8rcDKX6ytOeG/c0011c3552bb8380297c53fd4fce1e6b/Illustration_of_the_output_of_embedding_models.png&quot;&gt;&lt;img alt=&quot;Left column: photo, audio, text. Middle column: embedding model. Right column: embedding vectors.&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1200&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/70SjGpVnBJ8rcDKX6ytOeG/c0011c3552bb8380297c53fd4fce1e6b/Illustration_of_the_output_of_embedding_models.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;How-Meaning-is-Indexed&quot;&gt;How Meaning is Indexed&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;Embedding vectors often have hundreds or thousands of dimensions that allow them to represent complex meaning. But that also makes them hard to search. Think about it: should beach photos come before or after food photos? What about photos of food at the beach? There’s no natural ordering for multi-dimensional vectors, the way there is for numbers or strings. That means traditional indexes don’t apply.&lt;/p&gt;&lt;p&gt;Instead of scanning for exact matches, semantic queries need to find vectors that are &lt;i&gt;nearby&lt;/i&gt; in multi-dimensional space. At a small scale, brute-force search is often good enough – you can scan the dataset, compute distances, and return the closest matches. But as the number of vectors grows into the tens of thousands or beyond, that approach quickly becomes too slow to be practical.&lt;/p&gt;&lt;p&gt;Vector indexes address this by efficiently finding &lt;i&gt;approximate&lt;/i&gt; nearest neighbors. These indexes trade a small amount of accuracy for a large gain in performance. While they don’t guarantee that the exact nearest vectors will be returned, the results are close enough to be useful, and the performance benefits make real-time search possible at scale.&lt;/p&gt;&lt;h2 id=&quot;Adapting-Vector-Indexing-Algorithms-for-Distributed-SQL&quot;&gt;Adapting Vector Indexing Algorithms for Distributed SQL&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;Even with a good vector indexing algorithm, plugging it into a distributed SQL database like CockroachDB isn’t straightforward. To support elastic scale, fault tolerance, and multi-region availability, any indexing algorithm needs to follow a set of architectural rules:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;No central coordinator.&lt;/b&gt; Any node in the cluster should be able to serve reads and writes. The index can’t rely on a single leader to coordinate queries or updates.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;No large in-memory structures.&lt;/b&gt; Index state must live in persistent storage. We can’t assume every node has gigabytes of RAM available for caching vectors, and we want to avoid long warm-up times spent building large in-memory structures. This is especially important for Serverless deployments.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Minimal network hops.&lt;/b&gt; Cross-node round-trips are expensive. Indexes that require sequential traversal across nodes can accumulate latency quickly and make performance unpredictable.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Sharding-compatible layout.&lt;/b&gt; Index data must map naturally to CockroachDB’s key-value ranges so it can be split, merged, and rebalanced like any other data.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;No hot spots.&lt;/b&gt; As vector inserts and queries scale up, the index must avoid concentrating traffic on a single node or range. Load should be balanced across the cluster.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Incremental updates.&lt;/b&gt; The index must handle inserts and deletes in real time, without blocking queries, requiring large rebuilds, or hurting search quality.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;These constraints ruled out many common approaches. We needed something that fit cleanly into CockroachDB’s execution model and harnessed the power of its distributed architecture. That’s where C-SPANN comes in.&lt;/p&gt;&lt;h2 id=&quot;Introducing-C-SPANN&quot;&gt;Introducing C-SPANN&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;C-SPANN, short for CockroachDB SPANN, is a vector indexing algorithm that incorporates ideas from Microsoft’s &lt;a href=&quot;https://www.microsoft.com/en-us/research/wp-content/uploads/2021/11/SPANN_finalversion1.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;SPANN&lt;/u&gt;&lt;/a&gt; and &lt;a href=&quot;https://www.microsoft.com/en-us/research/publication/spfresh-incremental-in-place-update-for-billion-scale-vector-search/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;SPFresh&lt;/u&gt;&lt;/a&gt; papers, as well as Google’s ScaNN project.&lt;/p&gt;&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/1usMrgsU8zscQFSTLvfecm/d9ba9cd581ea2c48c096bcc269178bb4/research-before-cockroach-spann-cspann.png&quot;&gt;&lt;img alt=&quot;A diagram showing that C-SPANN, short for CockroachDB SPANN, is a vector indexing algorithm that incorporates ideas from Microsoft’s SPANN and SPFresh papers, as well as Google’s ScaNN project.&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1200&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/1usMrgsU8zscQFSTLvfecm/d9ba9cd581ea2c48c096bcc269178bb4/research-before-cockroach-spann-cspann.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;At the core of C-SPANN is a &lt;i&gt;hierarchical K-means tree&lt;/i&gt;. Vectors are grouped into partitions based on similarity, with each partition containing anywhere from dozens to hundreds of vectors. Each partition has a centroid, which is the average of the vectors it contains, representing their “center of mass”. Those centroids are recursively clustered into higher-level partitions, forming a tree that efficiently narrows the search space.&lt;/p&gt;&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/7MgxZ9L711btb1evJ6Su03/59fca894ab1a60fbc0b0622fd615bdc2/k-means-tree-powering-cspann-cockroachdb-vector-indexing.png&quot;&gt;&lt;img alt=&quot;The core data structure powering C-SPANN is the K-means tree. Within the tree, vectors are grouped into partitions, which can contain anywhere from dozens to hundreds of vectors. Each partition has a centroid vector, which is the average of the vectors in that partition, and represents their “center of mass”.&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1171&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/7MgxZ9L711btb1evJ6Su03/59fca894ab1a60fbc0b0622fd615bdc2/k-means-tree-powering-cspann-cockroachdb-vector-indexing.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Each partition is stored as a self-contained unit in CockroachDB’s key-value layer, making the index naturally sharding-compatible. Partition data is laid out as a contiguous set of key-value rows within a CockroachDB range. As partitions are added, removed, or grow in size, the underlying ranges can be automatically split, merged, and rebalanced by the database, just like any other table data.&lt;/p&gt;&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/39XWBxQXfWU1jCmy4VNRAh/8bcfbca5006a19aebbda23c3aec5c014/partitions-cockroachdb-nodes.png&quot;&gt;&lt;img alt=&quot;Each partition is stored as a self-contained unit in CockroachDB’s key-value layer, making the index naturally sharding-compatible. Partition data is laid out as a contiguous set of key-value rows within a CockroachDB range. As partitions are added, removed, or grow in size, the underlying ranges can be automatically split, merged, and rebalanced by the database, just like any other table data.&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;914&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/39XWBxQXfWU1jCmy4VNRAh/8bcfbca5006a19aebbda23c3aec5c014/partitions-cockroachdb-nodes.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;At query time, the search starts at the root of the tree. We compare the query vector to the centroids at that level, then descend into the partitions with the closest matches. This process repeats at each level until we reach the leaves, where we scan a small number of candidate vectors. Partitions at each level can be processed in parallel, helping to reduce latency. And because vectors within a partition are packed together and are similar by design, we can take advantage of SIMD CPU instructions to efficiently scan blocks of vectors.&lt;/p&gt;&lt;p&gt;Because the tree fanout is typically around 100, the structure remains wide and shallow. This keeps the number of levels (and therefore the number of network round-trips) small and predictable, even at large scale. An index with 1 million vectors requires just 3 levels; even one with 10 billion vectors needs only 5 levels. To reduce round-trips even further, the root partition can be cached in memory.&lt;/p&gt;&lt;p&gt;C-SPANN also avoids central coordination. Any node can serve queries or handle inserts and updates. The index structure lives in persistent storage, so there’s no need for large in-memory vector caches or custom data structures that must be rebuilt at startup. Instead, partition rows are cached automatically by the storage layer’s block cache, just like any other table data. This allows searches to avoid repeated disk reads, without requiring extra RAM or specialized vector caching logic.&lt;/p&gt;&lt;p&gt;Check out this demo by technical evangelist, Rob Reid, to see vector indexing in action:&lt;/p&gt;&lt;p&gt;&lt;!--$!--&gt;&lt;template data-dgst=&quot;BAILOUT_TO_CLIENT_SIDE_RENDERING&quot;&gt;&lt;/template&gt;&lt;!--/$--&gt;&lt;/p&gt;&lt;h2 id=&quot;Maintaining-a-Healthy-Index&quot;&gt;Maintaining a Healthy Index&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;As new vectors are inserted into the index, they naturally scatter across partitions, which are themselves distributed across the cluster. There’s no single range or node that absorbs a disproportionate share of the write traffic, which helps to prevent hot spots from forming. But over time, some partitions will grow too large and need to be split.&lt;/p&gt;&lt;p&gt;Splits happen automatically in the background to reduce impact on foreground transactions. When a split is triggered, the vectors in the original partition are divided into two roughly equal groups using a balanced variant of the K-means algorithm. Each group becomes a new, more tightly clustered partition with its own centroid. The tree is updated to reflect this change, and future inserts are routed to the new partitions based on proximity to these new centroids. Here’s an example where partition 4 is replaced by partitions 5 and 6 at the leaf level of the tree:&lt;/p&gt;&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/4GCOAven5TfAqtk6Bm3rdZ/cce87b367e800a5b64e23ea03d84d0fc/example-partition-replacement.png&quot;&gt;&lt;img alt=&quot;Here’s an example where partition 4 is replaced by partitions 5 and 6 at the leaf level of the tree. Splits happen automatically in the background to reduce impact on foreground transactions. When a split is triggered, the vectors in the original partition are divided into two roughly equal groups using a balanced variant of the K-means algorithm. Each group becomes a new, more tightly clustered partition with its own centroid. The tree is updated to reflect this change, and future inserts are routed to the new partitions based on proximity to these new centroids.&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1253&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/4GCOAven5TfAqtk6Bm3rdZ/cce87b367e800a5b64e23ea03d84d0fc/example-partition-replacement.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;It’s also worth noting that partition splits are distinct from CockroachDB’s range splits, though the two work together to ensure scalability and consistent performance. A partition is a logical unit within the index that groups similar vectors. A range is a physical unit of storage in the key-value layer. Splitting a partition improves search efficiency by maintaining tight clustering of vectors. Splitting a range helps balance data storage and access across the cluster. Together, these mechanisms reduce hot spots and help spread both query and insert load more evenly. When nodes are added to the system, ranges containing index partitions are automatically distributed across the new nodes, allowing the total workload to scale out with the cluster at near-linear rates.&lt;/p&gt;&lt;p&gt;There’s one wrinkle worth noting: some vectors may no longer be in the “right” partition after a split. A vector in the splitting partition might be closer to a nearby partition’s centroid than to either of the new centroids. Likewise, a vector in a nearby partition might now be closer to one of the new centroids. In both cases, vectors need to be relocated to the partition with the closest centroid. To see how this can happen, consider these red and blue clusters (centroids are marked with X):&lt;/p&gt;&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/3V5eSYixfR41R3p22DCp1L/bddf488911ecf878ff405d6623066dc4/partition-split-relocation.png&quot;&gt;&lt;img alt=&quot;Some vectors may no longer be in the “right” partition after a split. A vector in the splitting partition might be closer to a nearby partition’s centroid than to either of the new centroids. Likewise, a vector in a nearby partition might now be closer to one of the new centroids. In both cases, vectors need to be relocated to the partition with the closest centroid. After the blue cluster is split, one of its vectors is reassigned to the red cluster because it’s now closer to the red centroid than to either of the new blue centroids. Similarly, one of the red vectors is reassigned to the righthand blue cluster for the same reason. Relocating vectors based on updated proximity is introduced in the SPFresh paper (as part of ensuring “nearest partition assignment”) and plays a key role in maintaining high clustering accuracy after splits.&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;927&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/3V5eSYixfR41R3p22DCp1L/bddf488911ecf878ff405d6623066dc4/partition-split-relocation.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;After the blue cluster is split, one of its vectors is reassigned to the red cluster because it’s now closer to the red centroid than to either of the new blue centroids. Similarly, one of the red vectors is reassigned to the righthand blue cluster for the same reason. Relocating vectors based on updated proximity is introduced in the SPFresh paper (as part of ensuring “nearest partition assignment”) and plays a key role in maintaining high clustering accuracy after splits.&lt;/p&gt;&lt;p&gt;While splits ensure that partitions don’t grow too large, merges ensure they don’t shrink too small. If vectors are deleted or moved such that a partition falls below the minimum size, a background process merges it away. Its vectors are reassigned to nearby partitions, and the original partition is removed from the tree.&lt;/p&gt;&lt;p&gt;Taken together, splits, merges, and partition reassignments are highly effective at preserving index accuracy, even after many cycles of vector inserts, updates, and deletes. In fact, the approach works so well that there&#39;s not a lot to gain from rebuilding the index after adding new data. You can start with an empty table, insert millions of vectors, and still get high accuracy. The index adapts rapidly and dynamically as the data evolves, keeping itself balanced and efficient over time.&lt;/p&gt;&lt;h2 id=&quot;Reducing-Index-Size-by-94%&quot;&gt;Reducing Index Size by 94%&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;Full-precision vectors are expensive. OpenAI embeddings, for example, use 1,536 dimensions with 2-byte floats, which comes out to about 3 KB per vector. Multiply that by millions of vectors, and the index size adds up quickly. Storage is one cost, but often the greater expense is the CPU and memory required to load and scan full vectors during index searches.&lt;/p&gt;&lt;p&gt;To reduce this overhead, C-SPANN uses a technique called &lt;i&gt;quantization&lt;/i&gt; to compress the vectors stored in the index. Instead of storing full vectors, it stores compact binary representations that approximate the originals. During search, distances are computed using these quantized forms, which are both smaller and faster to scan.&lt;/p&gt;&lt;p&gt;While many quantization algorithms exist, we use one called RaBitQ, which reduces each vector dimension to a single bit. It stores those bits along with a few precomputed values per vector, achieving roughly a 94% reduction in size for common cases. In the OpenAI embedding example, that shrinks a vector from about 3 KB to only around 200 bytes.&lt;/p&gt;&lt;p&gt;This approach integrates naturally with the K-means tree: each vector is quantized relative to the centroid of the partition it belongs to, allowing for tighter grouping and better accuracy. Because quantization is local to each partition, splits and merges only require re-quantizing the vectors within the affected partition. This enables the index to evolve incrementally and locally, without centralized coordination or global retraining.&lt;/p&gt;&lt;p&gt;While I won’t dive into every detail, I want to show you how beautiful and simple the core RaBitQ algorithm is. Each data vector is first “mixed” with a random orthogonal transform, which spreads any data skew more evenly across dimensions while still preserving angles and distances. It’s then mean-centered with respect to the partition centroid and normalized to unit length. Finally, each dimension is converted to a bit: zero if the value is less than zero, one otherwise.&lt;/p&gt;&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/3pw1IYPSzRZOHg3rAN7Fa5/af2c5be42d3ae4759abf296a6cd56aeb/rabitq-quantization.png&quot;&gt;&lt;img alt=&quot;Graphs illustrating RaBitQ quantization.&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1830&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/3pw1IYPSzRZOHg3rAN7Fa5/af2c5be42d3ae4759abf296a6cd56aeb/rabitq-quantization.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The result is a string of bits that captures the essence of the original vector in highly compressed form. These bits are stored alongside the dot product between the quantized and original vectors, as well as the exact distance of the original vector from the centroid. Remarkably, that’s enough to estimate distances with reasonable accuracy. To make distance comparisons fast as well as compact, RaBitQ uses a different quantization method for the query vector that assigns 4 bits per dimension and is optimized for SIMD instructions.&lt;/p&gt;&lt;p&gt;Since quantization is lossy, these distance estimates are only approximate. To correct for this, C-SPANN includes a reranking step. We scan quantized vectors to build a candidate set, then fetch the original full vectors from the table to re-compute exact distances. By over-fetching candidate vectors, we can compensate for quantization error. RaBitQ provides error bounds that help determine how many extra vectors are needed to find the true nearest neighbors with high probability.&lt;/p&gt;&lt;p&gt;The result is the best of both worlds: fast, compact scans with accurate results.&lt;/p&gt;&lt;h2 id=&quot;An-Index-for-Every-User&quot;&gt;An Index for Every User&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;I’ve explained how C-SPANN can cluster vast numbers of vectors and keep the index fresh with real-time, incremental updates. But there’s a further twist to the story. In most real-world applications, those vectors belong to someone, whether it be a user, a customer, a tenant, or some other owner. And most queries are scoped to just that one owner. In fact, including vectors from other owners could be a security issue.&lt;/p&gt;&lt;p&gt;CockroachDB vector indexes handle this cleanly by supporting &lt;i&gt;prefix columns&lt;/i&gt;, which allow the index to be partitioned by ownership (or anything else). Here’s a simple example:&lt;/p&gt;&lt;div class=&quot;blog-codeblock mb-4 font-roboto-mono&quot;&gt;&lt;div class=&quot; [&amp;amp;&gt;div&gt;span&gt;code]:bg-transparent [&amp;amp;&gt;div&gt;span&gt;code]:text-white&quot;&gt;&lt;div class=&quot;sc-gsDLFA oicjj&quot;&gt;&lt;span style=&quot;font-size:inherit;font-family:inherit;background:#282a36;color:#f8f8f2;border-radius:3px;display:flex;line-height:1.4285714285714286;overflow-x:auto;white-space:pre&quot;&gt;&lt;code style=&quot;white-space:pre;font-size:inherit;font-family:inherit;line-height:1.6666666666666667;padding:8px&quot;&gt;CREATE TABLE photos (
  id UUID PRIMARY KEY,
  user_id UUID,
  embedding VECTOR(1536),
  VECTOR INDEX (user_id, embedding)
);&lt;/code&gt;&lt;/span&gt;&lt;button aria-label=&quot;Copy Code&quot; type=&quot;button&quot; class=&quot;sc-bdvvNz SnCde&quot;&gt;&lt;svg class=&quot;icon&quot; viewBox=&quot;0 0 384 512&quot; width=&quot;16pt&quot; height=&quot;16pt&quot; fill=&quot;#f8f8f2&quot;&gt;&lt;path d=&quot;M280 240H168c-4.4 0-8 3.6-8 8v16c0 4.4 3.6 8 8 8h112c4.4 0 8-3.6 8-8v-16c0-4.4-3.6-8-8-8zm0 96H168c-4.4 0-8 3.6-8 8v16c0 4.4 3.6 8 8 8h112c4.4 0 8-3.6 8-8v-16c0-4.4-3.6-8-8-8zM112 232c-13.3 0-24 10.7-24 24s10.7 24 24 24 24-10.7 24-24-10.7-24-24-24zm0 96c-13.3 0-24 10.7-24 24s10.7 24 24 24 24-10.7 24-24-10.7-24-24-24zM336 64h-80c0-35.3-28.7-64-64-64s-64 28.7-64 64H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM192 48c8.8 0 16 7.2 16 16s-7.2 16-16 16-16-7.2-16-16 7.2-16 16-16zm144 408c0 4.4-3.6 8-8 8H56c-4.4 0-8-3.6-8-8V120c0-4.4 3.6-8 8-8h40v32c0 8.8 7.2 16 16 16h160c8.8 0 16-7.2 16-16v-32h40c4.4 0 8 3.6 8 8v336z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;In this case, the vector index is partitioned by the leading &lt;code&gt;user_id&lt;/code&gt; column. That means photo embeddings are indexed and searched &lt;i&gt;per user&lt;/i&gt;. Here’s a query that finds the 10 closest photos for a given user, using &lt;code&gt;pgvector&lt;/code&gt; compatible syntax:&lt;/p&gt;&lt;div class=&quot;blog-codeblock mb-4 font-roboto-mono&quot;&gt;&lt;div class=&quot; [&amp;amp;&gt;div&gt;span&gt;code]:bg-transparent [&amp;amp;&gt;div&gt;span&gt;code]:text-white&quot;&gt;&lt;div class=&quot;sc-gsDLFA oicjj&quot;&gt;&lt;span style=&quot;font-size:inherit;font-family:inherit;background:#282a36;color:#f8f8f2;border-radius:3px;display:flex;line-height:1.4285714285714286;overflow-x:auto;white-space:pre&quot;&gt;&lt;code style=&quot;white-space:pre;font-size:inherit;font-family:inherit;line-height:1.6666666666666667;padding:8px&quot;&gt;SELECT id
FROM photos
WHERE user_id = $1
ORDER BY embedding &amp;lt;-&amp;gt; $2
LIMIT 10&lt;/code&gt;&lt;/span&gt;&lt;button aria-label=&quot;Copy Code&quot; type=&quot;button&quot; class=&quot;sc-bdvvNz SnCde&quot;&gt;&lt;svg class=&quot;icon&quot; viewBox=&quot;0 0 384 512&quot; width=&quot;16pt&quot; height=&quot;16pt&quot; fill=&quot;#f8f8f2&quot;&gt;&lt;path d=&quot;M280 240H168c-4.4 0-8 3.6-8 8v16c0 4.4 3.6 8 8 8h112c4.4 0 8-3.6 8-8v-16c0-4.4-3.6-8-8-8zm0 96H168c-4.4 0-8 3.6-8 8v16c0 4.4 3.6 8 8 8h112c4.4 0 8-3.6 8-8v-16c0-4.4-3.6-8-8-8zM112 232c-13.3 0-24 10.7-24 24s10.7 24 24 24 24-10.7 24-24-10.7-24-24-24zm0 96c-13.3 0-24 10.7-24 24s10.7 24 24 24 24-10.7 24-24-10.7-24-24-24zM336 64h-80c0-35.3-28.7-64-64-64s-64 28.7-64 64H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM192 48c8.8 0 16 7.2 16 16s-7.2 16-16 16-16-7.2-16-16 7.2-16 16-16zm144 408c0 4.4-3.6 8-8 8H56c-4.4 0-8-3.6-8-8V120c0-4.4 3.6-8 8-8h40v32c0 8.8 7.2 16 16 16h160c8.8 0 16-7.2 16-16v-32h40c4.4 0 8 3.6 8 8v336z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Even if the index contains billions of photos, this query will only search the subset that belongs to one user. Performance for inserts and searches is proportional to the number of vectors owned by that user, not the total number of vectors in the system. Contention between users is minimized, since queries don’t touch the same index partitions or rows.&lt;/p&gt;&lt;p&gt;Behind the scenes, the index maintains a separate K-means tree for each distinct user. From the system’s perspective, there isn’t much difference between 1 billion vectors arranged in a single tree or the same number spread across a million smaller trees. Vectors are still assigned to partitions and packed into ranges in the CockroachDB key-value layer. Those ranges are automatically split, merged, and distributed across nodes, just like any other data, enabling near-linear scaling as usage grows.&lt;/p&gt;&lt;h2 id=&quot;Users-in-Every-Region&quot;&gt;Users in Every Region&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;Prefix columns become even more powerful when used with CockroachDB’s multi-region features. For example, you can use a &lt;a href=&quot;https://www.cockroachlabs.com/docs/stable/table-localities.html#regional-by-row-tables&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;&lt;code&gt;REGIONAL BY ROW&lt;/code&gt;&lt;/u&gt;&lt;/a&gt; table to store each user&#39;s data in their home region, which reduces latency and helps meet data domiciling requirements:&lt;/p&gt;&lt;div class=&quot;blog-codeblock mb-4 font-roboto-mono&quot;&gt;&lt;button class=&quot;w-full bg-[#6933ff] p-4 text-sm text-white hover:underline focus:outline-none&quot;&gt;Show code &lt;/button&gt;&lt;/div&gt;&lt;p&gt;This statement automatically adds a &lt;code&gt;crdb_region&lt;/code&gt; column to the table, which is included in the vector index alongside &lt;code&gt;user_id&lt;/code&gt; and &lt;code&gt;embedding&lt;/code&gt;. This ensures that both table and index rows are co-located in the region specified by each row’s &lt;code&gt;crdb_region&lt;/code&gt; value. Photos for a user in Europe will be stored in Europe, with fast, local access from that region. Photos for a user in the US will be stored in the US, with equally low-latency access there. The combination of &lt;code&gt;crdb_region&lt;/code&gt; and &lt;code&gt;user_id&lt;/code&gt; as prefix columns partitions the index by both location and ownership, making it efficient, secure, and locality-aware by default.&lt;/p&gt;&lt;h2 id=&quot;Future-Work&quot;&gt;Future Work&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;We released a preview of vector indexing in our 25.2 release. It includes all of the core functionality described above, but several optimizations are still underway to improve accuracy and performance. Merge operations and partition reassignments are not yet fully implemented. Root partition caching and expanded use of SIMD instructions will help speed up both searches and inserts. We&#39;re also working to minimize contention between foreground queries and background operations like splits and merges.&lt;/p&gt;&lt;p&gt;On the functionality side, we plan to expand support for &lt;code&gt;IMPORT&lt;/code&gt;,&amp;nbsp; &lt;code&gt;ALTER INDEX&lt;/code&gt; and additional distance metrics. The current implementation supports Euclidean distance, and we’re actively working to add support for cosine and inner product as well. And while the current implementation can leverage the vector index when filtering on prefix columns, we’re aiming to support a wider range of &lt;code&gt;WHERE&lt;/code&gt; clause filter patterns in future releases.&lt;/p&gt;&lt;p&gt;If you&#39;re working with a large number of vectors, need to support high QPS, fresh results, geo-locality, high-availability, or anything else discussed here, we&#39;d love to hear from you. Your use case could help shape our future roadmap.&lt;/p&gt;&lt;div class=&quot;mb-8 rounded-3xl border border-solid border-[#D2D2D5] bg-[#F1F1F1] p-7&quot;&gt;&lt;h2 class=&quot;mb-4 text-display-md font-semibold text-electric-purple-500&quot;&gt;Try CockroachDB Today&lt;/h2&gt;&lt;p class=&quot;mb-4&quot;&gt;Spin up your first CockroachDB Cloud cluster in minutes. Start with $400 in free credits.
Or get a free 30-day trial of CockroachDB Enterprise on self-hosted environments.&lt;/p&gt;&lt;div&gt;&lt;a href=&quot;https://cockroachlabs.cloud/signup&quot;&gt;&lt;button class=&quot;inline-flex justify-center items-center gap-2 disabled:cursor-not-allowed border border-solid border-electric-purple-500 bg-electric-purple-500 text-white hover:bg-white hover:text-electric-purple-500 active:border-electric-purple-100 active:bg-electric-purple-100 active:text-white px-6 py-2.5 leading-tight rounded-full&quot;&gt;Try Cloud Today&lt;/button&gt;&lt;/a&gt;&lt;a href=&quot;https://cockroachlabs.cloud/signup?experience=enterprise&quot;&gt;&lt;button class=&quot;inline-flex justify-center items-center gap-2 disabled:cursor-not-allowed border border-solid border-electric-purple-500 bg-electric-purple-500 text-white hover:bg-white hover:text-electric-purple-500 active:border-electric-purple-100 active:bg-electric-purple-100 active:text-white px-6 py-2.5 leading-tight rounded-full&quot;&gt;Try Self-Hosted Today&lt;/button&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;</description><link>https://www.cockroachlabs.com/blog/cspann-real-time-indexing-billions-vectors/</link><guid isPermaLink="false">https://www.cockroachlabs.com/blog/cspann-real-time-indexing-billions-vectors/</guid></item><item><title>Tutorial: Augment your AI use case with RAG on CockroachDB</title><description>&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/5eg3ErfcPE72PL3CXz9byw/6ce4816fce53b0d3f79bb5686f881775/cockroachdb-ai-use-case-rag-chatbot.png&quot;&gt;&lt;img alt=&quot;A text editor with a chat bubble that has three dots and a chat bubble with &amp;quot;AI.&amp;quot;&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1211&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/5eg3ErfcPE72PL3CXz9byw/6ce4816fce53b0d3f79bb5686f881775/cockroachdb-ai-use-case-rag-chatbot.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;With the rise of AI across industries, it’s becoming more &lt;a href=&quot;https://www.nytimes.com/2025/05/05/technology/ai-hallucinations-chatgpt-google.html&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;important to address&lt;/u&gt;&lt;/a&gt; the limitations of LLMs. One increasingly popular method is &lt;a href=&quot;https://arxiv.org/abs/2005.11401&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;Retrieval Augmented Generation (RAG)&lt;/u&gt;&lt;/a&gt;, which allows you to provide external knowledge sources as context to Large Language Models (LLMs).&amp;nbsp;&lt;/p&gt;&lt;p&gt;In this blog post, we dive into the significance and benefits of RAG applications first. Then we explore the advantages of leveraging &lt;a href=&quot;https://www.cockroachlabs.com/product/overview/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;CockroachDB&lt;/u&gt;&lt;/a&gt;, a highly scalable and resilient distributed SQL database, as the foundation for building efficient and robust RAG applications. To illustrate the practical implementation, I’ve created a knowledge base chatbot. Readers will experience a clear walkthrough of the application&#39;s operation via an interactive demo, gaining insights into how CockroachDB &lt;a href=&quot;https://www.cockroachlabs.com/blog/vector-search-pgvector-cockroachdb/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;vector search&lt;/u&gt;&lt;/a&gt; seamlessly integrates with LLM APIs to ensure real-time, contextualized responses. Finally, we&#39;ll summarize key takeaways and highlight why CockroachDB provides an ideal backend for modern RAG-powered applications.&lt;/p&gt;&lt;h2 id=&quot;What-is-Retrieval-Augmented-Generation-(RAG)?-How-does-RAG-improve-LLMs?&quot;&gt;What is Retrieval Augmented Generation (RAG)? How does RAG improve LLMs?&amp;nbsp;&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;Large Language Models (LLMs) bring tremendous knowledge and creativity, enabling groundbreaking capabilities in generating human-like text and automating numerous tasks. However, despite being trained on massive datasets, these models often exhibit limitations when dealing with specific domain knowledge or real-time personalized transactional information. As seen online, LLMs can generate inaccuracies or completely fabricated information—a phenomenon known as “hallucinations.” Hallucinations occur when an LLM generates plausible-sounding but factually incorrect or entirely fabricated statements.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Retrieval Augmented Generation (RAG) addresses this critical challenge by introducing grounded data, meaning responses are directly supported by accurate and relevant information. Instead of solely relying on the model’s pre-trained knowledge, RAG first queries a specialized database containing domain-specific knowledge to identify the most relevant and update-to-date information. This retrieved context is then fed back into the LLM, enabling the generation of precise, trustworthy answers based on verified data rather than ungrounded predictions.&lt;/p&gt;&lt;h2 id=&quot;Retrieval-Augmented-Generation-(RAG)-Use-Cases&quot;&gt;Retrieval Augmented Generation (RAG) Use Cases&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;There is a lot of potential for RAG in a variety of industries. Here are just a few:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;For example businesses utilize RAG applications to enhance knowledge base queries, allowing employees to rapidly access relevant, domain-specific insights, which boosts productivity and supports informed decision-making.&amp;nbsp;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;RAG facilitates real-time information retrieval within enterprise applications, enabling immediate access to critical, up-to-date information, which is essential for operations like risk assessment, financial analytics, and strategic planning.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;In customer support&lt;b&gt; &lt;/b&gt;scenarios, RAG empowers chatbots to deliver accurate, context-aware answers, substantially enhancing user satisfaction and reducing response times by grounding the LLM in a database of customer support documentation.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;For content generation tasks, such as marketing copy or technical documentation, RAG leverages verified sources to ensure the content is factual, consistent, and aligns closely with organizational guidelines.&amp;nbsp;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;Why-Build-a-RAG-Application-on-CockroachDB&quot;&gt;Why Build a RAG Application on CockroachDB&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;&lt;!--$!--&gt;&lt;template data-dgst=&quot;BAILOUT_TO_CLIENT_SIDE_RENDERING&quot;&gt;&lt;/template&gt;&lt;!--/$--&gt;&lt;/p&gt;&lt;h3 id=&quot;Unified-Storage-of-Source-Data,-Metadata,-and-Vector-Data&quot;&gt;Unified Storage of Source Data, Metadata, and Vector Data&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;p&gt;CockroachDB enables the storage of source data, &lt;a href=&quot;https://www.cockroachlabs.com/solutions/usecases/user-accounts-and-metadata/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;metadata&lt;/u&gt;&lt;/a&gt;, and &lt;a href=&quot;https://www.cockroachlabs.com/docs/stable/vector&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;vector embeddings&lt;/u&gt;&lt;/a&gt; within the same database, significantly simplifying data management, lowering cost, and improving performance for RAG applications. This unified storage approach allows vectors and their corresponding source data to be updated simultaneously, providing immediate, real-time access to the latest information without the delays associated with multi-database architectures.&amp;nbsp;&lt;/p&gt;&lt;p&gt;When vector data and source data reside in separate systems it requires additional pipelines and frequent synchronization efforts. Such systems often suffer from latency and inconsistency, leading to outdated vector indexes, which increases the risk of retrieving and serving stale information. CockroachDB addresses this fundamental limitation by streamlining the data management processes, thus delivering accurate, timely responses in RAG-enabled applications.&lt;/p&gt;&lt;h3 id=&quot;Scalability,-Reliability,-and-Simplicity-of-Operations&quot;&gt;Scalability, Reliability, and Simplicity of Operations&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;p&gt;CockroachDB is purpose-built to run business-critical applications at scale, providing &lt;a href=&quot;https://www.cockroachlabs.com/blog/database-testing-performance-under-adversity/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;robust scalability and unmatched resilience&lt;/u&gt;&lt;/a&gt;, which makes it ideal for powering RAG systems that handle intensive workloads and large data volumes. Trusted by numerous enterprises large and small, CockroachDB&#39;s distributed architecture ensures &lt;a href=&quot;https://www.cockroachlabs.com/docs/stable/data-resilience#high-availability&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;continuous availability&lt;/u&gt;&lt;/a&gt; by automatically self-healing from hardware failures or network issues, substantially reducing maintenance overhead and operational complexity.&amp;nbsp;&lt;/p&gt;&lt;div class=&quot;mb-8 rounded-3xl border border-solid border-[#D2D2D5] bg-[#F1F1F1] p-7&quot;&gt;&lt;h2 class=&quot;mb-4 text-display-md font-semibold text-electric-purple-500&quot;&gt;Measure what matters&lt;/h2&gt;&lt;p class=&quot;mb-4&quot;&gt;Traditional benchmarks only test when everything’s perfect. But you need to know what happens when everything fails. CockroachDB&#39;s new benchmark, &quot;Performance under Adversity,&quot; tests real-world scenarios: network partitions, regional outages, disk stalls, and so much more.&lt;/p&gt;&lt;div&gt;&lt;a href=&quot;https://www.cockroachlabs.com/performance-under-adversity/?referralid=blogs_pua_launch_bottom_card&quot;&gt;&lt;button class=&quot;inline-flex justify-center items-center gap-2 disabled:cursor-not-allowed border border-solid border-electric-purple-500 bg-electric-purple-500 text-white hover:bg-white hover:text-electric-purple-500 active:border-electric-purple-100 active:bg-electric-purple-100 active:text-white px-6 py-2.5 leading-tight rounded-full&quot;&gt;See it in action&lt;/button&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;CockroachDB is &lt;a href=&quot;https://www.cockroachlabs.com/blog/postgresql-compatible-database-cockroachdb/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;PostgreSQL-wire compatible&lt;/u&gt;&lt;/a&gt;, and our &lt;a href=&quot;https://www.cockroachlabs.com/docs/dev/vector&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;code&gt;&lt;u&gt;VECTOR&lt;/u&gt;&lt;/code&gt;&lt;u&gt; implementation&lt;/u&gt;&lt;/a&gt; is compatible with the &lt;code&gt;pgvector&lt;/code&gt; extension, making it easier for engineering teams to integrate with existing systems. But by leveraging CockroachDB for vector storage and retrieval, developers avoid the scalability limitations associated with &lt;a href=&quot;https://www.cockroachlabs.com/blog/vector-search-pgvector-cockroachdb/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;pgvector/Postgres&lt;/u&gt;&lt;/a&gt;. With CockroachDB’s vector capabilities, you can scale your RAG applications while maintaining consistent performance under increasing load.&lt;/p&gt;&lt;p&gt;Additionally, CockroachDB’s consistency model ensures outdated vectors will not be queried, further enhancing the accuracy of retrieval results. CockroachDB’s &lt;a href=&quot;https://www.cockroachlabs.com/docs/stable/deploy-cockroachdb-with-kubernetes#helm-version&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;Helm chart &amp;amp; Kubernetes Operator&lt;/u&gt;&lt;/a&gt; seamlessly handles large-scale deployments, making it an ideal backend for powering efficient and reliable vector search functionalities.&lt;/p&gt;&lt;h3 id=&quot;Advanced-Access-Control-and-Security&quot;&gt;Advanced Access Control and Security&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;p&gt;As powerful Large Language Models (LLMs) become central to enterprise applications, &lt;a href=&quot;https://www.cockroachlabs.com/docs/cockroachcloud/security-overview.html&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;security and access control&lt;/u&gt;&lt;/a&gt; become paramount considerations. CockroachDB addresses these concerns comprehensively: Role-based access controls (RBAC) and &lt;a href=&quot;https://www.cockroachlabs.com/docs/v25.2/row-level-security.html&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;Row-Level Security&lt;/u&gt;&lt;/a&gt;, empowering organizations to provide fine-grained user permissions. This ensures that users access only the data they&#39;re authorized to view, preventing unauthorized disclosures and enhancing overall data governance. Additionally, CockroachDB has native &lt;a href=&quot;https://www.cockroachlabs.com/docs/stable/partitioning&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;geo-data placement capabilities&lt;/u&gt;&lt;/a&gt; to enable data governance and improve performance by keeping data close to the customers that need it. Such precise control mechanisms set CockroachDB apart in securely supporting knowledge bases integrated with advanced generative AI capabilities.&lt;/p&gt;&lt;h2 id=&quot;How-to-build-a-knowledge-base-chatbot-with-RAG-on-CockroachDB&quot;&gt;How to build a knowledge base chatbot with RAG on CockroachDB&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;Building a knowledge based application using RAG on CockroachDB can significantly streamline how enterprises leverage their private knowledge bases, greatly improving productivity across various internal workflows. This chatbot leverages a general-purpose Large Language Model (LLM), significantly reducing the cost and complexity associated with training a domain-specific model, while still maintaining accurate, relevant, and timely responses.&lt;/p&gt;&lt;h3 id=&quot;Data-flow&quot;&gt;Data flow&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/79CqUXvhZBfrCAXWRm9dZA/ce983fc00643dbbccac77f4aa180d015/rag-data-flow-with-cockroachdb-chatbot.png&quot;&gt;&lt;img alt=&quot;The data flow for a RAG-based chatbot application using CockroachDB. The user inputs a question, which is fed into am embedding model that vectorizes the text. Then CockroachDB implements vector search. The AI then uses the user question and relevant sources to ground the response. Then the LLM generates a contextualized answer, which is outputted to the user.&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;937&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/79CqUXvhZBfrCAXWRm9dZA/ce983fc00643dbbccac77f4aa180d015/rag-data-flow-with-cockroachdb-chatbot.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;As illustrated in the above flowchart, in this knowledge base chatbot scenario, a user initiates interaction by asking a question. This query is first processed by an embedding model, which vectorizes the question, transforming it into a numerical representation. The vectorized query is then passed to CockroachDB, which houses both the vector embeddings and the source data. Using similarity search capabilities, CockroachDB quickly identifies and retrieves the most relevant content sources.&lt;/p&gt;&lt;p&gt;Once relevant sources are retrieved, they serve as grounded context alongside the original user query. The grounding step ensures the LLM generates context-aware and facts-based responses. This combination reduces the risk of hallucination.&lt;/p&gt;&lt;h3 id=&quot;Application-architecture&quot;&gt;Application architecture&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/2jhUWrVbC1RBCGoOQyHNqt/9a4a27504db21938d1561ba967e31247/cockroachdb-chatbot-ai-use-case-rag-application-architecture-diagram.png&quot;&gt;&lt;img alt=&quot;The retrieval augmented generation (RAG) application architecture using CockroachDB: frontend, Rest API, LLM API, and CockroachDB Cloud.&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;937&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/2jhUWrVbC1RBCGoOQyHNqt/9a4a27504db21938d1561ba967e31247/cockroachdb-chatbot-ai-use-case-rag-application-architecture-diagram.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The Retrieval Augmented Generation (RAG) application architecture depicted in the diagram consists of three primary components: a frontend chatbot UI, a FastAPI-based REST API service calling Cockroach Cloud, and an LLM API. The user interacts with the chatbot through the frontend interface, submitting questions or queries. These user inputs are then sent to the REST API service, which orchestrates data processing by communicating with Cockroach Cloud to perform similarity searches and retrieve relevant, grounded information. Next the REST API leverages the LLM API to vectorize the user&#39;s query, use contextual prompts to produce accurate, contextually enriched responses. This design enables efficient data management, real-time retrieval, and seamless integration between the database and the generative capabilities of LLMs, providing users with timely, accurate, and reliable information.&lt;/p&gt;&lt;p&gt;Check out a full demo of the chatbot at our YouTube channel:&lt;/p&gt;&lt;p&gt;&lt;!--$!--&gt;&lt;template data-dgst=&quot;BAILOUT_TO_CLIENT_SIDE_RENDERING&quot;&gt;&lt;/template&gt;&lt;!--/$--&gt;&lt;/p&gt;&lt;h2 id=&quot;RAG-and-CockroachDB:-Better-Together&quot;&gt;RAG and CockroachDB: Better Together&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;RAG enhances Large Language Models (LLMs) by grounding their responses in verified, domain-specific data, thus improving accuracy and reliability, which is often required in many applications, including customer support, content generation, knowledge base queries, and real-time information retrieval.&lt;/p&gt;&lt;p&gt;CockroachDB is an ideal foundation for RAG applications, given its ability to store&amp;nbsp; source data, metadata, and vector data all in the same place. By bringing vector capabilities into a distributed SQL database, you can easily implement AI use cases, simplify database management, and gain the scalability, resilience, and familiarity of a proven distributed SQL database.&amp;nbsp;&lt;/p&gt;&lt;p&gt;To learn more about how you can leverage CockroachDB for your AI applications, contact us! We’d love to hear from you.&lt;/p&gt;&lt;div class=&quot;mb-8 rounded-3xl border border-solid border-[#D2D2D5] bg-[#F1F1F1] p-7&quot;&gt;&lt;h2 class=&quot;mb-4 text-display-md font-semibold text-electric-purple-500&quot;&gt;Try CockroachDB Today&lt;/h2&gt;&lt;p class=&quot;mb-4&quot;&gt;Spin up your first CockroachDB Cloud cluster in minutes. Start with $400 in free credits.
Or get a free 30-day trial of CockroachDB Enterprise on self-hosted environments.&lt;/p&gt;&lt;div&gt;&lt;a href=&quot;https://cockroachlabs.cloud/signup&quot;&gt;&lt;button class=&quot;inline-flex justify-center items-center gap-2 disabled:cursor-not-allowed border border-solid border-electric-purple-500 bg-electric-purple-500 text-white hover:bg-white hover:text-electric-purple-500 active:border-electric-purple-100 active:bg-electric-purple-100 active:text-white px-6 py-2.5 leading-tight rounded-full&quot;&gt;Try Cloud Today&lt;/button&gt;&lt;/a&gt;&lt;a href=&quot;https://cockroachlabs.cloud/signup?experience=enterprise&quot;&gt;&lt;button class=&quot;inline-flex justify-center items-center gap-2 disabled:cursor-not-allowed border border-solid border-electric-purple-500 bg-electric-purple-500 text-white hover:bg-white hover:text-electric-purple-500 active:border-electric-purple-100 active:bg-electric-purple-100 active:text-white px-6 py-2.5 leading-tight rounded-full&quot;&gt;Try Self-Hosted Today&lt;/button&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;</description><link>https://www.cockroachlabs.com/blog/tutorial-rag-with-cockroachdb/</link><guid isPermaLink="false">https://www.cockroachlabs.com/blog/tutorial-rag-with-cockroachdb/</guid></item><item><title>Ideal isn’t real: Stress testing CockroachDB’s resilience</title><description>&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/DxyiJDRSvJj4734ff8OMK/f2a58a38423f7e2ad3163cba880784e3/stress-testing-cockroachdb-resilience-blog-header.png&quot;&gt;&lt;img alt=&quot;People running a race through the mud.&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1080&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/DxyiJDRSvJj4734ff8OMK/f2a58a38423f7e2ad3163cba880784e3/stress-testing-cockroachdb-resilience-blog-header.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;In today’s always-on, global applications, raw speed is no longer enough. Modern enterprises demand not only blistering transaction rates but also unwavering stability when the unexpected strikes; whether that’s a network hiccup, a failing disk, or an entire data center going dark. With organizations averaging &lt;a href=&quot;https://www.cockroachlabs.com/guides/the-state-of-resilience-2025/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;86 outages a year&lt;/u&gt;&lt;/a&gt;, failures are the norm today. But traditional benchmarks like TPC-C only tell you how fast a database runs in perfect conditions, or sunny days. They leave out the more important story of what happens when things go wrong.&lt;/p&gt;&lt;p&gt;As announced by Cockroach Labs, our new database benchmarking methodology, &lt;a href=&quot;https://www.cockroachlabs.com/blog/database-testing-performance-under-adversity/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;“Performance under Adversity”&lt;/u&gt;&lt;/a&gt; captures these complex, operational realities of modern enterprise systems: where everything fails all the time. The benchmark is a single, continuous test that weaves seven increasingly severe failure scenarios into a standard OLTP workload. By measuring throughput, latency, and failure rates through rolling upgrades, disk stalls, network partitions, node restarts, and even full zone or regional outages, our benchmark reveals how well CockroachDB, a distributed SQL database, maintains service continuity when it matters most.&lt;/p&gt;&lt;p&gt;In this blog post, we’ll dive into what makes CockroachDB uniquely resilient under pressure. We will examine its baseline performance, its behavior under internal operational stress, and its ability to self-heal through grey failures and large-scale outages.&amp;nbsp; We explain exactly how CockroachDB stays online and keeps data safe even beyond perfect, sunny days and clear operational skies.&lt;/p&gt;&lt;div class=&quot;mb-8 rounded-3xl border border-solid border-[#D2D2D5] bg-[#F1F1F1] p-7&quot;&gt;&lt;h2 class=&quot;mb-4 text-display-md font-semibold text-electric-purple-500&quot;&gt;Measure what matters&lt;/h2&gt;&lt;p class=&quot;mb-4&quot;&gt;Traditional benchmarks only test when everything’s perfect. But you need to know what happens when everything fails. CockroachDB&#39;s new benchmark, &quot;Performance under Adversity,&quot; tests real-world scenarios: network partitions, regional outages, disk stalls, and so much more.&lt;/p&gt;&lt;div&gt;&lt;a href=&quot;https://www.cockroachlabs.com/performance-under-adversity/?referralid=blogs_pua_launch_bottom_card&quot;&gt;&lt;button class=&quot;inline-flex justify-center items-center gap-2 disabled:cursor-not-allowed border border-solid border-electric-purple-500 bg-electric-purple-500 text-white hover:bg-white hover:text-electric-purple-500 active:border-electric-purple-100 active:bg-electric-purple-100 active:text-white px-6 py-2.5 leading-tight rounded-full&quot;&gt;See it in action&lt;/button&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;The-Seven-Phases-of-Adversity&quot;&gt;The Seven Phases of Adversity&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;Before exploring how CockroachDB tackles the operational realities of modern enterprise systems, let’s first outline the behaviors you should expect from a resilient database as it endures each phase of real-world adversity.&lt;/p&gt;&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/7Jwdlb12Xv0RtyhdAVn2fZ/60946f17ed0c5234338bb25023adc4ba/expected-resilience-during-phases-of-adversity-table.png&quot;&gt;&lt;img alt=&quot;A table showing expected resilience behavior during phases of adversities. The left column is for the phase, and the right column is for the expected database resilience behavior:
1) Baseline Performance | Steady state TPC-C benchmark (&amp;quot;sunny days&amp;quot;)
2) Internal Operational Stress: Such as CDC, full backups, online schema changes, and rolling upgrades. | Minimal degradation and the database should absorb bursty traffic without crashing or slowing to a crawl.
3) Disk Stalls: Random disk slowness and complete stalls. | Withstand disk slowness or stalls without unavailability or dropping transactions and while maintaining overall tpmC.
4) Network Failures: Network failure preventing nodes in a network partition from communicating with the nodes in another. | Nodes across datacenters and geographies should be able to handle partial and full network partitions without unavailability or drops in throughput and while maintaining overall tpmC.
5) Node Restarts: Unpredictable outage of nodes. | Recover from losing a node while maintaining throughput and overall tpmC. 
6) Zone Outages: Outage of an entire availability zone (AZs). | Redistribute load to other zones and preserve data integrity while maintaining availability and later reintegrate the recovered site. 
7) Region Outages: Outage of an entire geographic region. | Redistribute load to other regions and preserve data integrity while maintaining availability and later reintegrate when the region recovers&quot; loading=&quot;lazy&quot; width=&quot;3376&quot; height=&quot;2335&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/7Jwdlb12Xv0RtyhdAVn2fZ/60946f17ed0c5234338bb25023adc4ba/expected-resilience-during-phases-of-adversity-table.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;What-Keeps-CockroachDB-Resilient-and-Stable-Under-Pressure?&quot;&gt;What Keeps CockroachDB Resilient and Stable Under Pressure?&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;To understand how CockroachDB handles the pressure, let us look at the results of the benchmark in the &lt;a href=&quot;https://www.cockroachlabs.com/performance-under-adversity/dashboard/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;b&gt;&lt;u&gt;interactive dashboard&lt;/u&gt;&lt;/b&gt;&lt;/a&gt; and then analyze the result of each phase.&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Baseline Performance&lt;/b&gt;: Normal conditions only running TPC-C workload with no internal or external stressors (a perfect, “sunny day”)&lt;/p&gt;&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/coXByWWhgaslAggHboNKI/a41f5c173cce189565bb6fbc09024b48/cockroachdb-baseline-performance.png&quot;&gt;&lt;img alt=&quot;A table illustrating the baseline performance of a 15-node CockroachDB cluster (multi-region), and a 9-node CockroachDB cluster (single region)
Warehouses: 7000 vs. 5000
Connections: 14000 vs. 1800
CPU Load: ~60% vs. ~50%
Workload Throughput (Transactions per minute (tpmC)): ~87K vs. ~62K
Workload p95 latency: ~160-180 ms vs. ~25-40 ms 
SQL Throughput (Queries per seconds (QPS)): ~24K vs. ~17K
SQL p95 latency: ~20-30 ms vs. ~3 ms&quot; loading=&quot;lazy&quot; width=&quot;3372&quot; height=&quot;1739&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/coXByWWhgaslAggHboNKI/a41f5c173cce189565bb6fbc09024b48/cockroachdb-baseline-performance.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;b&gt;It is important to note that tpmC measures transactions per minute for TPC-C and each transaction is &lt;/b&gt;&lt;a href=&quot;https://www.tpc.org/tpc_documents_current_versions/pdf/tpc-c_v5.11.0.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;b&gt;&lt;u&gt;~14 queries.&lt;/u&gt;&lt;/b&gt;&lt;/a&gt;&lt;b&gt; So the corresponding SQL queries per seconds (QPS) is tpmC multiplied by a factor of 14/60&lt;/b&gt;. The largest transaction tested is the &quot;New Order&quot; transaction, which consists of up to 14 SQL statements involving 8 database tables to complete an order within a transaction. This workload is both read- and write-intensive, designed with high execution frequency and strict response-time requirements to simulate real-world online database activity.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Internal Operational Stress&lt;/b&gt;: In this phase, routine maintenance tasks are executed, including backups, change feeds, online schema changes, and rolling upgrades.&lt;/p&gt;&lt;p&gt;During backups, change-data capture (CDC), and index builds (online schema change), the database must scan or rewrite tables. These operations consume significant CPU and I/O bandwidth.&lt;/p&gt;&lt;p&gt;Likewise, during rolling upgrades, for each node being upgraded, CockroachDB drains SQL connections on the node, transfers data leases from the node to the other nodes and then restarts the node with the upgraded binary. Any application connected to the node will experience a SQL connection drop when the node restarts; and the application may try to reconnect, generating a burst of new connections. Upon rejoining, the restarted node receives snapshots of data that changed while it was down from other nodes. The lease transfers, connection burst, and snapshot streaming to restarted nodes generates heavy CPU and IOPS load.&lt;/p&gt;&lt;p&gt;Without careful throttling and scheduling, large background scans, large connection bursts, and snapshot streaming will inevitably siphon CPU, I/O, and network capacity from your primary workload. In turn driving up latency, eroding throughput, and risking overall cluster health.&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;As can be seen on the &lt;a href=&quot;https://benchmarkingortal.netlify.app/?benchmark_config=multi-region-15-node&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;dashboard&lt;/u&gt;&lt;/a&gt; during this phase on CockroachDB, tpmC remained unaffected during internal operational stress with minimal latency impact, and CockroachDB maintained stability.&amp;nbsp;&lt;/p&gt;&lt;p&gt;CockroachDB avoids the aforementioned pitfalls with its &lt;a href=&quot;https://www.cockroachlabs.com/docs/stable/admission-control&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;built-in admission control&lt;/u&gt;&lt;/a&gt; layer, which dynamically prioritizes client-facing traffic over background operations. Not only that, admission control throttles access to a resource (CPU or IO) before the resource becomes overloaded, rather than after. The result is rock-solid stability, consistently low latencies, and minimal throughput impact even when backups, CDC streams, index builds, and rolling upgrades run concurrently.&lt;/p&gt;&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/wq4KTGulyRv1L1OXzk4yS/b56623c018923bf6c4f35fce574eb7a2/performance-under-adversity-dashboard.png&quot;&gt;&lt;img alt=&quot;The &amp;quot;Performance under Adversity&amp;quot; interactive dashboard for the 15-node CockroachDB cluster.&quot; loading=&quot;lazy&quot; width=&quot;908&quot; height=&quot;897&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/wq4KTGulyRv1L1OXzk4yS/b56623c018923bf6c4f35fce574eb7a2/performance-under-adversity-dashboard.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;sup&gt;&lt;i&gt;Image: 15-node CockroachDB cluster under internal operational stress&lt;/i&gt;&lt;/sup&gt;&lt;/p&gt;&lt;p&gt;Next, let us understand how CockroachDB handles external stressors that are not controlled by the database administrator.&lt;/p&gt;&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/7Mf61VoIRKap1rwM1JPMoV/7c69df6003bb45a92f4c1e5c7ee2495a/performance-under-adversity-dashboard-explained.png&quot;&gt;&lt;img alt=&quot;Zoomed in version of the &amp;quot;Performance under Adversity&amp;quot; dashboard showing the Cluster Metrics and Client Experience graphs, SQL Metrics and Workload Metrics, respectively when the 15-node cluster was under going disk stalls, network failure, node restarts, zone outages, and regional outages.&quot; loading=&quot;lazy&quot; width=&quot;908&quot; height=&quot;723&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/7Mf61VoIRKap1rwM1JPMoV/7c69df6003bb45a92f4c1e5c7ee2495a/performance-under-adversity-dashboard-explained.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;i&gt;&lt;sup&gt;Image: 15-node CockroachDB cluster withstanding external stressors (disk stalls, network partitions, node restarts, and facility and region outage)&lt;/sup&gt;&lt;/i&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Disk Stalls&lt;/b&gt;:&amp;nbsp; Transient disk stalls are a frequent reality in cloud environments whether on AWS EBS, Azure SSD, or GCP PD occurring as often as 20–30 times per hour in a single cluster. During a stall, write-ahead log (WAL) writes block until the disk recovers, often leading to transaction timeouts, latency spikes, and elusive “grey” failures.&lt;/p&gt;&lt;p&gt;As can be seen on the &lt;a href=&quot;https://benchmarkingortal.netlify.app/?benchmark_config=multi-region-15-node&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;dashboard&lt;/u&gt;&lt;/a&gt;, CockroachDB handles disk stalls with minimal latency impact and stable throughput.&lt;/p&gt;&lt;p&gt;CockroachDB turns disk stalls into a non-event by leveraging multiple disks per node: if one disk stalls, &lt;a href=&quot;https://www.cockroachlabs.com/blog/write-ahead-log-failover/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;WAL writes automatically fail over&lt;/u&gt;&lt;/a&gt; to an alternate disk within 100ms. The result is seamless resilience, with steady latency without blips and no noticeable drop in performance or throughput.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Network Failures: &lt;/b&gt;Network failures can result in network partitions, which isolate one or more nodes from the rest of the cluster. These issues can arise from hardware or software failures, traffic congestion, or misconfiguration and can last anywhere from seconds to minutes (or, in rare cases, even longer). When partitions occur, they can result in read-errors, write-errors, latency spikes, and potentially stale or inconsistent data. Such gray failures are notoriously hard to diagnose because they’re often transient and shifting.&lt;/p&gt;&lt;p&gt;As evident on the &lt;a href=&quot;https://benchmarkingortal.netlify.app/?benchmark_config=multi-region-15-node&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;dashboard&lt;/u&gt;&lt;/a&gt;, which shows a minor latency spike for a brief duration and minimal impact on throughput, CockroachDB is partition-tolerant.&lt;/p&gt;&lt;p&gt;We ran these tests using CockroachDB v25.1. It survives network partitions with epoch leases, which fence out stale masters and prevent a split‐brain scenario. During a partition, only the majority side (with more than half of ranges) can renew or re‐elect leases and the minority side leases stales out. Any future operations by stale leaseholders are rejected and the surviving leader continues serving traffic seamlessly, preserving consistency and availability, and minimizing impact on throughput. Once the network recovers from partition, all the nodes start participating in quorum.&lt;/p&gt;&lt;p&gt;Starting with v25.2, CockroachDB survives network partitions thanks to its &lt;a href=&quot;https://www.cockroachlabs.com/docs/v25.1/architecture/replication-layer#leader-leases&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;leader-leases architecture&lt;/u&gt;&lt;/a&gt;: every Raft leader also holds the range’s lease, ensuring a single, unequivocal authority for both reads and writes. By unifying leadership and leaseholding in a single role, it eliminates single points of failure and split-brain risks. So even when node communication is severed, the surviving leader continues serving traffic seamlessly, preserving consistency and availability; and minimizing impact on throughput.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Node Restarts&lt;/b&gt;: Similar to rolling upgrades, a node restart also triggers lease transfer from the restarted node to other nodes across the clusters. If the node takes longer than 5 minutes to restart, it also triggers range rebalancing. Additionally any applications connected to the node will experience SQL connection drops, and will try to reconnect generating a burst of new connections. These are random and ungraceful reboots, and the resulting lease transfers, connection burst, and snapshot streaming generate heavy storage engine CPU load, IOPS and network traffic. In turn impacting latency and throughput by taking away resources from foreground traffic. However CockrochDB’s Admission Control handles this by prioritizing foreground traffic over rebalancing activities while maintaining stability, and resulting in only minor latency increases and negligible throughput impacts.&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;In the benchmarking run where three nodes were restarted randomly, the &lt;a href=&quot;https://benchmarkingortal.netlify.app/?benchmark_config=multi-region-15-node&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;dashboard&lt;/u&gt;&lt;/a&gt; shows a brief, minor latency spike and negligible impact on throughput of the CockroachDB cluster.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Zone Outages&lt;/b&gt;: Zone outages can occur when the data center hosting the zone experiences power or network outage. When this occurs, data replicas in the impacted zone need to move over to the remaining zones to ensure full cluster availability. This data movement is done by streaming range data among the nodes in the remaining zones, thus balancing the range distribution in the cluster.&lt;/p&gt;&lt;p&gt;Range rebalancing across multiple nodes generates heavy storage engine CPU load, IOPS and network traffic. Unchecked, the range rebalancing can overload these resources and starve foreground queries of resources resulting in negative impact on latency and throughput and in extreme cases destabilizing the cluster altogether. However,&amp;nbsp; CockroachDB, as shown on the &lt;a href=&quot;https://benchmarkingortal.netlify.app/?benchmark_config=multi-region-15-node&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;dashboard&lt;/u&gt;&lt;/a&gt;, only experienced a very brief, minor latency spike and virtually no change in throughput during the zone outage.&lt;/p&gt;&lt;p&gt;Overall availability and stability of the CockroachDB cluster throughout the zone outage is thanks to the automatic redirection of traffic from failed zones to available zones and especially how CockroachDB’s Admission Control handles foreground traffic and background range rebalancing traffic.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Regional Outages&lt;/b&gt;: Enterprises with presence in multiple geographies require that users in all locations have consistent experiences with latency and throughput. In addition, these enterprises must comply with data domiciling regulations. For such organizations, CockroachDB can operate in multiple regions by placing data closer to users in different geographic locations.&lt;/p&gt;&lt;p&gt;Similar to zone outages, regional outages trigger range rebalancing across the nodes of the remaining regions to maintain full cluster availability. As explained earlier, range rebalancing across multiple nodes can negatively impact foreground latency and throughput, and cluster stability. However this is not an issue in CockroachDB, as shown in the &lt;a href=&quot;https://benchmarkingortal.netlify.app/?benchmark_config=multi-region-15-node&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;dashboard&lt;/u&gt;&lt;/a&gt;.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Again, similar to zone outage, CockroachDB’s admission control automatically redirects traffic to available regions and dynamically prioritizes client-facing traffic over background operations. Along with properly throttling access to resources before they become overloaded, results in stability with minimal latency and throughput impact.&amp;nbsp;&lt;/p&gt;&lt;p&gt;One final observation to make is the consistency in CPU and disk usage throughout the entire benchmarking run.&lt;/p&gt;&lt;p&gt;You can check out a full demo of the interactive dashboard on our YouTube channel:&lt;/p&gt;&lt;p&gt;&lt;!--$!--&gt;&lt;template data-dgst=&quot;BAILOUT_TO_CLIENT_SIDE_RENDERING&quot;&gt;&lt;/template&gt;&lt;!--/$--&gt;&lt;/p&gt;&lt;h2 id=&quot;Resilience-Is-Essential,-Not-Optional&quot;&gt;Resilience Is Essential, Not Optional&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;As you’ve seen, the new database benchmarking methodology, “Performance under Adversity,” pushes CockroachDB through seven increasingly severe failure scenarios and in every case CockroachDB delivers steady throughput, low latency, and zero downtime. That resilience comes from engineered features like back-pressured range rebalancing, admission control that favors client traffic, co-located leaseholders, and multi-disk WAL failover.&lt;/p&gt;&lt;p&gt;After all, it’s not enough to know how fast your database can go when the sun is shining and conditions are perfect. You need to know that your database will keep churning at scale, under load, and in the face of every curveball the real world can throw. With CockroachDB and our new benchmark, you get both performance and peace of mind even beyond the sunny days.&lt;/p&gt;&lt;p&gt;Explore the &lt;a href=&quot;https://benchmarkingortal.netlify.app/?benchmark_config=multi-region-15-node&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;interactive dashboard&lt;/u&gt;&lt;/a&gt; to review phase-by-phase metrics, run your own tests, or spin up a &lt;a href=&quot;https://cockroachlabs.cloud/signup&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;free CockroachDB cluster&lt;/u&gt;&lt;/a&gt; today.&lt;/p&gt;&lt;div class=&quot;mb-8 rounded-3xl border border-solid border-[#D2D2D5] bg-[#F1F1F1] p-7&quot;&gt;&lt;h2 class=&quot;mb-4 text-display-md font-semibold text-electric-purple-500&quot;&gt;Try CockroachDB Today&lt;/h2&gt;&lt;p class=&quot;mb-4&quot;&gt;Spin up your first CockroachDB Cloud cluster in minutes. Start with $400 in free credits.
Or get a free 30-day trial of CockroachDB Enterprise on self-hosted environments.&lt;/p&gt;&lt;div&gt;&lt;a href=&quot;https://cockroachlabs.cloud/signup&quot;&gt;&lt;button class=&quot;inline-flex justify-center items-center gap-2 disabled:cursor-not-allowed border border-solid border-electric-purple-500 bg-electric-purple-500 text-white hover:bg-white hover:text-electric-purple-500 active:border-electric-purple-100 active:bg-electric-purple-100 active:text-white px-6 py-2.5 leading-tight rounded-full&quot;&gt;Try Cloud Today&lt;/button&gt;&lt;/a&gt;&lt;a href=&quot;https://cockroachlabs.cloud/signup?experience=enterprise&quot;&gt;&lt;button class=&quot;inline-flex justify-center items-center gap-2 disabled:cursor-not-allowed border border-solid border-electric-purple-500 bg-electric-purple-500 text-white hover:bg-white hover:text-electric-purple-500 active:border-electric-purple-100 active:bg-electric-purple-100 active:text-white px-6 py-2.5 leading-tight rounded-full&quot;&gt;Try Self-Hosted Today&lt;/button&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;b&gt;&lt;i&gt;Disclaimer:&lt;/i&gt;&lt;/b&gt;&lt;i&gt; Results are from specific test setups. &lt;/i&gt;&lt;a href=&quot;https://www.cockroachlabs.com/performance-under-adversity/dashboard&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;i&gt;&lt;u&gt;Try CockroachDB yourself&lt;/u&gt;&lt;/i&gt;&lt;/a&gt;&lt;i&gt; to see how it fits your needs.&lt;/i&gt;&lt;/p&gt;</description><link>https://www.cockroachlabs.com/blog/stress-testing-cockroachdb-resilience/</link><guid isPermaLink="false">https://www.cockroachlabs.com/blog/stress-testing-cockroachdb-resilience/</guid></item><item><title>CockroachDB 25.2: Celebrating a decade of innovation with enhanced performance, vector indexing, and more</title><description>&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/2ufSoh7SnVNLI3VflxwUBU/f6aecc2c71c88a5202c437a5fe1494f4/cockroachdb-decade-innovation-252-vector-indexing-blog-header.png&quot;&gt;&lt;img alt=&quot;The CockroachDB logo with the words &amp;quot;CockroachDB 25.2&amp;quot;&quot; loading=&quot;lazy&quot; width=&quot;3840&quot; height=&quot;2160&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/2ufSoh7SnVNLI3VflxwUBU/f6aecc2c71c88a5202c437a5fe1494f4/cockroachdb-decade-innovation-252-vector-indexing-blog-header.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;A few months ago &lt;a href=&quot;https://www.cockroachlabs.com/blog/cockroachdb-turns-ten-scaling-relational-databases/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;Cockroach Labs turned 10&lt;/u&gt;&lt;/a&gt;, and this release celebrates 10 years of continuous distributed SQL innovation. We’re introducing even more performance and scalability improvements and AI vector indexing, along with many other new features and enhancements to both self-hosted and cloud offerings in the areas of change data capture (CDC), security, observability, and migrations.&lt;/p&gt;&lt;p&gt;CockroachDB v25.2 is the most performant, scalable, and secure version of CockroachDB yet. My favorite new feature highlights of this release include:&lt;/p&gt;&lt;h2 id=&quot;Performance-improvements:-50%-increased-throughput-and-more&quot;&gt;Performance improvements: 50% increased throughput and more&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;We’ve achieved 50% increased throughput as compared to 24.3 as measured on average across nine workloads. &lt;!-- --&gt;These performance improvements are the result of over 100 changes, both large and small, including new features like &lt;a href=&quot;https://www.cockroachlabs.com/docs/v25.1/cost-based-optimizer#query-plan-type&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;generic query plans&lt;/u&gt;&lt;/a&gt; (now in GA).&lt;/p&gt;&lt;p&gt;&lt;!--$!--&gt;&lt;template data-dgst=&quot;BAILOUT_TO_CLIENT_SIDE_RENDERING&quot;&gt;&lt;/template&gt;&lt;!--/$--&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Buffered writes (now in Preview).&lt;/b&gt; Buffered writes is an under-the-covers way to improve performance by bundling up database writes more efficiently to increase throughput and decrease latency, while also reducing hardware requirements. Buffered writes performance improvements are not counted towards the 50% improvement discussed earlier because it’s still a preview feature and the default setting for buffered writes is ‘off’.&lt;/p&gt;&lt;p&gt;Buffered writes introduces a new step in the transaction flow, which temporarily stores transaction writes on the client side (gateway) until the transaction commits. This approach minimizes the number of roundtrips to the leaseholders, reduces pipeline stalls, and allows for the passive use of the 1-phase commit fast-path. By deferring writes until commit time, the system can reduce redundant writes and serve read-your-writes locally, resulting in performance gains that in our tests range from 15% (Sysbench &lt;code&gt;oltp_read_write&lt;/code&gt;) to 40% (customer-specific testing) improvements.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Database restore enhancements&lt;/b&gt;. Improvements to the database restore capabilities have led to an increase in up to 4x the speed when restoring from backup for some restore use cases.&lt;/p&gt;&lt;h2 id=&quot;Vector-indexing-is-in-Preview-for-AI-applications-at-scale&quot;&gt;Vector indexing is in Preview for AI applications at scale&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;&lt;!--$!--&gt;&lt;template data-dgst=&quot;BAILOUT_TO_CLIENT_SIDE_RENDERING&quot;&gt;&lt;/template&gt;&lt;!--/$--&gt;&lt;/p&gt;&lt;p&gt;In 24.2 we released &lt;a href=&quot;https://www.cockroachlabs.com/docs/stable/vector.html&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;code&gt;&lt;u&gt;pgvector&lt;/u&gt;&lt;/code&gt;&lt;u&gt; support&lt;/u&gt;&lt;/a&gt; for the vector datatype, which was a good way for customers to begin experimenting with advanced LLM applications. When we introduced &lt;code&gt;pgvector&lt;/code&gt; support, we did so for vectors with thousands of dimensions. Now customers are moving their testing along to where performance is important.&lt;/p&gt;&lt;p&gt;To support performant search and discovery we are now introducing &lt;a href=&quot;https://www.cockroachlabs.com/docs/stable/vector-indexes&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;vector indexing&lt;/u&gt;&lt;/a&gt; in Preview based on a protocol we’re calling Cockroach-SPANN (or C-SPANN). C-SPANN is based on Microsoft’s &lt;a href=&quot;https://www.microsoft.com/en-us/research/uploads/prod/2021/11/SPANN_finalversion1.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;SPANN&lt;/u&gt;&lt;/a&gt; and &lt;a href=&quot;https://dl.acm.org/doi/10.1145/3600006.3613166&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;SPFRESH&lt;/u&gt;&lt;/a&gt; research papers which, along with &lt;a href=&quot;https://arxiv.org/pdf/2405.12497&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;RaBitQ&lt;/u&gt;&lt;/a&gt;, deliver an indexing method that is small, fully distributed, and easy to update without degrading index quality. We’re very excited about this release as it directly addresses scalability concerns of vector applications for customers with support for indexing billions of vectors. With vector indexing, we now make it even more compelling to combine the strengths of a vector database and an operational database onto a single, horizontally scalable and performant solution.&amp;nbsp;&lt;/p&gt;&lt;h2 id=&quot;Introducing-row-level-security&quot;&gt;Introducing row-level security&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;&lt;!--$!--&gt;&lt;template data-dgst=&quot;BAILOUT_TO_CLIENT_SIDE_RENDERING&quot;&gt;&lt;/template&gt;&lt;!--/$--&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Row-level security&lt;/b&gt; (released as GA) is a critical feature for large organizations in sectors such as healthcare and finance, where sensitive customer information must be meticulously protected. These organizations often have a diverse array of database users, including database administrators and application users, each requiring different levels of data access. CockroachDB provides robust mechanisms for managing roles and privileges to restrict access to specific tables, and now we are adding the capability to enforce row-level security. This means that both access to individual tables can be controlled and there is built-in functionality to restrict access to specific rows within those tables based on the user or role.&lt;/p&gt;&lt;p&gt;Row-level security ensures sensitive data is protected and access to the data is tightly controlled. With row-level security customers also now have better tenant isolation to protect their customer information within a single table without relying upon application level constraints.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Enhanced observability:&lt;/b&gt; We now enable organizations to gain more insights into their workloads to improve overall performance. Capabilities include generating work-load level index recommendations to improve performance, finer-grained SQL metrics, and comprehensive hotspot logs.&lt;/p&gt;&lt;h2 id=&quot;New-CockroachDB-Cloud-regions-and-plan-switching-without-downtime&quot;&gt;New CockroachDB Cloud regions and plan switching without downtime&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;&lt;b&gt;New CockroachDB Cloud regions:&lt;/b&gt; There are two new GCP regions and two new AWS regions to support customer deployments with even richer region support to help keep your data as close to your client applications as possible. For the full list of regions supported, &lt;a href=&quot;https://www.cockroachlabs.com/docs/cockroachcloud/regions&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;check out the docs&lt;/u&gt;&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;b&gt;CockroachDB Cloud plan switching:&lt;/b&gt; With plan switching, customers deploying CockroachDB as a managed service will now have complete flexibility in the plans they choose, and switching between them as their needs evolve. Plan switching enables customers to easily scale workloads up or down without added downtime based on application scale and security needs. This helps to avoid plan lock-in, and lets customers select their plan tiers based on evolving needs and lessons learned. Plan switching currently supports Basic to Standard (and the reverse), with Standard to Advanced (and the reverse) coming out soon.&lt;/p&gt;&lt;p&gt;To see the full list of features and improvements in v25.2 and our Cloud offering head over to the “&lt;a href=&quot;https://www.cockroachlabs.com/whatsnew/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;what’s new&lt;/u&gt;&lt;/a&gt;” landing page.&lt;/p&gt;&lt;div class=&quot;mb-8 rounded-3xl border border-solid border-[#D2D2D5] bg-[#F1F1F1] p-7&quot;&gt;&lt;h2 class=&quot;mb-4 text-display-md font-semibold text-electric-purple-500&quot;&gt;Try CockroachDB Today&lt;/h2&gt;&lt;p class=&quot;mb-4&quot;&gt;Spin up your first CockroachDB Cloud cluster in minutes. Start with $400 in free credits.
Or get a free 30-day trial of CockroachDB Enterprise on self-hosted environments.&lt;/p&gt;&lt;div&gt;&lt;a href=&quot;https://cockroachlabs.cloud/signup&quot;&gt;&lt;button class=&quot;inline-flex justify-center items-center gap-2 disabled:cursor-not-allowed border border-solid border-electric-purple-500 bg-electric-purple-500 text-white hover:bg-white hover:text-electric-purple-500 active:border-electric-purple-100 active:bg-electric-purple-100 active:text-white px-6 py-2.5 leading-tight rounded-full&quot;&gt;Try Cloud Today&lt;/button&gt;&lt;/a&gt;&lt;a href=&quot;https://cockroachlabs.cloud/signup?experience=enterprise&quot;&gt;&lt;button class=&quot;inline-flex justify-center items-center gap-2 disabled:cursor-not-allowed border border-solid border-electric-purple-500 bg-electric-purple-500 text-white hover:bg-white hover:text-electric-purple-500 active:border-electric-purple-100 active:bg-electric-purple-100 active:text-white px-6 py-2.5 leading-tight rounded-full&quot;&gt;Try Self-Hosted Today&lt;/button&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;</description><link>https://www.cockroachlabs.com/blog/cockroachdb-252-performance-vector-indexing/</link><guid isPermaLink="false">https://www.cockroachlabs.com/blog/cockroachdb-252-performance-vector-indexing/</guid></item><item><title>CockroachDB Redefines Database Performance with Real-World Testing</title><description>&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/6ICYtEx0i3xMUjYsiNTSVY/6dbd02e333700a32a2b6f1fff9e0afda/PuA_ad_image_header.png&quot;&gt;&lt;img alt=&quot;A series of charts showing database performance over time against an abstract dotted background.&quot; loading=&quot;lazy&quot; width=&quot;3840&quot; height=&quot;2160&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/6ICYtEx0i3xMUjYsiNTSVY/6dbd02e333700a32a2b6f1fff9e0afda/PuA_ad_image_header.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;“Performance-under-Adversity”-pressure-testing-proves-most-resilient-database&quot;&gt;“Performance under Adversity” pressure testing proves most resilient database&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;For decades, database benchmarking has been stuck in the past. Industry-standard benchmarks like &lt;a href=&quot;https://www.tpc.org/tpcc/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;TPC-C&lt;/u&gt;&lt;/a&gt; – first approved 33 years ago, in 1992 – were designed to measure peak performance in pristine lab environments, isolated from the chaos of the real world. For example, they assume single datacenter deployments, ignoring the complexity of global applications and the global distribution of data. While they might include durability tests, they often do not explicitly measure performance during failures or maintenance, nor do they measure recovery time after failures. What they &lt;i&gt;do&lt;/i&gt; show you is how a database behaves &lt;i&gt;when nothing goes wrong. &lt;/i&gt;For example,&lt;i&gt; &lt;/i&gt;once the steady-state run is disrupted (for example by a power pull) the test is considered over.&lt;/p&gt;&lt;p&gt;But nothing has ever stayed perfect in production.&amp;nbsp;&lt;/p&gt;&lt;h2 id=&quot;Why-we-must-re-evaluate-database-performance-now&quot;&gt;Why we must re-evaluate database performance now&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;Modern applications are globally distributed, always-on, and increasingly complex. There are real world operations such as rolling upgrades, schema changes, and backups. There might be inconsistent storage access or complex network issues. While in the cloud, &lt;a href=&quot;https://cacm.acm.org/opinion/everything-fails-all-the-time/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;something fails all the time&lt;/u&gt;&lt;/a&gt;. Downtime, planned or unplanned, is no longer just a nuisance — it’s a multi-million dollar problem. Just ask &lt;a href=&quot;https://edition.cnn.com/2024/07/24/tech/crowdstrike-outage-cost-cause&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;CrowdStrike&lt;/u&gt;&lt;/a&gt;, &lt;a href=&quot;https://www.cbsnews.com/news/newark-airport-air-traffic-control-outage/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;FAA&lt;/u&gt;&lt;/a&gt;, &lt;a href=&quot;https://www.bbc.com/news/articles/c7875w07l93o&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;Lloyds Banking Group&lt;/u&gt;&lt;/a&gt;, and the &lt;a href=&quot;https://apnews.com/article/sony-playstation-outage-gamers-social-media-05610de4925f0e66dcd083b0443abb31&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;PlayStation Network&lt;/u&gt;&lt;/a&gt;, all of whom have suffered recent, very public outages.&lt;/p&gt;&lt;p&gt;In 2011, &lt;a href=&quot;https://www.mckinsey.com/capabilities/strategy-and-corporate-finance/our-insights/are-you-ready-for-the-era-of-big-data&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;McKinsey&lt;/u&gt;&lt;/a&gt; predicted the era of big data, and since then we’ve seen an explosive growth in the amount of data we generate and how quickly that data is shared between both users and machines. The increasing use of AI and applications such as virtual agents, coupled with the increased complexity of interconnected systems only drives this growth higher. As a result, organizations are more vulnerable to disruptions such as cyberattacks, natural disasters, and outages from equipment failures.&lt;/p&gt;&lt;p&gt;Our “State of Resilience 2025” Report &lt;a href=&quot;https://www.cockroachlabs.com/guides/the-state-of-resilience-2025/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;surveyed 1,000 senior technology leaders&lt;/u&gt;&lt;/a&gt;, and found that on average, organizations experience 86 outages each year, putting revenue and brand reputation at risk regularly. Even more telling: 79% of companies admit they aren’t ready to comply with emerging regulations surrounding operational resilience, like &lt;a href=&quot;https://www.cockroachlabs.com/blog/preparing-for-dora-regulations/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;DORA&lt;/u&gt;&lt;/a&gt; and NIS2. Of the 95% of executives who acknowledged their operational vulnerability, almost half have yet to take action.&lt;/p&gt;&lt;p&gt;Today, organizations often rely on chaos engineering tools such as Chaos Monkey and Chaos Mesh to ensure applications are resilient in the face of changing, real-world conditions. However, most chaos engineering tools only target a single instance and do not simulate more complex failures such as loss of an entire availability zone (AZ) or region. They also only focus on a single point of failure and do not include impact to database performance. Knowing how to coordinate the use of these tools on a given infrastructure is critical to assess the impact of resilience on sustained performance.&lt;/p&gt;&lt;p&gt;So what if there was a database benchmark that could measure these resilience factors along with its impact to sustained performance?&lt;/p&gt;&lt;h2 id=&quot;Measuring-what-matters:-Resilience,-recovery,-and-sustained-&amp;quot;Performance-under-Adversity&amp;quot;&quot;&gt;Measuring what matters: Resilience, recovery, and sustained &quot;Performance under Adversity&quot;&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;For the last 10 years we have built CockroachDB with the core belief that performance isn’t about speed – it’s about survival. In fact, we believe resilience is the new performance metric.&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;That’s why we’ve released a novel methodology for benchmarking modern databases that tests the impact of real-world conditions faced by application and infrastructure teams every day. The shift from measuring peak performance allows us to measure how infrastructure performs under pressure.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Then, we show how CockroachDB responds to these conditions, preventing downtime, delivering business value and fast, consistent performance, and allowing teams to meet their overall TCO goals.&amp;nbsp;&lt;/p&gt;&lt;h3 id=&quot;The-metrics-behind-real-world-testing&quot;&gt;The metrics behind real-world testing&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/1X7YLZme9vWFhHipncAuxO/66c99dc075e4ffb8612e1ca93e29de69/database-benchmarking-for-the-real-world.png&quot;&gt;&lt;img alt=&quot;CockroachDB&#39;s new database benchmarking dashboard: &amp;quot;Database benchmarking for the real world,&amp;quot; shows 7 scenarios: Baseline Performance, Internal Operational Stress, Disk Stalls, Network Failures, Node Restarts, Zone Outages, Regional Outages.&quot; loading=&quot;lazy&quot; width=&quot;3840&quot; height=&quot;2160&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/1X7YLZme9vWFhHipncAuxO/66c99dc075e4ffb8612e1ca93e29de69/database-benchmarking-for-the-real-world.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;i&gt;Database benchmarking for the real world interactive dashboard&lt;/i&gt;&lt;/p&gt;&lt;p&gt;Our new benchmarking methodology goes far beyond traditional metrics. It’s designed to answer the hard questions, like how your system behaves during rolling upgrades, node failures, or full data center outages.&lt;/p&gt;&lt;p&gt;The benchmark includes seven escalating phases of adversity in a single continuous run, each one introducing progressively harsher failure conditions and operational stress. The metrics provide insight on impact to resilience and sustained performance.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Baseline Performance:&lt;/b&gt; Measure steady-state throughput under normal conditions.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Internal Operational Stress:&lt;/b&gt; Simulate resource-intensive operations such as change data capture, full backups, schema changes, and rolling upgrades.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Disk Stalls:&lt;/b&gt; Randomly inject I/O freezes to evaluate storage resilience.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Network Failures:&lt;/b&gt; Simulate partial and full network failures preventing one partition from communicating with nodes in another partition.&amp;nbsp;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Node Restarts:&lt;/b&gt; Unpredictably reboot database nodes (1 at a time) to test recovery time and impact to performance.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Zone Outages:&lt;/b&gt; Take down an entire Availability Zone.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Regional Outages:&lt;/b&gt; Take down an entire Region.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Through all these phases, we measure throughput in transactions per minute (tpmC), latency (90th and 95 percentile), and recovery time to baseline.&lt;/p&gt;&lt;h2 id=&quot;The-benchmarking-dashboard:-See-resilience-in-action&quot;&gt;The benchmarking dashboard: See resilience in action&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;These results aren’t just published. We’ve built a live, &lt;a href=&quot;https://www.cockroachlabs.com/performance-under-adversity/dashboard/?referralid=blogs_pua_launch&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;interactive dashboard&lt;/u&gt;&lt;/a&gt; that lets you:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Explore performance trends:&lt;/b&gt; View graphs of throughput and latency over time.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Replay failure scenarios:&lt;/b&gt; Dive into node restarts, flaky storage, and regional outages.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;See resilience in action:&lt;/b&gt; Track CockroachDB’s self-healing in real time.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Now you can see how CockroachDB actually performs under the conditions your team cares about most.&lt;/p&gt;&lt;p&gt;&lt;!--$!--&gt;&lt;template data-dgst=&quot;BAILOUT_TO_CLIENT_SIDE_RENDERING&quot;&gt;&lt;/template&gt;&lt;!--/$--&gt;&lt;/p&gt;&lt;h2 id=&quot;Future-proof-at-scale-and-with-lower-TCO&quot;&gt;Future-proof at scale and with lower TCO&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;By combining resilience and performance into a single database benchmark and testing methodology, organizations can future-proof their database infrastructure at scale and without risking their operational data. Using CockroachDB, teams can deploy applications with confidence, because we are sharing the receipts that enable us to deliver consistent performance and state-of-the-art resilience. In turn this means lower TCO for organizations because any downtime negatively affects performance, time to market, and cost. That doesn’t include the broader impacts of loss in customer trust and satisfaction, and damage to brand and reputation.&lt;/p&gt;&lt;h2 id=&quot;Reproducing-the-benchmark-on-CockroachDB&quot;&gt;Reproducing the benchmark on CockroachDB&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;Like any robust benchmark, reproducibility is critical. We’ve made it easy to run the tests yourself. Our benchmarking methodology is fully documented and open. For our testing, we used version 25.1 of CockroachDB, distributed across three geographically separate regions, and ran automated tests to simulate failures like network partitions, disk stalls, and node restarts.&lt;/p&gt;&lt;p&gt;For architects, operators, and data leaders, this changes the game. You’re no longer left guessing how your database will behave during chaos. With “Performance under Adversity,” you get proof.&lt;/p&gt;&lt;p&gt;Proof that your apps will stay online.
Proof that you can scale without sharding.
Proof that you can survive and thrive under pressure.&lt;/p&gt;&lt;p&gt;Join us in setting a new standard for database performance.&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;i&gt;Disclaimer:&lt;/i&gt;&lt;/b&gt;&lt;i&gt; Results are from specific test setups. &lt;/i&gt;&lt;a href=&quot;https://www.cockroachlabs.com/performance-under-adversity/dashboard/?referralid=blogs_pua_launch&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;i&gt;&lt;u&gt;Try the dashboard yourself&lt;/u&gt;&lt;/i&gt;&lt;/a&gt;&lt;i&gt; to see how it fits your needs.&lt;/i&gt;&lt;/p&gt;&lt;div class=&quot;mb-8 rounded-3xl border border-solid border-[#D2D2D5] bg-[#F1F1F1] p-7&quot;&gt;&lt;h2 class=&quot;mb-4 text-display-md font-semibold text-electric-purple-500&quot;&gt;Measure what matters&lt;/h2&gt;&lt;p class=&quot;mb-4&quot;&gt;Traditional benchmarks only test when everything’s perfect. But you need to know what happens when everything fails. CockroachDB&#39;s new benchmark, &quot;Performance under Adversity,&quot; tests real-world scenarios: network partitions, regional outages, disk stalls, and so much more.&lt;/p&gt;&lt;div&gt;&lt;a href=&quot;https://www.cockroachlabs.com/performance-under-adversity/?referralid=blogs_pua_launch_bottom_card&quot;&gt;&lt;button class=&quot;inline-flex justify-center items-center gap-2 disabled:cursor-not-allowed border border-solid border-electric-purple-500 bg-electric-purple-500 text-white hover:bg-white hover:text-electric-purple-500 active:border-electric-purple-100 active:bg-electric-purple-100 active:text-white px-6 py-2.5 leading-tight rounded-full&quot;&gt;See it in action&lt;/button&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;</description><link>https://www.cockroachlabs.com/blog/database-testing-performance-under-adversity/</link><guid isPermaLink="false">https://www.cockroachlabs.com/blog/database-testing-performance-under-adversity/</guid></item><item><title>How to Deploy CockroachDB on Red Hat OpenShift Virtualization</title><description>&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/5skGkhgmrjeAOaaErJX6yD/710b34f99e62e2f7c53e23240790aae0/cockroachdb-red-hat-openshift-virtualization-tutorial.png&quot;&gt;&lt;img alt=&quot;CockroachDB x Red Hat logos on an abstract bluish purple background&quot; loading=&quot;lazy&quot; width=&quot;3840&quot; height=&quot;2160&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/5skGkhgmrjeAOaaErJX6yD/710b34f99e62e2f7c53e23240790aae0/cockroachdb-red-hat-openshift-virtualization-tutorial.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Rising VMware licensing costs and the uncertainty following the &lt;a href=&quot;https://investors.broadcom.com/news-releases/news-release-details/broadcom-completes-acquisition-vmware&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;Broadcom acquisition&lt;/u&gt;&lt;/a&gt; are prompting many enterprises to explore alternatives for their virtualization platforms. Simultaneously, more organizations than ever want to adopt cloud-native architectures and operational models, even as they grapple with strict on-premises and hybrid requirements.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.redhat.com/en/technologies/cloud-computing/openshift/virtualization&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;Red Hat OpenShift Virtualization&lt;/u&gt;&lt;/a&gt; stands out as a compelling alternative to VMware. It unifies traditional virtual machines (VMs) with container-based workloads under the same Kubernetes-driven platform—delivering cost efficiency, consistent operations, and open standards. Meanwhile, &lt;a href=&quot;https://www.cockroachlabs.com/product/overview/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;CockroachDB&lt;/u&gt;&lt;/a&gt; offers a distributed SQL database that is highly scalable, resilient, and truly cloud-native. Together, they provide a forward-looking solution to modernize infrastructure while still protecting mission-critical data and workflows.&lt;/p&gt;&lt;p&gt;This blog presents an in-depth technical blueprint for deploying CockroachDB on OpenShift Virtualization, referencing real-world validation tests, and context for our recently announced &lt;a href=&quot;https://www.prnewswire.com/news-releases/cockroach-labs-collaborates-with-red-hat-on-comprehensive-solution-for-vm-based-migrations-across-hybrid-cloud-environments-302460832.html&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;partnership with Red Hat&lt;/u&gt;&lt;/a&gt;. While most relevant to organizations in highly regulated industries and those seeking immediate VMware alternatives, the suggestions apply broadly to any enterprise requiring a cloud-native, future-proof virtualization strategy.&lt;/p&gt;&lt;h2 id=&quot;Why-Consider-OpenShift-Virtualization-as-a-VMware-Alternative?&quot;&gt;Why Consider OpenShift Virtualization as a VMware Alternative?&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;Since Broadcom’s acquisition of VMware, VMware has introduced new licensing models and cost structures that can be less than ideal, especially for environments still anchored on-premises. In addition, many enterprises running mission-critical workloads on VMware worry about renewed vendor lock-in, especially as they navigate modernization to containers and microservices. As an alternative to VMware, Red Hat’s OpenShift Virtualization offers a number of key advantages:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Unified Platform&lt;/b&gt;: Rather than managing virtualization separately from container orchestration, OpenShift Virtualization merges kernel-based virtual machines (KVMs) and Kubernetes containers into a single control plane, simplifying infrastructure and operational overhead.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Cost and Operational Efficiency&lt;/b&gt;: By consolidating onto a single platform, enterprises often reduce infrastructure sprawl, license expenses, and administrative complexity.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Hybrid Cloud-Readiness&lt;/b&gt;: Built on Red Hat OpenShift, clusters can span data centers, private clouds, and public clouds—facilitating a measured, step-wise migration away from purely on-premises environments.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Compliance and Control&lt;/b&gt;: For highly regulated industries (finance, healthcare, government), the ability to keep workloads on-premises under a standardized&amp;nbsp; platform—while selectively extending to the public cloud—delivers both agility and compliance.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Future-Proof Architecture&lt;/b&gt;: With virtualization and containers managed together, organizations can steadily refactor or containerize VMs over time without abrupt migrations, mitigating risk during modernization.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h2 id=&quot;Why-CockroachDB-for-VMware-to-OpenShift-Migrations?&quot;&gt;Why CockroachDB for VMware-to-OpenShift Migrations?&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/634NyFaqDEShiRHYT5Z8V8/d0c31dfbe286036a706ef4faf4fb8291/CockroachDB_features.png&quot;&gt;&lt;img alt=&quot;CockroachDB features: horizontal scalability, resilience &amp;amp; fault tolerance, strong consistency / ACID transaction guarantees, familiar SQL interface, cloud-native capabilities.&quot; loading=&quot;lazy&quot; width=&quot;3840&quot; height=&quot;2160&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/634NyFaqDEShiRHYT5Z8V8/d0c31dfbe286036a706ef4faf4fb8291/CockroachDB_features.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;CockroachDB is a cloud-native, distributed SQL database well-suited for hybrid and multi-cloud deployments. Its architecture is inherently designed to:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Scale Horizontally&lt;/b&gt;: New nodes can be added to the cluster as your needs grow—no complex re-sharding or forklift upgrades.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Resilience &amp;amp; Fault Tolerance&lt;/b&gt;: Built-in replication using the Raft consensus protocol ensures automatic failover with minimal operator intervention.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Strong Consistency&lt;/b&gt;: Retains ACID transactional guarantees across distributed nodes, vital for mission-critical systems.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Familiar SQL Interface&lt;/b&gt;: Postgres-compatible queries minimize developer retraining and reduce adoption friction.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Cloud-Native Capabilities&lt;/b&gt;: Automated rebalancing, rolling upgrades, and integration with orchestration tools like Kubernetes.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3 id=&quot;Benefits-in-an-OpenShift-Virtualization-Context&quot;&gt;Benefits in an OpenShift Virtualization Context&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Shared-Nothing Architecture&lt;/b&gt;: Each CockroachDB node runs independently with its own CPU, memory, and storage, aligning seamlessly with the VM-based approach in OpenShift Virtualization.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Operational Consistency&lt;/b&gt;: Whether on-premises or in the cloud, CockroachDB’s operational model stays consistent—fitting well into a hybrid environment managed by OpenShift.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Reduced Complexity in Migrations&lt;/b&gt;: CockroachDB’s built-in backup and restore features ease data transfer from VMware-based environments to OpenShift Virtualization VMs.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3 id=&quot;Validating-CockroachDB-on-OpenShift-Virtualization&quot;&gt;Validating CockroachDB on OpenShift Virtualization&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;p&gt;While testing CockroachDB, I validated performance, availability, and deployment simplicity on OpenShift Virtualization. My own evaluations covered:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Seamless Installation&lt;/b&gt;: CockroachDB installs cleanly on Linux VMs provisioned by OpenShift Virtualization.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;High Availability&lt;/b&gt;: Node failure tests confirmed automatic failover and rebalancing without downtime for read/write workloads.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Performance at Scale&lt;/b&gt;: Even under heavier TPC-C workloads (with 1,750 warehouses in testing), CockroachDB handled throughput without performance bottlenecks.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Easy Observability&lt;/b&gt;: Standard metrics endpoints integrate smoothly with Prometheus/Grafana or other enterprise monitoring tools.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;These tests gave me confidence that CockroachDB is ready for deployments in OpenShift Virtualization environments, even for mission-critical apps.&lt;/p&gt;&lt;h2 id=&quot;CockroachDB-on-OpenShift-Virtualization:-Overall-Architecture&quot;&gt;CockroachDB on OpenShift Virtualization: Overall Architecture&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;OpenShift Virtualization extends the Red Hat OpenShift platform, allowing you to run both containers and virtual machines under a unified Kubernetes-based management plane. In the illustration below, we highlight not only the CockroachDB VMs but also the worker nodes, the KVM hypervisor layer, and essential components of the OpenShift ecosystem that orchestrate and manage these workloads.&lt;/p&gt;&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/2wLjjkgnG2zE2F2ZXyfbvs/a9a68aefdacc34173c5f5f60d3fc597c/Red_Hat_OpenShift_Virtualization_Architecture_diagram.png&quot;&gt;&lt;img alt=&quot;Architecture diagram showing how you can deploy CockroachDB on Red Hat OpenShift Virtualization&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;2346&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/2wLjjkgnG2zE2F2ZXyfbvs/a9a68aefdacc34173c5f5f60d3fc597c/Red_Hat_OpenShift_Virtualization_Architecture_diagram.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3 id=&quot;Key-Components&quot;&gt;Key Components&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;p&gt;&lt;b&gt;Red Hat OpenShift Platform&lt;/b&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Provides the Kubernetes-based control plane for container orchestration, networking, and security.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Includes OpenShift Virtualization, enabling you to run KVM-based virtual machines alongside containers.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;b&gt;Worker Nodes (RHEL CoreOS)&lt;/b&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Each worker node runs a KVM hypervisor and the virtualization components.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Labeled for scheduling to ensure each CockroachDB VM resides on a different physical node.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;b&gt;Dedicated CockroachDB VMs&lt;/b&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Each VM (e.g., &lt;code&gt;crdb-node-1&lt;/code&gt;, &lt;code&gt;crdb-node-2&lt;/code&gt;, &lt;code&gt;crdb-node-3&lt;/code&gt;) hosts a CockroachDB node.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Deployed on RHEL/CentOS&amp;nbsp;or another supported OS.
Leverages local or persistent storage volumes to maintain the shared-nothing architecture.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;b&gt;Networking Services&lt;/b&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Headless Service &lt;/b&gt;(&lt;code&gt;crdb-internal&lt;/code&gt;): Enables node discovery via stable DNS entries within the cluster.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;LoadBalancer Service &lt;/b&gt;(&lt;code&gt;crdb-loadbalancer&lt;/code&gt;): Facilitates external SQL traffic (port &lt;code&gt;26257&lt;/code&gt;) and UI/metrics (port &lt;code&gt;8080&lt;/code&gt;) to all CockroachDB nodes.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;b&gt;Storage Layer&lt;/b&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Local SSDs or a supported Persistent Volume (PV) solution.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Must provide POSIX compliance and sufficient throughput.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;b&gt;OpenShift API / Management Plane&lt;/b&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Coordinates all scheduling, networking, and lifecycle actions across the cluster.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Exposes a single interface for both container-based workloads and VMs.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;By encapsulating the virtualization layer within OpenShift, enterprises unify both containerized and traditional VM workloads under consistent tooling. CockroachDB’s distributed nature fits neatly into this framework, ensuring strong fault tolerance and near-linear scalability even as you transition away from traditional VMware-based environments.&lt;/p&gt;&lt;h3 id=&quot;Architectural-Summary-CockroachDB-on-OpenShift-Virtualization&quot;&gt;Architectural Summary CockroachDB on OpenShift Virtualization&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;p&gt;&lt;b&gt;Shared-Nothing Architecture in Action&lt;/b&gt;&lt;/p&gt;&lt;p&gt;CockroachDB’s shared-nothing model is fully realized in this deployment model:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Each VM is pinned to its own worker node (using labels and scheduling constraints).&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;CPU, memory, and SSD/local storage remain dedicated to each VM, eliminating noisy-neighbor issues commonly found in resource-shared deployments.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Network communications rely on standard Kubernetes services for node discovery and client ingress.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;b&gt;Core Components of CockroachDB&lt;/b&gt;&lt;/p&gt;&lt;p&gt;CockroachDB consists of a number of key components that allow us to provide the always-on availability, operational resilience, and performance at scale that our customers have come to know and depend on. A few are particularly important to call out when leveraging CockroachDB with OpenShift Virtualization&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;SQL Engine: &lt;/b&gt;Provides a powerful SQL interface compatible with PostgreSQL.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Transactional Key-Value Store: &lt;/b&gt;Uses the Raft protocol for replication and consensus-driven writes.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Data Distribution &amp;amp; Replication: &lt;/b&gt;Dynamically balances data ranges across nodes for optimal performance and fault tolerance.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h2 id=&quot;Deployment-Considerations&quot;&gt;Deployment Considerations&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;h3 id=&quot;1.-Network-Configuration&quot;&gt;1. Network Configuration&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Ports&lt;/b&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Port &lt;code&gt;26257&lt;/code&gt; for SQL and inter-node traffic.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Port &lt;code&gt;8080&lt;/code&gt; for the DB Console and metrics.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Firewall:&lt;/b&gt; Ensure these ports are open on each VM to allow node-to-node communications.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Service Types&lt;/b&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Headless&lt;/b&gt; (no ClusterIP) for internal node discovery.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;LoadBalancer&lt;/b&gt; for external access by apps or DBAs.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3 id=&quot;2.-Storage-Requirements&quot;&gt;2. Storage Requirements&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Local SSD or Fast Persistent Storage:&lt;/b&gt; CockroachDB depends heavily on low-latency local storage for transaction logs and data files.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;POSIX Compliance:&lt;/b&gt; Storage must be POSIX-compliant to ensure ACID guarantees under crash recovery, strongly recommend using SSDs.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3 id=&quot;3.-High-Availability-&amp;amp;-Resilience&quot;&gt;3. High Availability &amp;amp; Resilience&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Node Affinity&lt;/b&gt;: Label worker nodes to ensure each CockroachDB VM is scheduled separately, avoiding single-point-of-failure scenarios.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Automatic Failover&lt;/b&gt;: If a VM or node fails, CockroachDB automatically re-replicates data to remaining nodes.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3 id=&quot;4.-Load-Balancing&quot;&gt;4. Load Balancing&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Round-Robin LB&lt;/b&gt;: The Kubernetes LoadBalancer typically distributes incoming SQL queries across all healthy nodes.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Internal Connectivity&lt;/b&gt;: The headless service ensures the CockroachDB processes use stable DNS names for Raft replication.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;Summary-of-the-Technical-Deployment-Steps&quot;&gt;Summary of the Technical Deployment Steps&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;Below is a quick recap of the recommended approach:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Node Preparation&lt;/b&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Label three OpenShift worker nodes (e.g., &lt;code&gt;node-role.kubernetes.io/crdb-node-1=true&lt;/code&gt;) so that each CockroachDB VM can be pinned to a distinct node.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Create a dedicated namespace &lt;code&gt;cockroachdb&lt;/code&gt; for resources.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Networking Setup&lt;/b&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Headless Service&lt;/b&gt; (&lt;code&gt;crdb-internal&lt;/code&gt;): No &lt;code&gt;clusterIP&lt;/code&gt;, used for internal DNS resolution among the CockroachDB nodes.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;LoadBalancer Service&lt;/b&gt; (&lt;code&gt;crdb-loadbalancer&lt;/code&gt;): Exposes external connections to port &lt;code&gt;26257&lt;/code&gt; (SQL) and &lt;code&gt;8080&lt;/code&gt; (UI).&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;VM Provisioning&lt;/b&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Create three VMs via the OpenShift Virtualization console (e.g., &lt;code&gt;crdb-node-1&lt;/code&gt;, &lt;code&gt;crdb-node-2&lt;/code&gt;, &lt;code&gt;crdb-node-3&lt;/code&gt;) using the CentOS 9 image.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Allocate resources per CockroachDB production best practices (refer to the &lt;a href=&quot;https://www.cockroachlabs.com/docs/stable/recommended-production-settings&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;production checklist&lt;/u&gt;&lt;/a&gt;).&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Update firewall rules (if necessary) to open ports &lt;code&gt;26257&lt;/code&gt; and &lt;code&gt;8080&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Adjust SELinux settings if needed to ensure the CockroachDB processes can run and bind to required ports.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;CockroachDB Installation&lt;/b&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Download CockroachDB binaries on each VM.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Place the &lt;code&gt;cockroach&lt;/code&gt; binary in &lt;code&gt;/usr/local/bin&lt;/code&gt; and ensure the PATH is updated.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Cluster Initialization&lt;/b&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Start each node with &lt;code&gt;--insecure&lt;/code&gt; or TLS flags as desired, specifying &lt;code&gt;--join&lt;/code&gt; to the internal FQDNs for the other nodes.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;On one node, run &lt;code&gt;cockroach init&lt;/code&gt; to bootstrap the cluster.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Validate using &lt;code&gt;cockroach sql --execute=&quot;SHOW DATABASES;&quot;&lt;/code&gt; to confirm a healthy cluster.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;External Connectivity&lt;/b&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Retrieve the LoadBalancer external IP (&lt;code&gt;oc get svc crdb-loadbalancer -n cockroachdb&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Connect from outside using &lt;code&gt;cockroach sql --host=&amp;lt;LoadBalancer-IP&amp;gt;:26257&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Verification and Testing&lt;/b&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Run basic DDL, DML, and transaction operations to confirm cluster stability.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Confirm high availability by stopping one node’s CockroachDB process; the cluster should remain writable.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h2 id=&quot;Reliability-and-Performance-Observations&quot;&gt;Reliability and Performance Observations&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;h3 id=&quot;1.-Test-Results-at-a-Glance&quot;&gt;1. Test Results at a Glance&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;No Installation Barriers&lt;/b&gt;: The CockroachDB nodes came online without errors.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Connectivity&lt;/b&gt;: Internal and external clients could connect via the configured services.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Basic SQL&lt;/b&gt;: DDL, DML, and transactional statements worked as expected with ACID guarantees.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;High Availability&lt;/b&gt;: Node shutdown or partition tests showed zero downtime for read/write workloads; automatic rejoin upon node recovery.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Performance&lt;/b&gt;: With TPC-C–style workloads at moderate scale (1,750 warehouses), the cluster maintained stable throughput and latency even as I scaled the cluster by adding nodes and also introducing node failures/network partitions.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3 id=&quot;2.-Monitoring&quot;&gt;2. Monitoring&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;p&gt;CockroachDB provides a &lt;a href=&quot;https://www.cockroachlabs.com/docs/stable/ui-overview.html&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;DB Console&lt;/u&gt;&lt;/a&gt; (port &lt;code&gt;8080&lt;/code&gt;) for real-time cluster stats and integrates seamlessly with &lt;a href=&quot;https://www.cockroachlabs.com/docs/stable/monitor-cockroachdb-with-prometheus&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;Prometheus&lt;/u&gt;&lt;/a&gt; for metrics collection. During testing, no issues arose in scraping or visualizing performance data.&lt;/p&gt;&lt;h3 id=&quot;3.-Rolling-Upgrades&quot;&gt;3. Rolling Upgrades&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;p&gt;Upgrading CockroachDB nodes individually can be done without cluster downtime. This is critical for production environments that demand continuous availability.&lt;/p&gt;&lt;h2 id=&quot;Migration-from-VMware-to-OpenShift-Virtualization&quot;&gt;Migration from VMware to OpenShift Virtualization&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;h3 id=&quot;1.-Key-Considerations&quot;&gt;1. Key Considerations&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Risk Management&lt;/b&gt;: Minimal disruption is paramount for mission-critical apps. CockroachDB’s automated data replication and zero-downtime approach to adding/removing nodes reduce risk during migrations.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Phased Approach&lt;/b&gt;: Migrate certain workloads or lines-of-business first, then gradually decommission VMware clusters.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Backup &amp;amp; Restore&lt;/b&gt;: CockroachDB’s built-in backup tools simplify data transfers from existing databases.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Kubernetes familiarity&lt;/b&gt;: Teams familiar with VMware need training in Kubernetes-based virtualization concepts. Early pilots help build internal knowledge.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3 id=&quot;2.-Practical-Steps&quot;&gt;2. Practical Steps&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Set Up OpenShift Virtualization&lt;/b&gt;: Create an OpenShift environment with worker nodes sized appropriately for the new VM-based cluster.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Network &amp;amp; Storage Alignment&lt;/b&gt;: Ensure that your target environment can provide the same or better performance characteristics than VMware (especially regarding storage IOPS and network throughput).&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Deploy CockroachDB&lt;/b&gt;: Follow the steps outlined above or the official deployment guide.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Data Migration&lt;/b&gt;: Use CockroachDB’s &lt;code&gt;IMPORT&lt;/code&gt;, &lt;code&gt;BACKUP/RESTORE&lt;/code&gt;, or third-party ETL tools to seed data from legacy systems.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Validation &amp;amp; Cutover&lt;/b&gt;: Conduct acceptance tests against the new CockroachDB cluster. Transition application connections to the newly deployed environment once validated.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h2 id=&quot;Key-Takeaways&quot;&gt;Key Takeaways&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Cost-Effective and Future-Proof&lt;/b&gt;: Moving away from VMware to OpenShift Virtualization provides significant cost and operational advantages.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Cloud-Native Database&lt;/b&gt;: CockroachDB complements this modernization by offering a highly resilient, horizontally scalable SQL platform that fits both on-premises and across multiple clouds.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Validated Architecture&lt;/b&gt;: My testing was able to give me confidence and confirm that CockroachDB runs reliably on OpenShift Virtualization with minimal operational friction and feels just as similar to deploying CockroachDB on cloud VMs.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Streamlined Migration&lt;/b&gt;: Enterprises can migrate mission-critical workloads at their own pace, leveraging proven backup/restore flows and phased cutovers.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;As new complexities and uncertainties arise, organizations seeking flexibility, performance, and cost savings will find a robust alternative in Red Hat OpenShift Virtualization, powered by CockroachDB’s distributed SQL capabilities. This approach not only addresses immediate licensing and lock-in concerns, but also paves the way for hybrid and multi-cloud strategies that are increasingly essential in modern IT landscapes.&lt;/p&gt;&lt;div class=&quot;mb-8 rounded-3xl border border-solid border-[#D2D2D5] bg-[#F1F1F1] p-7&quot;&gt;&lt;h2 class=&quot;mb-4 text-display-md font-semibold text-electric-purple-500&quot;&gt;Try CockroachDB Today&lt;/h2&gt;&lt;p class=&quot;mb-4&quot;&gt;Spin up your first CockroachDB Cloud cluster in minutes. Start with $400 in free credits.
Or get a free 30-day trial of CockroachDB Enterprise on self-hosted environments.&lt;/p&gt;&lt;div&gt;&lt;a href=&quot;https://cockroachlabs.cloud/signup&quot;&gt;&lt;button class=&quot;inline-flex justify-center items-center gap-2 disabled:cursor-not-allowed border border-solid border-electric-purple-500 bg-electric-purple-500 text-white hover:bg-white hover:text-electric-purple-500 active:border-electric-purple-100 active:bg-electric-purple-100 active:text-white px-6 py-2.5 leading-tight rounded-full&quot;&gt;Try Cloud Today&lt;/button&gt;&lt;/a&gt;&lt;a href=&quot;https://cockroachlabs.cloud/signup?experience=enterprise&quot;&gt;&lt;button class=&quot;inline-flex justify-center items-center gap-2 disabled:cursor-not-allowed border border-solid border-electric-purple-500 bg-electric-purple-500 text-white hover:bg-white hover:text-electric-purple-500 active:border-electric-purple-100 active:bg-electric-purple-100 active:text-white px-6 py-2.5 leading-tight rounded-full&quot;&gt;Try Self-Hosted Today&lt;/button&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;</description><link>https://www.cockroachlabs.com/blog/red-hat-openshift-virtualization-tutorial/</link><guid isPermaLink="false">https://www.cockroachlabs.com/blog/red-hat-openshift-virtualization-tutorial/</guid></item><item><title>MOLT Verify: Ensuring Data Integrity in Database Migrations</title><description>&lt;p&gt;Database migrations are complex, and ensuring the migrated data is 100% correct is critical. After all, a migration isn’t over until you feel confident and comfortable cutting over to the new infrastructure. To streamline migrations, Cockroach Labs created the MOLT (Migrate Off Legacy Technology) toolkit, which includes three tools that improve different parts of the user journey.&lt;/p&gt;&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/33tCFEYLlklRIiKQqLkXq0/542bbae02ed71756cb5176144511e574/molt-toolkit.png&quot;&gt;&lt;img alt=&quot;Table explaining the three tools in the MOLT (Migrate Off Technology) suite, and how it corresponds to the user journey. The three tools are MOLT Convert (previously MOLT Schema Conversion Tool), MOLT Fetch, and MOLT Verify.&quot; loading=&quot;lazy&quot; width=&quot;2699&quot; height=&quot;1080&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/33tCFEYLlklRIiKQqLkXq0/542bbae02ed71756cb5176144511e574/molt-toolkit.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Ultimately, we built MOLT Verify to give engineers confidence when moving data from legacy databases to CockroachDB. In this deep dive, we’ll explore what MOLT Verify is, how it works under the hood, and how to use it effectively for seamless migrations. We’ll cover its role in the migration process, the architecture and integration with databases, how it verifies data consistency, and best practices for engineers.&lt;/p&gt;&lt;p&gt;To learn more about the rest of the MOLT tools, check out our blog on &lt;a href=&quot;https://www.cockroachlabs.com/blog/molt-schema-conversion-tool/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;MOLT Convert&lt;/u&gt;&lt;/a&gt; (previously MOLT SCT), and our colleagues’ post on &lt;a href=&quot;https://www.cockroachlabs.com/blog/molt-fetch-cockroachdb/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;MOLT Fetch&lt;/u&gt;&lt;/a&gt;.&lt;/p&gt;&lt;h2 id=&quot;What-is-MOLT-Verify?&quot;&gt;What is MOLT Verify?&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/6v3HYJcGgLvGEnavsojUDR/17ea6ba1371c31fba3fe8aaf67c95099/cockroachdb-molt-verify-thumbnail.png&quot;&gt;&lt;img alt=&quot;MOLT Verify blog thumbnail showing one database equalling the new CockroachDB instance.&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1080&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/6v3HYJcGgLvGEnavsojUDR/17ea6ba1371c31fba3fe8aaf67c95099/cockroachdb-molt-verify-thumbnail.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;MOLT Verify is a data validation tool in Cockroach Labs’ migration toolkit. Its primary role is to compare a source database (e.g. PostgreSQL or MySQL) against a CockroachDB target to ensure that everything matches after migration. MOLT Verify automatically compares the source and target databases at multiple levels—schema and row-level data validation. This prevents the risk of silent corruption, missing records, or mismatches, and offers an automated, scalable, and repeatable way to validate database migrations in minutes instead of days.&lt;/p&gt;&lt;p&gt;The tool performs a series of checks so you feel confident that your new CockroachDB cluster faithfully mirrors the original database:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Table verification:&lt;/b&gt; It confirms that each table in the source has a corresponding table in the target with the same schema definition (table name, number of columns, etc.)&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Column definition verification:&lt;/b&gt; For each table, it validates that column names, data types, constraints, nullability, and other attributes match between source and target. This catches any schema drift or type conversion issues from the migration.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Row data verification:&lt;/b&gt; It compares the actual data in each table, row-by-row, to ensure every value in the source appears identically in CockroachDB.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3 id=&quot;Supported-databases&quot;&gt;Supported databases&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;p&gt;MOLT Verify currently supports verifying data from &lt;a href=&quot;https://www.cockroachlabs.com/docs/molt/molt-overview#:~:text=MOLT%20Verify%20checks%20for%20discrepancies,are%20PostgreSQL%2C%20MySQL%2C%20and%20CockroachDB&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;PostgreSQL, Oracle, and MySQL sources&lt;/u&gt;&lt;/a&gt; (as well as CockroachDB itself) against a CockroachDB cluster – covering the most common migration paths. It’s provided as &lt;a href=&quot;https://www.cockroachlabs.com/docs/molt/molt-verify#installation&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;a standalone CLI tool&lt;/u&gt;&lt;/a&gt; (with downloadable binaries or a Docker image) that you run during migration.&lt;/p&gt;&lt;h2 id=&quot;Key-Benefits-of-MOLT-Verify&quot;&gt;Key Benefits of MOLT Verify&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;MOLT Verify acts as a safety net in the migration workflow, dramatically reduce the risk of data corruption or loss when migrating off legacy systems. After you’ve loaded data into CockroachDB (whether via bulk import or a live replication tool), running MOLT Verify lets you catch any missing records, mismatched values, or schema inconsistencies &lt;i&gt;before&lt;/i&gt; you cut over your application.&lt;/p&gt;&lt;p&gt;In a &lt;a href=&quot;https://www.cockroachlabs.com/docs/stable/migration-overview#:~:text=2,1000%20rows%29%2C%20stop&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;typical migration plan&lt;/u&gt;&lt;/a&gt;, you would use MOLT Verify as a final validation step: for example, after all data is replicated to CockroachDB, run MOLT Verify to validate consistency, then proceed with the cutover once everything matches.&lt;/p&gt;&lt;p&gt;In particular, we recognized that large-scale migrations are uniquely challenging with regard to validation due to the sheer volume of data, and manual validation is virtually impossible in such scenarios. MOLT Verify, with its automated verification layer, checks every record in every row in every table, ensuring that the migration is accurate before production cutover.&lt;/p&gt;&lt;p&gt;The benefits of MOLT Verify include:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Cutover without fear of losing or corrupting data&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Faster automated data validation checks&amp;nbsp;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Validation beyond row counts: schema consistency, data integrity, row-level discrepancies&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Designed for large-scale distributed migrations, validate billions of records systematically and efficiently&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;Architecture:-How-MOLT-Verify-Integrates-with-CockroachDB-and-Source-Databases&quot;&gt;Architecture: How MOLT Verify Integrates with CockroachDB and Source Databases&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;Under the hood, MOLT Verify is built as a standalone tool that connects to both the source and target databases and orchestrates a comparison between them. This design means it can work with heterogeneous systems and will impose minimal load on the source and target clusters, beyond standard SQL reads. Ultimately, how you choose to &lt;a href=&quot;https://www.cockroachlabs.com/docs/molt/molt-verify#flags&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;handle concurrency&lt;/u&gt;&lt;/a&gt; will affect the load placed on your clusters.&lt;/p&gt;&lt;p&gt;Key points about MOLT Verify’s architecture and integration:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Standard Database Connections:&lt;/b&gt; MOLT Verify uses native connection protocols for each database. For example, it connects to CockroachDB using the &lt;a href=&quot;https://www.cockroachlabs.com/docs/stable/postgresql-compatibility&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;PostgreSQL wire protocol&lt;/u&gt;&lt;/a&gt; (since Cockroach speaks &lt;a href=&quot;https://www.cockroachlabs.com/blog/postgresql-compatible-database-cockroachdb/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;Postgres-compatible SQL&lt;/u&gt;&lt;/a&gt;), and connects to MySQL through the MySQL protocol. This means it doesn’t require any special plugins on the databases; if you can connect via a SQL client, MOLT Verify can connect too.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Multi-Database Support via Abstraction:&lt;/b&gt; The tool is designed with an abstraction layer to handle different database flavors. It knows how to retrieve metadata and data from each supported source. It treats the source as the “truth” and CockroachDB as the destination to verify.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Schema Mapping and Assumptions:&lt;/b&gt; Because different databases have different ways to organize schemas, MOLT Verify makes some assumptions to simplify the comparison. For example, when comparing MySQL to CockroachDB, it assumes you’re comparing one MySQL database schema to a CockroachDB database’s public schema. MySQL’s notion of a database is analogous to a schema or namespace in Postgres/Cockroach. So if you have multiple schemas or databases to migrate, you would run MOLT Verify separately for each logical schema. This one-to-one mapping ensures the tool knows which tables to line up between source and target.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;External Binary with CockroachDB Integration:&lt;/b&gt; Cockroach Labs distributes MOLT Verify as part of the &lt;a href=&quot;https://www.cockroachlabs.com/docs/molt/molt-verify#installation&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;MOLT CLI&lt;/u&gt;&lt;/a&gt;. The CLI package includes a &lt;code&gt;molt&lt;/code&gt; command (and a helper binary called &lt;code&gt;replicator&lt;/code&gt; used for live replication). You can download it for Linux, Mac, or Windows, or run it via a Docker container.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Parallel and Distributed Processing:&lt;/b&gt; Architecturally, MOLT Verify employs a multi-threaded design to handle large schemas efficiently. This is critical for integration with CockroachDB, which is a distributed database – MOLT Verify can generate multiple concurrent read requests that CockroachDB will handle on its distributed nodes, thereby speeding up the scan of large tables. Similarly, for a source like Postgres or MySQL, multiple threads can pull data from different tables (or different parts of the same table) concurrently, thus reducing overall runtime.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;In summary, the design allows MOLT Verify to slot into migration workflows without requiring special infrastructure – if you can run the binary and connect to your databases, you can use MOLT Verify.&lt;/p&gt;&lt;h2 id=&quot;Verification-Mechanism:-How-MOLT-Verify-Ensures-Data-Consistency&quot;&gt;Verification Mechanism: How MOLT Verify Ensures Data Consistency&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/2A4krazNM2FxlEQIx54Axo/5d2dbab4ce8bd8403f234653449e38c0/MOLT-Verify-Data-Validation_Workflow.png&quot;&gt;&lt;img alt=&quot;A diagram show the MOLT Verify: Data Validation Workflow. The source database is the input, which goes into the MOLT Verify CLI. The MOLT Verify CLI consists of checking schema match, column definition match, and row-by-row data match. Then checking with the target database (CockroachDB).&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;748&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/2A4krazNM2FxlEQIx54Axo/5d2dbab4ce8bd8403f234653449e38c0/MOLT-Verify-Data-Validation_Workflow.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;MOLT Verify’s core responsibility is to ensure data consistency and correctness during migration. It does so by performing a thorough comparison at multiple levels of the database, flagging any discrepancies. Let’s break down the verification mechanism in detail.&lt;/p&gt;&lt;h3 id=&quot;Schema-and-Table-Verification&quot;&gt;Schema and Table Verification&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;p&gt;The first thing MOLT Verify checks is that the schema has been migrated correctly. It retrieves the list of tables from the source and the target, and verifies that every expected table exists on CockroachDB with the same schema structure. This includes comparing table names and primary keys, and then drilling down into columns. For each table, it checks all columns to ensure the column names, data types, and attributes (&lt;code&gt;NULL&lt;/code&gt;/defaults, constraints, etc.) match between source and target. If, for example, a column in MySQL was an &lt;code&gt;INT&lt;/code&gt; but the target schema accidentally used a &lt;code&gt;STRING&lt;/code&gt;, or if a &lt;code&gt;NOT NULL&lt;/code&gt; constraint was dropped, MOLT Verify will catch those discrepancies.&lt;/p&gt;&lt;h3 id=&quot;Row-Data-Verification&quot;&gt;Row Data Verification&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;p&gt;After confirming the schemas align, MOLT Verify moves on to the data itself. This is the most intensive part: it compares the contents of each table row-by-row between the source and CockroachDB. Under the hood, MOLT Verify will typically perform an ordered scan of the table on each database (often using the primary key order to have a consistent traversal) and then compare the rows as it goes. Essentially, it performs a synchronized read from source and target and checks that for every primary key (or unique identifier) present in the source, the target has a row with identical values.&lt;/p&gt;&lt;p&gt;MOLT Verify will report summary counts of matched vs mismatched data for each table. For example, after running, you might see an output (in JSON or log format) per table indicating how many rows were successfully verified and how many differences were found. An example summary line looks like this:&lt;/p&gt;&lt;div class=&quot;blog-codeblock mb-4 font-roboto-mono&quot;&gt;&lt;div class=&quot; [&amp;amp;&gt;div&gt;span&gt;code]:bg-transparent [&amp;amp;&gt;div&gt;span&gt;code]:text-white&quot;&gt;&lt;div class=&quot;sc-gsDLFA oicjj&quot;&gt;&lt;span style=&quot;font-size:inherit;font-family:inherit;background:#282a36;color:#f8f8f2;border-radius:3px;display:flex;line-height:1.4285714285714286;overflow-x:auto;white-space:pre&quot;&gt;&lt;code style=&quot;white-space:pre;font-size:inherit;font-family:inherit;line-height:1.6666666666666667;padding:8px&quot;&gt;{&quot;table_schema&quot;:&quot;public&quot;,
&quot;table_name&quot;:&quot;common_table&quot;,
&quot;num_truth_rows&quot;:6,
&quot;num_success&quot;:3,
&quot;num_missing&quot;:2,
&quot;num_mismatch&quot;:1,
&quot;num_extraneous&quot;:2, 
... 
&quot;message&quot;:&quot;finished row verification&quot;}&lt;/code&gt;&lt;/span&gt;&lt;button aria-label=&quot;Copy Code&quot; type=&quot;button&quot; class=&quot;sc-bdvvNz SnCde&quot;&gt;&lt;svg class=&quot;icon&quot; viewBox=&quot;0 0 384 512&quot; width=&quot;16pt&quot; height=&quot;16pt&quot; fill=&quot;#f8f8f2&quot;&gt;&lt;path d=&quot;M280 240H168c-4.4 0-8 3.6-8 8v16c0 4.4 3.6 8 8 8h112c4.4 0 8-3.6 8-8v-16c0-4.4-3.6-8-8-8zm0 96H168c-4.4 0-8 3.6-8 8v16c0 4.4 3.6 8 8 8h112c4.4 0 8-3.6 8-8v-16c0-4.4-3.6-8-8-8zM112 232c-13.3 0-24 10.7-24 24s10.7 24 24 24 24-10.7 24-24-10.7-24-24-24zm0 96c-13.3 0-24 10.7-24 24s10.7 24 24 24 24-10.7 24-24-10.7-24-24-24zM336 64h-80c0-35.3-28.7-64-64-64s-64 28.7-64 64H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM192 48c8.8 0 16 7.2 16 16s-7.2 16-16 16-16-7.2-16-16 7.2-16 16-16zm144 408c0 4.4-3.6 8-8 8H56c-4.4 0-8-3.6-8-8V120c0-4.4 3.6-8 8-8h40v32c0 8.8 7.2 16 16 16h160c8.8 0 16-7.2 16-16v-32h40c4.4 0 8 3.6 8 8v336z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;In this example, MOLT Verify is reporting that out of 6 rows in the source (“truth”) table, 3 rows matched exactly, 2 rows were missing on the target, 1 row had mismatched data, and 2 extraneous rows were found on the target. Similar statistics are output for each table.&lt;/p&gt;&lt;p&gt;This row-by-row comparison mechanism is essentially performing a massive diff between the two databases. Importantly, MOLT Verify does this in a streaming and memory-efficient way. It processes a chunk of rows at a time (by default 20,000 rows per batch) rather than loading an entire table into memory. It reads a batch from the source and the corresponding batch from the target, compares them, then moves on.&lt;/p&gt;&lt;h3 id=&quot;Handling-Live-Data-Changes&quot;&gt;Handling Live Data Changes&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;p&gt;In a migration scenario, you might be running MOLT Verify while changes are still trickling into the source (and being replicated to the target). If the source database is still “live,” it’s possible a row could change between the time you read it from the source and the time you read it from the target (or between batches). MOLT Verify accounts for this with the &lt;a href=&quot;https://www.cockroachlabs.com/docs/molt/molt-verify#flags&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;--live flag&lt;/u&gt;&lt;/a&gt;. When you run with the &lt;code&gt;--live&lt;/code&gt; flag, the tool will automatically retry verification on any rows that didn’t match before declaring them as errors. This is useful during continuous replication or minimal-downtime migrations – it prevents false alarms due to timing lags. If after a retry the row still doesn’t match, then it’s a true mismatch. The output even tracks a &lt;code&gt;num_live_retry&lt;/code&gt; count to show how many mismatches were fixed by a later retry (so you know how much data was in flux).&lt;/p&gt;&lt;p&gt;There is also a &lt;code&gt;--continuous&lt;/code&gt; mode, which tells MOLT Verify to run in a loop continuously – essentially, once it finishes verifying all tables, it will start over until you stop it. This could be used to constantly monitor data consistency during a long-running migration, giving you up-to-date information on whether the target is in sync.&lt;/p&gt;&lt;p&gt;Get all the details in our &lt;a href=&quot;https://www.cockroachlabs.com/docs/molt/molt-verify&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;documentation&lt;/u&gt;&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;i&gt;Check out MOLT Verify in action as technical evangelist, Rob Reid validates the migration from his PostgreSQL database to CockroachDB:&lt;/i&gt;&lt;/p&gt;&lt;p&gt;&lt;!--$!--&gt;&lt;template data-dgst=&quot;BAILOUT_TO_CLIENT_SIDE_RENDERING&quot;&gt;&lt;/template&gt;&lt;!--/$--&gt;&lt;/p&gt;&lt;h2 id=&quot;Best-Practices:-Tips-for-Using-MOLT-Verify-Effectively&quot;&gt;Best Practices: Tips for Using MOLT Verify Effectively&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;To get the most out of MOLT Verify and ensure a smooth migration, consider the following best practices and recommendations:&lt;/p&gt;&lt;h3 id=&quot;Run-Verification-at-Key-Points-in-the-Migration&quot;&gt;Run Verification at Key Points in the Migration&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;p&gt;Don’t wait until the final switch to run MOLT Verify for the first time. It’s wise to use it in earlier stages as well. For example, after an initial test data load, run MOLT Verify on a subset of data to catch any glaring schema or data issues. During iterative testing (the “validation” phase of migration), use it on smaller samples. By the time you do the full migration, you’ll be familiar with the tool and have confidence that it will likely report zero issues.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Always run a final verification on the full dataset right before cutover (or as part of the cutover) – this is your final gate to ensure consistency. If using continuous replication, keep MOLT Verify running with &lt;code&gt;--continuous&lt;/code&gt; so you have up-to-date info, and then do one last run in non-continuous mode when replication is stopped.&lt;/p&gt;&lt;h3 id=&quot;Minimize-Changes-for-the-Final-Verification&quot;&gt;Minimize Changes for the Final Verification&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;p&gt;While MOLT Verify can work with live data, you will get the cleanest results if the source is &lt;b&gt;static or nearly static&lt;/b&gt; during the verification. Try to schedule the verification during a read-only window on the source if possible. Many teams will stop application writes, let the replication catch up, then run MOLT Verify on a static snapshot of data. This avoids the complexity of transient mismatches. If you must verify while changes are happening, definitely use &lt;code&gt;--live&lt;/code&gt; to filter out false mismatches, and possibly run multiple passes (&lt;code&gt;--continuous&lt;/code&gt;) until the mismatches go to zero.&lt;/p&gt;&lt;h3 id=&quot;Tune-Concurrency-and-Batching-for-Your-Environment:&quot;&gt;Tune Concurrency and Batching for Your Environment:&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h3&gt;&lt;p&gt;You can adjust &lt;code&gt;--concurrency&lt;/code&gt;, &lt;code&gt;--concurrency-per-table&lt;/code&gt;, and &lt;code&gt;--row-batch-size&lt;/code&gt; to optimize runtime. The &lt;code&gt;--concurrency&lt;/code&gt; flag toggles how many tables to verify at a time, and then &lt;code&gt;--concurrency-per-table&lt;/code&gt; allows you to adjust how many threads should run per table. Start with defaults, and if you find verification is taking too long, consider increasing concurrency. If you do raise concurrency, monitor the source database – you don’t want to accidentally overload production with read queries. It might be useful to test on a staging environment to gauge how much concurrency the source can handle.&amp;nbsp;&lt;/p&gt;&lt;p&gt;If the network is a bottleneck, see if larger batches improve throughput. Conversely, if you run into memory constraints on the MOLT Verify side (or if either database starts to see issues like long transaction times), you might lower the batch size to reduce the footprint. The goal is to make verification as fast as possible &lt;i&gt;without&lt;/i&gt; jeopardizing the stability of your systems.&amp;nbsp;&lt;/p&gt;&lt;p&gt;MOLT Verify also offers &lt;code&gt;--schema-filter&lt;/code&gt; and &lt;code&gt;--table-filter&lt;/code&gt; options (accepting regex patterns) to limit what it checks. This is useful for phased migrations. For instance, if you are migrating in waves, you could verify one schema at a time by filtering. Or if one giant table dominates the runtime, you might isolate it in a separate run.&lt;/p&gt;&lt;hr&gt;&lt;p&gt;&lt;b&gt;RELATED&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Check out our tutorials on how to &lt;a href=&quot;https://www.cockroachlabs.com/docs/stable/migrate-to-cockroachdb&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;migrate from PostgreSQL or MySQL to CockroachDB&lt;/u&gt;&lt;/a&gt;.&lt;/p&gt;&lt;hr&gt;&lt;h2 id=&quot;MOLT-to-CockroachDB-with-Confidence&quot;&gt;MOLT to CockroachDB with Confidence&lt;span class=&quot;relative ml-2 inline-block size-4 hover:size-5&quot;&gt;&lt;img src=&quot;https://www.cockroachlabs.com/images/icons/copy-icon.svg&quot; alt=&quot;Copy Icon&quot; style=&quot;cursor:pointer&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/span&gt;&lt;/h2&gt;&lt;div class=&quot;blog-image&quot;&gt;&lt;div class=&quot;-mt-6 mb-8&quot;&gt;&lt;a href=&quot;https://images.ctfassets.net/00voh0j35590/2xX2hwGxtP5Fvh9zESs3ti/d067ba52529f15f155e64515c284801c/molt-tools-migration-to-cockroachdb.png&quot;&gt;&lt;img alt=&quot;A diagram from the Cockroach Labs documentation site showing the workflow with the full MOLT (Migrate Off Legacy Technology) Suite: MOLT SCT, MOLT Fetch, and MOLT Verify.&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;749&quot; decoding=&quot;async&quot; data-nimg=&quot;1&quot; class=&quot;min-w-hit min-h-hit&quot; style=&quot;color:transparent&quot; src=&quot;https://images.ctfassets.net/00voh0j35590/2xX2hwGxtP5Fvh9zESs3ti/d067ba52529f15f155e64515c284801c/molt-tools-migration-to-cockroachdb.png&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Ensuring data integrity during migrations is crucial for any organization. MOLT Verify provides an automated, comprehensive validation process that gives you the confidence to complete your migration swiftly and without the fear of data corruption. Remove guesswork from your migrations with MOLT Verify, validating every record systematically before production.&amp;nbsp;&lt;/p&gt;&lt;p&gt;To recap best practices: use the tool early and often, verify in as controlled an environment as possible, pay attention to its output, and address any problems it uncovers. Migrations are like a high-stakes endeavor, but with tools like MOLT Verify, you have a stethoscope to check the health of your data before declaring the operation a success.&lt;/p&gt;&lt;p&gt;Get started with CockroachDB Cloud today. We’re offering &lt;a href=&quot;https://www.cockroachlabs.com/docs/cockroachcloud/free-trial&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;$400 of free credits&lt;/u&gt;&lt;/a&gt; to help kickstart your CockroachDB journey, or &lt;a href=&quot;https://www.cockroachlabs.com/contact/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;u&gt;get in touch&lt;/u&gt;&lt;/a&gt; today to learn more.&lt;/p&gt;</description><link>https://www.cockroachlabs.com/blog/data-integrity-molt-verify-migrations/</link><guid isPermaLink="false">https://www.cockroachlabs.com/blog/data-integrity-molt-verify-migrations/</guid></item></channel></rss>