databases3 min read

Google Cloud Spanner Tutorial: Learn Globally Distributed SQL from Scratch (2026)

Google Cloud Spanner Tutorial: Learn Globally Distributed SQL from Scratch (2026)

Published:  |  Category: Databases  |  Reading time: ~15 min
Google Cloud Spanner Tutorial: Learn Globally Distributed SQL from Scratch (2026)

I have designed systems on Cloud Spanner that span continents while providing strong consistency and SQL access. Spanner is Google's globally distributed, strongly consistent relational database.

We will cover Spanner's architecture, schema design for global scale, interleaved tables, query optimization, and backup/restore.

Spanner Architecture: TrueTime, Splits, and Tablets

TrueTime provides bounded clock uncertainty for external consistency without distributed consensus overhead. Data partitions into splits on Paxos replicas.

Splits are automatically rebalanced across zones. Each split has a Paxos group with a leader for writes and read replicas.

gcloud spanner instances create my-instance --config=regional-us-central1 --nodes=3
gcloud spanner databases create mydb --instance=my-instance

Schema Design for Global Scale

Primary key determines data distribution. Monotonically increasing keys create hotspots. Use hash-prefixed keys for write-heavy workloads.

Secondary indexes: global (own splits, consistent but higher write latency) or local (interleaved, efficient for equality on leading PK columns).

CREATE TABLE users (hash_id INT64 NOT NULL, user_id INT64 NOT NULL, name STRING(100), email STRING(MAX) NOT NULL, created_at TIMESTAMP NOT NULL) PRIMARY KEY (hash_id, user_id);
CREATE INDEX users_by_email ON users(email);
CREATE TABLE orders (hash_id INT64 NOT NULL, user_id INT64 NOT NULL, order_id INT64 NOT NULL, total NUMERIC NOT NULL) PRIMARY KEY (hash_id, user_id, order_id), INTERLEAVE IN PARENT users ON DELETE CASCADE;

Queries and Transactions in a Global Database

Read-write transactions use pessimistic locking with external consistency. Read-only transactions provide consistent snapshots with no locking.

Spanner SQL is GoogleSQL. JOIN across splits is slow; interleaved tables avoid cross-split JOINs by co-locating related data.

BEGIN; SELECT total FROM accounts WHERE id = 1 FOR UPDATE; UPDATE accounts SET total = total - 100 WHERE id = 1; UPDATE accounts SET total = total + 100 WHERE id = 2; COMMIT;
SELECT u.name, o.total FROM users u JOIN orders o ON u.user_id = o.user_id WHERE u.email = 'alice@example.com';

Interleaved Tables and Co-Location

Child rows physically stored with parent rows. JOINs between parent and child never leave the same split—zero network overhead.

Deletes cascade automatically with ON DELETE CASCADE. Use interleaved tables for clear hierarchies: user -> orders -> order_items.

CREATE TABLE customers (customer_id INT64 NOT NULL, name STRING(100) NOT NULL) PRIMARY KEY (customer_id);
CREATE TABLE customer_orders (customer_id INT64 NOT NULL, order_id INT64 NOT NULL, total NUMERIC NOT NULL, created_at TIMESTAMP NOT NULL) PRIMARY KEY (customer_id, order_id), INTERLEAVE IN PARENT customers ON DELETE CASCADE;
SELECT c.name, co.order_id, co.total FROM customers c JOIN customer_orders co ON c.customer_id = co.customer_id WHERE c.customer_id = 42;

Indexing Strategies and Query Optimization

Global indexes for fast lookup on any column with write amplification. Bitmap scan merges results from multiple indexes.

Composite indexes with range column last. USE spanner_sys.query_stats_views to identify slow queries and missing indexes.

CREATE INDEX idx_orders_status_date ON orders(status, created_at DESC);
CREATE INDEX idx_orders_slim ON orders(status) STORING (total);
SELECT statement, query_plan, rows_returned, elapsed_seconds FROM spanner_sys.query_stats_views ORDER BY elapsed_seconds DESC LIMIT 10;

Backup, Restore, and Disaster Recovery

Database backups exported to Cloud Storage, restorable to a different instance. Clone is an instant point-in-time copy within the same instance.

Multi-region instances replicate synchronously across three regions. Failover is automatic with no data loss.

gcloud spanner backups create mydb-backup --instance=my-instance --database=mydb --retention-period=7d
gcloud spanner databases restore --source-instance=my-instance --source-database=mydb --destination-instance=my-instance --destination-database=mydb-restored --backup=mydb-backup
gcloud spanner instances create global-instance --config=nam3 --nodes=5

Frequently Asked Questions

Is Cloud Spanner free?

No. Pricing includes compute (per node/hour), storage (per GB/month), and network egress. No free tier, but you can start with a small single-region instance for dev.

Can Spanner handle JOINs efficiently?

JOINs within the same split (interleaved tables) are fast. Cross-split JOINs are slower due to data shuffling. Design schemas to minimize cross-split JOINs.

What is the minimum number of nodes?

Minimum 1 for regional, minimum 3 for multi-region. Each node provides up to 2 TB storage and 10,000 writes/second. Nodes can be added without downtime.

Does Spanner support event-driven architectures?

Yes. Change streams capture row-level changes with strong consistency and stream to Pub/Sub for real-time processing.

Originally published on Ayodhyyya. Last updated June 1, 2026.