Cockroachdb
Build with CockroachDB as a distributed SQL database. Use this skill when the project needs to integrate CockroachDB for globally distributed PostgreSQL-compatible SQL, multi-region deployments, serializable transactions, or horizontal scaling. Covers CockroachDB Serverless, node-postgres integration, multi-region patterns, and ORM compatibility.
You are a database specialist who integrates CockroachDB into projects. CockroachDB
is a distributed SQL database that provides PostgreSQL compatibility, serializable
transactions, and automatic horizontal scaling across regions.
## Key Points
- Use UUID primary keys — auto-incrementing IDs cause hotspots in distributed systems
- Implement transaction retry logic for `40001` (serialization) errors
- Use `RETURNING` on INSERT/UPDATE to avoid extra round trips
- Design schemas with CockroachDB-specific types: `STRING` instead of `VARCHAR`
- Use multi-region localities for latency-sensitive data
- Connection pool with `pg.Pool` — don't create connections per request
- Using auto-incrementing integer IDs — creates write hotspots on a single range
- Not retrying on serialization errors (code 40001) — expected in serializable isolation
- Using `SELECT FOR UPDATE` when a simple conditional update suffices
- Interleaving reads and writes in transactions unnecessarily — increases contention
- Not setting appropriate connection pool sizes — too many connections waste resources
- Ignoring region-aware table design in multi-region deployments
## Quick Example
```bash
npm install pg
# Or with Drizzle
npm install drizzle-orm pg
# Or with Prisma
npx prisma init
```
```prisma
datasource db {
provider = "cockroachdb"
url = env("DATABASE_URL")
}
```skilldb get database-services-skills/cockroachdbFull skill: 194 linesCockroachDB Integration
You are a database specialist who integrates CockroachDB into projects. CockroachDB is a distributed SQL database that provides PostgreSQL compatibility, serializable transactions, and automatic horizontal scaling across regions.
Core Philosophy
Distributed SQL
CockroachDB spreads data across multiple nodes and regions automatically. Every node can serve reads and writes — there's no single primary. If a node goes down, the cluster keeps running without intervention.
PostgreSQL compatible
CockroachDB speaks the PostgreSQL wire protocol. Your existing PostgreSQL drivers, ORMs, and tools work with minimal changes. If you know Postgres, you know CockroachDB.
Serializable by default
Every transaction in CockroachDB is serializable — the strongest isolation level. No phantom reads, no write skew, no surprises. You trade some latency for correctness guarantees most databases don't offer by default.
Setup
Install (use any PostgreSQL driver)
npm install pg
# Or with Drizzle
npm install drizzle-orm pg
# Or with Prisma
npx prisma init
Connect
import { Pool } from 'pg';
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
ssl: { rejectUnauthorized: false },
});
With Drizzle ORM
import { drizzle } from 'drizzle-orm/node-postgres';
import { Pool } from 'pg';
import * as schema from './schema';
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
const db = drizzle(pool, { schema });
With Prisma
datasource db {
provider = "cockroachdb"
url = env("DATABASE_URL")
}
Key Techniques
Schema (PostgreSQL-compatible)
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email STRING NOT NULL UNIQUE,
name STRING,
plan STRING NOT NULL DEFAULT 'free',
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
INDEX idx_users_email (email)
);
CREATE TABLE posts (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
title STRING NOT NULL,
content STRING NOT NULL,
status STRING NOT NULL DEFAULT 'draft',
author_id UUID NOT NULL REFERENCES users(id),
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
INDEX idx_posts_author (author_id),
INDEX idx_posts_status (status, created_at DESC)
);
CRUD operations
// Insert
const { rows: [user] } = await pool.query(
'INSERT INTO users (email, name) VALUES ($1, $2) RETURNING *',
['alice@example.com', 'Alice']
);
// Select
const { rows: posts } = await pool.query(
'SELECT p.*, u.name as author_name FROM posts p JOIN users u ON p.author_id = u.id WHERE p.status = $1 ORDER BY p.created_at DESC LIMIT $2',
['published', 20]
);
// Update
await pool.query(
'UPDATE posts SET title = $1, updated_at = now() WHERE id = $2',
['Updated', postId]
);
// Upsert
await pool.query(
'INSERT INTO users (email, name) VALUES ($1, $2) ON CONFLICT (email) DO UPDATE SET name = EXCLUDED.name, updated_at = now()',
['alice@example.com', 'Alice Updated']
);
// Delete
await pool.query('DELETE FROM posts WHERE id = $1', [postId]);
Transactions with retry
async function runTransaction<T>(fn: (client: any) => Promise<T>): Promise<T> {
const client = await pool.connect();
try {
while (true) {
try {
await client.query('BEGIN');
const result = await fn(client);
await client.query('COMMIT');
return result;
} catch (err: any) {
await client.query('ROLLBACK');
if (err.code === '40001') continue; // Retry on serialization error
throw err;
}
}
} finally {
client.release();
}
}
// Usage
const post = await runTransaction(async (client) => {
const { rows: [post] } = await client.query(
'UPDATE posts SET status = $1 WHERE id = $2 RETURNING *',
['published', postId]
);
await client.query(
'INSERT INTO notifications (user_id, type, entity_id) VALUES ($1, $2, $3)',
[post.author_id, 'published', post.id]
);
return post;
});
Multi-region configuration
-- Set table locality for low-latency regional reads
ALTER TABLE users SET LOCALITY REGIONAL BY ROW;
-- Add a crdb_region column
ALTER TABLE users ADD COLUMN crdb_region crdb_internal_region NOT NULL
DEFAULT gateway_region()::crdb_internal_region;
-- Global tables (replicated to all regions, fast reads everywhere)
ALTER TABLE config SET LOCALITY GLOBAL;
Best Practices
- Use UUID primary keys — auto-incrementing IDs cause hotspots in distributed systems
- Implement transaction retry logic for
40001(serialization) errors - Use
RETURNINGon INSERT/UPDATE to avoid extra round trips - Design schemas with CockroachDB-specific types:
STRINGinstead ofVARCHAR - Use multi-region localities for latency-sensitive data
- Connection pool with
pg.Pool— don't create connections per request
Anti-Patterns
- Using auto-incrementing integer IDs — creates write hotspots on a single range
- Not retrying on serialization errors (code 40001) — expected in serializable isolation
- Using
SELECT FOR UPDATEwhen a simple conditional update suffices - Interleaving reads and writes in transactions unnecessarily — increases contention
- Not setting appropriate connection pool sizes — too many connections waste resources
- Ignoring region-aware table design in multi-region deployments
Install this skill directly: skilldb add database-services-skills
Related Skills
Convex
Build with Convex as a reactive backend. Use this skill when the project needs to integrate Convex for real-time database, server functions, file storage, scheduled jobs, authentication, or full-stack TypeScript development with automatic reactivity. Covers the Convex client, queries, mutations, actions, schema validation, indexes, real-time subscriptions, and deployment.
Drizzle
Use Drizzle ORM for type-safe SQL in TypeScript. Use this skill when the project needs to integrate Drizzle for SQL-first database access, schema definition in TypeScript, migrations, relational queries, or connecting to PostgreSQL, MySQL, SQLite, Turso, Neon, PlanetScale, or Vercel Postgres. Covers Drizzle schema, query builder, relational API, migrations, and driver integrations.
Dynamodb
Build with Amazon DynamoDB as a serverless NoSQL database. Use this skill when the project needs to integrate DynamoDB for key-value and document storage, single-table design, global tables, streams, TTL, or serverless-first data access. Covers the AWS SDK v3, single-table design, GSIs, queries, scans, transactions, and DynamoDB Streams.
Fauna
Build with Fauna as a distributed document-relational database. Use this skill when the project needs to integrate Fauna for globally distributed data, ACID transactions, document-relational modeling, FQL queries, or serverless database access. Covers the Fauna v10 client, FQL, schema, indexes, and authentication.
Firebase Firestore
Build with Firebase Firestore as a NoSQL document database. Use this skill when the project needs to integrate Firestore for real-time document storage, offline persistence, security rules, queries, aggregations, or Cloud Functions triggers. Covers the Firestore SDK (v9+), data modeling, queries, security rules, real-time listeners, batched writes, transactions, and Cloud Functions integration.
Mongodb
Build with MongoDB as a document database. Use this skill when the project needs to integrate MongoDB or Mongoose for document storage, flexible schemas, aggregation pipelines, Atlas Search, change streams, or transactions. Covers the MongoDB Node.js driver, Mongoose ODM, schema design, indexing, aggregation, and Atlas features.