AlloyDB Guide
Comprehensive guide to AlloyDB for PostgreSQL covering clusters, instances, pgvector for AI embeddings, the columnar engine for analytics, cross-region replication, and migration strategies.
Prerequisites
- Basic PostgreSQL knowledge (SQL, connections, indexes)
- GCP account with billing enabled
- Familiarity with VPC networking concepts
Introduction to AlloyDB for PostgreSQL
AlloyDB is Google Cloud's fully managed, PostgreSQL-compatible database service designed for demanding enterprise workloads. It combines the familiarity and ecosystem of PostgreSQL with Google's proprietary storage layer that delivers up to 4x faster transactional throughput and up to 100x faster analytical queries compared to standard PostgreSQL. AlloyDB was purpose-built for workloads that need both OLTP and OLAP capabilities in a single database, eliminating the need to maintain separate systems for transactional and analytical processing.
Under the hood, AlloyDB separates compute from storage. The compute layer runs a modified PostgreSQL engine with intelligent caching, while the storage layer uses a distributed, log-structured architecture built on Google's infrastructure. This separation means you can scale compute and storage independently, and the storage layer handles replication, backups, and recovery automatically. AlloyDB maintains full compatibility with PostgreSQL 14 and 15, so existing applications, drivers, extensions, and tools work without modification.
This guide covers everything from creating your first cluster to advanced features like pgvector for AI embeddings, the columnar engine for analytics, cross-region replication, and migration strategies from existing PostgreSQL or other database systems.
AlloyDB Pricing
AlloyDB charges for vCPUs and memory on primary and read pool instances, plus storage consumed. A typical development cluster with 2 vCPUs and 16 GB RAM starts around $0.1386/hr for the primary instance. Storage is billed at $0.0004167/GB/hr (approximately $0.30/GB/month). AlloyDB does not have a free tier, but you can use AlloyDB Omni (the downloadable version) for local development at no cost.
Architecture and Core Concepts
AlloyDB uses a disaggregated architecture with three distinct layers: the database engine layer, an ultra-fast caching layer, and an intelligent storage layer. This architecture is what gives AlloyDB its performance advantages over standard PostgreSQL running on compute instances.
Key Architecture Components
| Component | Description | Purpose |
|---|---|---|
| Cluster | Top-level resource containing instances and storage | Logical grouping, regional scope |
| Primary Instance | Read-write database instance | Handles all write operations and reads |
| Read Pool | Group of 1-20 read-only instances | Scale reads horizontally with load balancing |
| Storage Layer | Log-structured distributed storage | Automatic replication, point-in-time recovery |
| Columnar Engine | In-memory columnar cache | Accelerates analytical queries up to 100x |
| Ultra-fast Cache | Low-latency caching on local SSDs | Reduces read latency below standard PostgreSQL |
Creating Your First AlloyDB Cluster
Before creating a cluster, you need a VPC network with Private Services Access configured. AlloyDB instances are only accessible via private IP addresses within your VPC, which provides strong network security by default but means you need to plan your network connectivity upfront.
# Enable the AlloyDB API
gcloud services enable alloydb.googleapis.com
# Configure Private Services Access (required for AlloyDB)
gcloud compute addresses create alloydb-psa-range \
--global \
--purpose=VPC_PEERING \
--prefix-length=16 \
--network=default
gcloud services vpc-peerings connect \
--service=servicenetworking.googleapis.com \
--ranges=alloydb-psa-range \
--network=default
# Create an AlloyDB cluster
gcloud alloydb clusters create my-alloydb-cluster \
--region=us-central1 \
--password=YourStr0ngP@ssword! \
--network=default
# Create the primary instance
gcloud alloydb instances create my-primary \
--cluster=my-alloydb-cluster \
--region=us-central1 \
--instance-type=PRIMARY \
--cpu-count=2
# Wait for the instance to be ready
gcloud alloydb instances describe my-primary \
--cluster=my-alloydb-cluster \
--region=us-central1 \
--format="value(state)"
# Get the private IP address
gcloud alloydb instances describe my-primary \
--cluster=my-alloydb-cluster \
--region=us-central1 \
--format="value(ipAddress)"Network Access Required
AlloyDB instances only have private IP addresses. To connect from your local machine, you need either a Cloud SQL Auth Proxy, a Compute Engine VM in the same VPC, a VPN connection, or Cloud Shell. For production, use the AlloyDB Auth Proxy for secure, IAM-based authentication without managing SSL certificates manually.
Connecting via the AlloyDB Auth Proxy
# Download the AlloyDB Auth Proxy
curl -o alloydb-auth-proxy \
https://storage.googleapis.com/alloydb-auth-proxy/v1/alloydb-auth-proxy.linux.amd64
chmod +x alloydb-auth-proxy
# Start the proxy (runs in background, connects on localhost:5432)
./alloydb-auth-proxy \
"projects/MY_PROJECT/locations/us-central1/clusters/my-alloydb-cluster/instances/my-primary" &
# Connect with psql
psql -h 127.0.0.1 -U postgres -d postgres
# Or connect from application code (Python example)
# pip install psycopg2-binary sqlalchemyimport sqlalchemy
from sqlalchemy import text
engine = sqlalchemy.create_engine(
"postgresql+psycopg2://postgres:YourStr0ngP@ssword!@127.0.0.1:5432/postgres"
)
with engine.connect() as conn:
result = conn.execute(text("SELECT version()"))
print(result.fetchone()[0])
# PostgreSQL 15.x on x86_64-pc-linux-gnu, compiled by gcc ...
# (AlloyDB-compatible)Read Pool Instances for Horizontal Scaling
AlloyDB read pool instances let you scale read traffic horizontally. A read pool is a group of one or more read-only instances that share a single connection endpoint. AlloyDB automatically load-balances connections across all nodes in the pool. Each node in the pool maintains its own ultra-fast cache, so adding nodes increases both throughput and effective cache size.
# Create a read pool with 2 nodes
gcloud alloydb instances create my-read-pool \
--cluster=my-alloydb-cluster \
--region=us-central1 \
--instance-type=READ_POOL \
--cpu-count=2 \
--read-pool-node-count=2
# Scale the read pool up to 4 nodes
gcloud alloydb instances update my-read-pool \
--cluster=my-alloydb-cluster \
--region=us-central1 \
--read-pool-node-count=4
# Get the read pool IP (single endpoint, load-balanced)
gcloud alloydb instances describe my-read-pool \
--cluster=my-alloydb-cluster \
--region=us-central1 \
--format="value(ipAddress)"Connection Routing Strategy
Use the primary instance endpoint for all write operations and the read pool endpoint for read-heavy queries like reports, dashboards, and search. Many connection poolers and ORMs support separate read/write endpoints natively. In SQLAlchemy, usecreate_engine with execution_options to route queries appropriately. This pattern can reduce primary instance load by 60-80% in typical web applications.
The Columnar Engine for Analytics
AlloyDB's columnar engine is an in-memory column store that accelerates analytical queries without requiring any application changes. When enabled, AlloyDB automatically identifies frequently queried columns and caches them in a columnar format optimized for aggregations, scans, and joins. Analytical queries that previously took minutes can complete in seconds.
The columnar engine operates transparently: you do not need to change your SQL queries, schema, or application code. AlloyDB's query optimizer automatically decides whether to use the row store or columnar engine for each query based on cost estimation. You can also manually recommend specific tables and columns for columnar caching.
-- Check columnar engine status
SHOW google_columnar_engine.enabled;
-- Enable the columnar engine (requires instance restart)
-- Set via instance flags:
-- google_columnar_engine.enabled = on
-- google_columnar_engine.memory_size_in_mb = 4096
-- Manually add a table to the columnar cache
SELECT google_columnar_engine_add(
relation => 'orders',
columns => ARRAY['order_date', 'total_amount', 'customer_id', 'status']
);
-- Check which columns are cached
SELECT * FROM g_columnar_recommended_columns;
-- Check columnar engine memory usage
SELECT * FROM g_columnar_memory_usage;
-- Run an analytical query (automatically uses columnar engine)
SELECT
DATE_TRUNC('month', order_date) AS month,
COUNT(*) AS order_count,
SUM(total_amount) AS revenue,
AVG(total_amount) AS avg_order_value
FROM orders
WHERE order_date >= '2025-01-01'
GROUP BY DATE_TRUNC('month', order_date)
ORDER BY month;
-- Verify the columnar engine was used
EXPLAIN (ANALYZE, COSTS, BUFFERS)
SELECT COUNT(*), SUM(total_amount)
FROM orders
WHERE status = 'completed';
-- Look for "Columnar Scan" in the outputpgvector for AI and Embeddings
AlloyDB includes built-in support for pgvector, the popular PostgreSQL extension for storing and querying vector embeddings. Combined with AlloyDB's performance optimizations, this makes AlloyDB an excellent choice for AI-powered applications that need semantic search, recommendation engines, or retrieval-augmented generation (RAG) pipelines. AlloyDB adds proprietary optimizations like ScaNN-based indexing that delivers significantly faster vector search than standard pgvector.
-- Enable the pgvector extension
CREATE EXTENSION IF NOT EXISTS vector;
-- Create a table for document embeddings
CREATE TABLE documents (
id BIGSERIAL PRIMARY KEY,
title TEXT NOT NULL,
content TEXT NOT NULL,
embedding VECTOR(768), -- 768 dimensions for text-embedding models
metadata JSONB DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Insert embeddings (typically generated by an embedding model)
INSERT INTO documents (title, content, embedding)
VALUES (
'Cloud Architecture Patterns',
'Microservices communicate through well-defined APIs...',
'[0.021, -0.034, 0.067, ...]'::vector -- 768-dim vector
);
-- Create a ScaNN index for fast similarity search (AlloyDB-specific)
CREATE INDEX ON documents
USING scann (embedding cosine)
WITH (num_leaves = 100, quantizer = 'SQ8');
-- Alternatively, use standard IVFFlat or HNSW indexes
CREATE INDEX ON documents
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 200);
-- Semantic search: find documents similar to a query embedding
SELECT
id,
title,
1 - (embedding <=> '[0.019, -0.041, 0.073, ...]'::vector) AS similarity
FROM documents
ORDER BY embedding <=> '[0.019, -0.041, 0.073, ...]'::vector
LIMIT 10;
-- Hybrid search combining vector similarity with metadata filters
SELECT id, title,
1 - (embedding <=> $1::vector) AS similarity
FROM documents
WHERE metadata->>'category' = 'architecture'
AND created_at > NOW() - INTERVAL '90 days'
ORDER BY embedding <=> $1::vector
LIMIT 5;ScaNN vs HNSW Indexing
AlloyDB's proprietary ScaNN (Scalable Nearest Neighbors) index typically delivers 2-10x better query performance than HNSW for large datasets (1M+ vectors) with comparable recall. ScaNN uses quantization techniques to reduce memory usage and speed up distance calculations. For datasets under 100K vectors, HNSW may perform equally well. Benchmark both on your actual data to choose the right index type.
Backup, Recovery, and High Availability
AlloyDB provides multiple layers of data protection. Automated continuous backups enable point-in-time recovery (PITR) to any second within the retention window (up to 35 days by default, extendable to 365 days). AlloyDB also supports on-demand backups for milestone snapshots, and cross-region backups for disaster recovery.
# Create an on-demand backup
gcloud alloydb backups create my-backup-20260314 \
--cluster=my-alloydb-cluster \
--region=us-central1
# List all backups
gcloud alloydb backups list \
--region=us-central1
# Restore a cluster from backup
gcloud alloydb clusters restore my-restored-cluster \
--region=us-central1 \
--backup=projects/MY_PROJECT/locations/us-central1/backups/my-backup-20260314 \
--network=default
# Point-in-time recovery (restore to a specific timestamp)
gcloud alloydb clusters restore my-pitr-cluster \
--region=us-central1 \
--continuous-backup-source=projects/MY_PROJECT/locations/us-central1/clusters/my-alloydb-cluster \
--point-in-time="2026-03-14T10:30:00Z" \
--network=default
# Configure automated backup policy
gcloud alloydb clusters update my-alloydb-cluster \
--region=us-central1 \
--automated-backup-enabled \
--automated-backup-days-of-week=MONDAY,WEDNESDAY,FRIDAY \
--automated-backup-start-times=02:00 \
--automated-backup-retention-count=14Cross-Region Replication
AlloyDB supports cross-region replication for disaster recovery and serving reads closer to your users. A secondary cluster in another region maintains an asynchronous replica of your primary cluster. In the event of a regional outage, you can promote the secondary cluster to become a fully independent primary cluster.
# Create a secondary cluster in another region
gcloud alloydb clusters create my-alloydb-secondary \
--region=europe-west1 \
--secondary \
--primary-cluster=projects/MY_PROJECT/locations/us-central1/clusters/my-alloydb-cluster \
--network=default
# Create an instance in the secondary cluster
gcloud alloydb instances create secondary-primary \
--cluster=my-alloydb-secondary \
--region=europe-west1 \
--instance-type=PRIMARY \
--cpu-count=2
# Check replication lag
gcloud alloydb clusters describe my-alloydb-secondary \
--region=europe-west1 \
--format="value(secondaryConfig)"
# Promote the secondary to an independent primary (during DR)
gcloud alloydb clusters promote my-alloydb-secondary \
--region=europe-west1Migrating to AlloyDB
Google provides the Database Migration Service (DMS) for migrating existing PostgreSQL databases to AlloyDB with minimal downtime. DMS supports continuous replication, so your source database can remain operational during the migration. For other database engines like MySQL or Oracle, use the pgloader tool or AWS Schema Conversion Tool equivalent workflows followed by DMS for the data migration phase.
# Enable the Database Migration Service API
gcloud services enable datamigration.googleapis.com
# Create a connection profile for the source PostgreSQL
gcloud database-migration connection-profiles create source-pg \
--region=us-central1 \
--display-name="Source PostgreSQL" \
--provider=POSTGRESQL \
--host=10.0.0.5 \
--port=5432 \
--username=postgres \
--password=SourcePassword123
# Create a connection profile for the AlloyDB destination
gcloud database-migration connection-profiles create dest-alloydb \
--region=us-central1 \
--display-name="AlloyDB Destination" \
--provider=ALLOYDB \
--alloydb-cluster=my-alloydb-cluster
# Create and start the migration job
gcloud database-migration migration-jobs create pg-to-alloydb \
--region=us-central1 \
--display-name="PG to AlloyDB Migration" \
--source=source-pg \
--destination=dest-alloydb \
--type=CONTINUOUS
# Monitor migration progress
gcloud database-migration migration-jobs describe pg-to-alloydb \
--region=us-central1 \
--format="table(name,state,phase,error)"
# Promote destination when ready (completes the cutover)
gcloud database-migration migration-jobs promote pg-to-alloydb \
--region=us-central1Performance Tuning and Best Practices
AlloyDB handles many PostgreSQL tuning tasks automatically, but there are still important optimizations you should apply for production workloads. The following recommendations are based on common AlloyDB deployment patterns.
Instance Sizing Guidelines
| Workload Type | Recommended vCPUs | Memory | Notes |
|---|---|---|---|
| Development / Testing | 2 | 16 GB | Smallest configuration |
| Small production (100 QPS) | 4 | 32 GB | Add read pool for read-heavy |
| Medium production (1K QPS) | 8-16 | 64-128 GB | Enable columnar engine |
| Large production (10K+ QPS) | 32-64 | 256-512 GB | Multiple read pool nodes |
-- Check active connections and their state
SELECT state, COUNT(*)
FROM pg_stat_activity
GROUP BY state;
-- Find slow queries
SELECT query, calls, mean_exec_time, total_exec_time
FROM pg_stat_statements
ORDER BY mean_exec_time DESC
LIMIT 20;
-- Check table bloat
SELECT schemaname, tablename,
pg_size_pretty(pg_total_relation_size(schemaname || '.' || tablename)) AS total_size,
n_dead_tup,
n_live_tup,
ROUND(n_dead_tup::numeric / NULLIF(n_live_tup, 0) * 100, 2) AS dead_pct
FROM pg_stat_user_tables
ORDER BY n_dead_tup DESC
LIMIT 10;
-- Monitor replication lag for read pools
SELECT
client_addr,
state,
sent_lsn,
replay_lsn,
pg_wal_lsn_diff(sent_lsn, replay_lsn) AS replication_lag_bytes
FROM pg_stat_replication;
-- Check index usage (unused indexes waste storage and slow writes)
SELECT
schemaname, tablename, indexname,
idx_scan AS times_used,
pg_size_pretty(pg_relation_size(indexrelid)) AS index_size
FROM pg_stat_user_indexes
WHERE idx_scan = 0
AND schemaname NOT IN ('pg_catalog', 'information_schema')
ORDER BY pg_relation_size(indexrelid) DESC;AlloyDB Omni for Local Development
AlloyDB Omni is a downloadable version of AlloyDB that runs anywhere: your laptop, on-premises servers, or other clouds. It includes the same columnar engine and pgvector optimizations as the managed service. Use Omni for local development to maintain feature parity with your production AlloyDB cluster. Install it via Docker withdocker pull google/alloydbomni and run it locally with no license cost.
Cleanup
# Delete read pool instances first
gcloud alloydb instances delete my-read-pool \
--cluster=my-alloydb-cluster \
--region=us-central1 --quiet
# Delete primary instance
gcloud alloydb instances delete my-primary \
--cluster=my-alloydb-cluster \
--region=us-central1 --quiet
# Delete the cluster (also deletes automated backups)
gcloud alloydb clusters delete my-alloydb-cluster \
--region=us-central1 --quiet
# Delete on-demand backups separately
gcloud alloydb backups delete my-backup-20260314 \
--region=us-central1 --quietKey Takeaways
- 1AlloyDB separates compute from storage, enabling independent scaling and automatic replication.
- 2The columnar engine accelerates analytical queries up to 100x without application changes.
- 3ScaNN-based vector indexing delivers 2-10x faster similarity search than standard pgvector HNSW.
- 4Read pools provide horizontal read scaling with automatic load balancing across nodes.
- 5AlloyDB Omni runs the same engine locally for development at no cost.
- 6Database Migration Service enables near-zero-downtime migration from existing PostgreSQL.
Frequently Asked Questions
How does AlloyDB differ from Cloud SQL for PostgreSQL?
Can I use AlloyDB for vector search and RAG?
Does AlloyDB have a free tier?
Written by CloudToolStack Team
Cloud engineers and architects with hands-on experience across AWS, Azure, and GCP. We write guides based on real-world production patterns, not just documentation rewrites.
Disclaimer: This guide is for educational purposes. Cloud services change frequently; always refer to official documentation for the latest information. AWS, Azure, and GCP are trademarks of their respective owners.