September 21, 2022·6 min read·engineeringcockroachdbserverlessarchitecture

CockroachDB Serverless makes database capacity a usage decision

CockroachDB Serverless reaches general availability with separate SQL and storage layers. Its request-unit budget connects query design, background activity, and available burst performance.

A serverless relational database still needs capacity for SQL execution and durable storage. The change is in how the service supplies that capacity and how an application pays for it. CockroachDB Serverless separates the SQL resources attached to a tenant from a shared storage deployment, allowing the service to manage execution capacity without asking the user to select a server size.

The September 21 general-availability announcement follows the public beta introduced last October. It describes automatic scaling and consumption-based pricing alongside capabilities added during the beta, including change data capture, backups, and a management API. The architecture and usage documentation give those product claims a more concrete operational meaning for an application choosing its deployment and connection behavior.

I accept CockroachDB's coordination costs because its consistency model is useful. A managed offering changes who operates the infrastructure, but query work still has a cost. The interesting question here is how explicitly that work appears in the service's scaling and budget model.

A virtual cluster has separate execution resources

The architecture documentation available at general availability describes a Serverless cluster as an isolated virtual tenant in a larger physical CockroachDB deployment. SQL pods provide compute, while KV pods provide a shared storage layer. The service does not allocate every virtual cluster a completely separate physical database deployment.

A cloud load balancer directs incoming connections to proxy pods. Those proxies route a client to its SQL pods, balance connections across available execution resources, and resume clusters paused through inactivity. The SQL pods then communicate with the KV layer to access stored data.

This separation explains how SQL capacity can change without making storage disappear. An idle application's execution resources can scale down while its data remains in the storage service. Starting work again requires execution capacity and connection routing, not recreating the database from nothing.

The documentation also describes network rules preventing SQL pods from communicating with pods belonging to other users. Shared physical infrastructure and tenant isolation therefore coexist through explicit placement and communication rules. Calling the service serverless does not mean that tenant boundaries follow automatically from the absence of a user-selected machine.

Usage measures work rather than statement count

The release-day request-unit documentation defines Request Units, or RUs, as an abstraction of request size and complexity. Activity includes SQL queries, bulk operations, and background jobs. Storage is a separate component of usage.

One SQL statement therefore does not correspond to one fixed unit. A point read of a small row has a different cost from a large scan. Writing a row includes replication work, and maintaining additional indexes increases the work attached to the write. The documentation's examples make those differences visible without presenting them as universal measurements for every workload.

The size of values matters too. Reading or writing a larger row moves more data, even when the statement has the same shape. A statement returning one result can scan many rows on its way to that result. The number of result rows alone is therefore a poor description of the work counted by the service.

That is a useful connection between query planning and a consumption bill. A missing index can increase the amount scanned, while an additional index can increase write work. Neither indexing choice is free merely because the service manages the machines. The relevant tradeoff still comes from the application's access patterns.

The documentation also assigns activity to establishing a SQL connection and executing a simple statement. Connection behavior can therefore contribute to usage independently of the rows an application intends to retrieve. A workload description needs its connection pattern as well as its headline query rate.

Background work belongs in the same budget

Automatic statistics collection can consume RUs. Changefeeds connected to an external sink can consume them too. These are database activities supporting an application even when the application has not issued another visible request at that moment.

The Serverless FAQ at the announcement date explains that statistics collection can produce a brief RU increase during an otherwise steady workload. Those statistics help the cost-based optimizer choose plans. Suppressing the collection to avoid its immediate work can leave the optimizer with less useful information and produce more expensive queries later.

This makes background usage part of interpreting a graph rather than evidence of unexplained application traffic. The application and database together generate the work that keeps the service useful. Measuring only explicit request arrivals leaves some of that work unaccounted for.

I prefer a usage model that admits those costs. It gives query design and supporting maintenance a common accounting context. The accounting still needs interpretation, since a temporary increase can improve later execution rather than represent wasted capacity.

A spend limit can become a performance limit

The architecture documentation describes baseline performance of 100 RUs per second and additional burst capacity. A cluster has an initial monthly burst allowance and earns additional capacity under the documented free-resource rules. A paid spend limit allows continued burst use beyond the free allowance, until that limit is reached.

Reaching the spend limit returns the cluster to baseline performance. It is therefore an operational input, not merely a number that appears after the month ends. An application depending on higher burst throughput can experience a change in available service when its budget is exhausted.

Storage receives priority in that budget, with the remainder available for burst performance. The same total limit can therefore support different execution patterns for clusters storing different amounts of data. An estimate based only on current query activity can omit the portion already committed to retaining the database.

This behavior differs from reserving a fixed machine for the month. The workload can use more when capacity is available under its budget, and later revert to the baseline. The service removes server-size selection, while retaining a real resource boundary that application operators need to understand.

The cluster-management documentation from the same date describes cost estimates as extrapolations from a chosen observation window. That window must represent the workload being estimated. A quiet interval or a short burst cannot establish a monthly pattern that the application does not actually follow.

Scaling to zero preserves storage and changes activation

The architecture describes pausing an inactive cluster after five consecutive minutes without a connection. Reconnection resumes it through the managed routing path. During inactivity, stored data remains a storage cost even when execution consumes no compute resources.

The FAQ gives a typical cold-start latency around 600 milliseconds. That is a published typical value, not a bound on every connection. The architecture also calls for application connection retry logic to handle node restarts or network disruptions. Managing the cluster does not make those client-visible conditions impossible.

This gives intermittent workloads a concrete benefit. They do not need to keep a chosen SQL server allocation running solely to remain ready for the next request. The first connection after inactivity still participates in resuming execution, so latency-sensitive application paths need to account for activation as part of their behavior.

General availability includes operational services

The release announcement highlights backups, change data capture, and an API added during the beta. The contemporaneous FAQ describes automatic full-cluster backups every hour, retained for 30 days. It distinguishes those from manual backups and says automatic backups do not provide database- or table-level restoration.

That scope matters to the meaning of a managed backup. An operator needs to know which unit can be restored, not only that backup exists. The service automates a recovery capability with defined granularity, while application recovery requirements may refer to a smaller portion of the database.

Version upgrades are automatic in the Serverless offering, according to the FAQ. Users can inspect the running version but do not choose an individual version upgrade themselves. That transfers another operational decision to the service and makes the documented client and feature compatibility part of using the offering.

General availability thus presents a managed execution and storage arrangement with explicit consumption behavior. SQL work, background activity, and retained data contribute to its resource model. Automatic scaling removes a server-sizing decision, while the request-unit budget and recovery capabilities remain concrete properties of running an application on the service.