Generated banner for Spanner Basics
Generated logo for Spanner Basics

Spanner Basics

GoogleOfficialPublished by Google

  • Skill
  • Tool integration
  • Cloud and DevOps
  • Apache-2.0
  • Low risk

From the author

Assists in provisioning instances and databases, designing performant schemas, and querying data in Cloud Spanner on Google Cloud. Use when designing primary keys, writing SQL queries or client library code, or diagnosing performance issues.
— the description by Google

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

Spanner Basics provides guidance and workflows for interacting with Google Cloud Spanner. It covers administrative tasks like provisioning instances and databases, as well as development tasks such as designing schemas, writing SQL queries, and utilizing client libraries. The skill includes specific instructions for performance-oriented schema design, such as primary key selection and table interleaving, and provides reference material for IAM security, Terraform, and PostgreSQL dialect usage.

What it does

  • Provides commands for provisioning and managing Spanner instances and databases.
  • Offers guidance on designing performant database schemas.
  • Assists in writing SQL queries and client library code for Spanner.
  • Helps diagnose performance issues using system tables.
  • Includes reference documentation for IAM, Terraform, and PostgreSQL compatibility.
  • Requires explicit user confirmation for all DDL and DML operations.

When to use it

  • When setting up or managing Cloud Spanner instances and databases via CLI.
  • When designing database schemas, including primary keys and interleaved tables.
  • When writing or debugging SQL queries and application code for Spanner.
  • When investigating performance metrics using system tables.
  • When implementing infrastructure as code using Terraform for Spanner resources.

Advantages

  • Centralizes access to Spanner-specific CLI commands and best practices.
  • Ensures safe execution by requiring user approval for destructive operations.
  • Provides structured guidance on complex topics like schema evolution.
  • Includes standardized attribution for command execution.

Usage examples

“Create a new Spanner instance named my-app-db with 1 node in us-central1.”
The agent will generate the appropriate gcloud spanner instances create command with the specified configuration.
“How should I design my primary key to avoid hotspots?”
The agent will provide guidance on avoiding monotonically increasing or decreasing values as the first part of a primary key.
“Show me how to list all databases in my instance.”
The agent will provide the gcloud spanner databases list command for the specified instance.
“Help me find the most resource-intensive queries in my database.”
The agent will suggest querying SPANNER_SYS.QUERY_STATS_TOP_HOUR to identify high CPU usage queries.

Install

  1. Download the skill as a ZIP:

    https://autogineer.com/agent-skills/google/spanner-basics/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip spanner-basics.zip -d .agents/skills

Documentation by Google

Spanner Basics

This skill provides core workflows and guidance for administering and developing with Cloud Spanner on Google Cloud, a fully managed, mission-critical database service offering global transactional consistency and automatic, synchronous replication for high availability.

Attribution

MUST READ: Before executing any gcloud, REST API, or MCP command, you MUST read Usage Attribution. For commands executed directly in the terminal (never in generated scripts, Terraform, or user code), prefix gcloud with CLOUDSDK_METRICS_REQUEST_ATTRIBUTION="agent-skills/1.0 (skill:spanner-basics)" and append agent-skills/1.0 (skill:spanner-basics) to User-Agent headers.

Core Principles

  • Performance First: Spanner scales horizontally. Efficiency is tied to Primary Key design. Always warn against using monotonically increasing/decreasing values (like sequential timestamps) as the first part of a primary key to avoid hotspots.

  • Schema Design: Prefer interleaved tables for strongly related parent-child data that is frequently accessed together.

Safety

[!CAUTION] CRITICAL INSTRUCTION: You MUST obtain explicit user confirmation before making any non-emulator database changes (DML or DDL) or destructive operations (such as dropping tables, indexes, or any other Spanner resources). Do not execute them automatically; instead, output the command (e.g., gcloud spanner databases ddl update) and ask for explicit user approval. When database access is unavailable or authentication fails, do not block on trying to verify the existence of the instance, database, or table. Assume the provided resources exist and directly generate the DDL commands.

Common Workflows

Schema Evolution & DDL
  1. Use gcloud spanner databases ddl update to apply schema updates (such as CREATE, ALTER, or DROP tables and indexes).

  2. Reference schema-design.md for guidelines on primary key selection and interleaved tables.

Diagnosing Performance Issues
  1. Use SPANNER_SYS tables to identify slow or resource-intensive queries.

  2. For example, query SPANNER_SYS.QUERY_STATS_TOP_HOUR to find queries with the highest CPU usage.

Reference Directory

  • Core Concepts: Explanation of Spanner internals, architecture, and design.

  • CLI Usage: Essential gcloud spanner command-line operations for managing instances and databases.

  • IAM Security: Roles, permissions, and data governance best practices for Spanner.

  • Client Library Usage: Using Google Cloud client libraries for Spanner (Java, Go, Python, Node.js).

  • Terraform Usage: Infrastructure as Code examples for provisioning Spanner instances and databases.

  • MCP Usage: Using the Spanner remote MCP server.

  • PostgreSQL Dialect: Best practices and examples for using the PostgreSQL interface in Spanner.

  • Queues Usage: Cloud Spanner Queues: mental model, design constraints, and links related to transactional message queues.

  • Schema Design: Guidelines on primary key selection and interleaved tables for performance.

If you need product information that's not found in these references, use the search_documents tool of the Developer Knowledge MCP server.

Files

references/queues-usage.md

Cloud Spanner Queues Usage

Cloud Spanner Queues provide an integrated, transactional messaging system built directly into Spanner. They let applications perform asynchronous and scheduled work reliably without running separate queuing infrastructure.

Prerequisite: Queues require the Enterprise or Enterprise Plus Spanner edition.

Table of Contents

  • Authoritative Public Documentation: Lines 18-33

  • Mental Model: Lines 37-54

  • Canonical Syntax & Operations: Lines 58-158

  • Constraints Worth Knowing Before You Design: Lines 162-179

  • Observability: Lines 183-196

  • Agent Verification Checklist: Lines 200-213

Authoritative Public Documentation

The DDL, the receive and renew-lease table-valued functions (TVFs), their parameters, defaults, and limits evolve. Fetch the current pages (or query the Developer Knowledge MCP server via search_documents) before writing or reviewing Spanner queue code:

PageUse it for
Queues OverviewConcepts, delivery semantics, when to use queues.
Use Spanner QueuesTask-by-task how-to: create, send, receive, renew, ack.
Queue ExamplesEnd-to-end examples and worker patterns.
At-Most-Once ProcessingAchieving at-most-once processing.
GoogleSQL DDL ReferenceAuthoritative GoogleSQL queue DDL grammar and options.
PostgreSQL DDL ReferenceAuthoritative PostgreSQL-dialect queue DDL grammar.
Fine-Grained Access Control for QueuesFine-grained access control for queues.
Spanner Quotas & LimitsQueue quotas and limits, including receiver concurrency.

Mental Model

These properties define how queues behave and are what the rest of a design should rest on:

  • Transactional. Sending and acknowledging happen inside ordinary read-write transactions, so they commit atomically with your table writes. This is the whole point of queues living in Spanner: no dual-write problem between a database and an external broker.

  • At-least-once delivery. A message is redelivered until acknowledged. Leases reduce duplicate work but do not guarantee exclusivity, so consumers must be idempotent.

  • Exactly-once acknowledgment. Acking is a transactional delete of the message row, so a given message can only be acked once.

  • Short leases. A delivered message is leased briefly (default 10 seconds). The worker acknowledges it or renews the lease before expiry, or it is redelivered. Long work should renew in a loop, or checkpoint by acking and re-sending with a future delivery time.

  • Scheduled delivery. Every message can carry a future delivery time (DeliverTime in GoogleSQL, deliver_time in PostgreSQL), which removes the need for polling or a separate scheduler.

  • A schema object. A queue has a primary key, appears in INFORMATION_SCHEMA, can be interleaved in a parent table, and can be inspected with an ordinary SELECT.


Canonical Syntax & Operations

1. Create a Queue (CREATE QUEUE)

Define a primary key (avoid monotonic leading keys; use a UUID or interleave under a high-cardinality parent table) and a non-nullable Payload column. DeliverTime (deliver_time in PostgreSQL) is created automatically by Spanner and must not be declared in CREATE QUEUE.

-- GoogleSQL
CREATE QUEUE UserTasks (
  UserId    INT64 NOT NULL,
  MessageId STRING(36) NOT NULL,
  Payload   BYTES(MAX) NOT NULL
) PRIMARY KEY (UserId, MessageId),
INTERLEAVE IN PARENT Users ON DELETE CASCADE;

-- PostgreSQL dialect
CREATE QUEUE usertasks (
  userid    bigint NOT NULL,
  messageid varchar(36) NOT NULL,
  payload   bytea NOT NULL,
  PRIMARY KEY (userid, messageid)
) INTERLEAVE IN PARENT users ON DELETE CASCADE;
2. Send a Message (INSERT or Client Library Send Mutation)

Insert into the queue inside the same read-write transaction as your application table updates:

-- GoogleSQL (immediate or scheduled delivery via DeliverTime)
INSERT INTO UserTasks (UserId, MessageId, Payload, DeliverTime)
VALUES (@userId, @messageId, @payload, TIMESTAMP_ADD(CURRENT_TIMESTAMP(), INTERVAL 10 MINUTE));

-- PostgreSQL dialect
INSERT INTO usertasks (userid, messageid, payload, deliver_time)
VALUES ($1, $2, $3, CURRENT_TIMESTAMP + INTERVAL '10 MINUTE');

Client libraries also provide spanner.Send("UserTasks", key, payload, spanner.WithDeliveryTime(t)) (Go) and Mutation.newSendBuilder("UserTasks") (Java).

3. Receive Messages (RECEIVE_<QueueName>)

Stream messages using ExecuteStreamingSQL with a strong, single-use, read-only transaction:

-- GoogleSQL
SELECT UserId, MessageId, Payload, DeliverTime,
       SpannerLeaseExpirationTimestamp, SpannerLeaseToken, SpannerLastBatchMessage
FROM RECEIVE_UserTasks(max_duration => '20m', max_batch_size => 20);

-- PostgreSQL dialect
SELECT userid, messageid, payload, deliver_time,
       spanner_lease_expiration_timestamp, spanner_lease_token, spanner_last_batch_message
FROM spanner.receive_usertasks(20, NULL, '20m');
4. Renew Leases (RENEWLEASE_<QueueName>) and Acknowledge (DELETE / Ack)
-- GoogleSQL: Renew lease (returns SpannerOldLeaseToken, SpannerNewLeaseToken, SpannerLeaseExpirationTimestamp)
SELECT * FROM RENEWLEASE_UserTasks(lease_tokens => [@leaseToken]);

-- GoogleSQL: Acknowledge message transactionally (guard with ASSERT_ROWS_MODIFIED 1)
DELETE FROM UserTasks WHERE UserId = @userId AND MessageId = @messageId ASSERT_ROWS_MODIFIED 1;

-- PostgreSQL dialect: Renew lease and Acknowledge
SELECT * FROM spanner.renewlease_usertasks(lease_tokens => ARRAY[$1]);
DELETE FROM usertasks WHERE userid = $1 AND messageid = $2 ASSERT_ROWS_MODIFIED 1;

Client libraries also provide spanner.Ack("UserTasks", key) (Go) and Mutation.newAckBuilder("UserTasks") (Java), which fail the transaction if the message row was already deleted.

Handle Long-Running Work

When processing can outlast the lease (default 10 seconds), use one of two patterns:

  • Renew in a loop. In a separate thread or goroutine, call RENEWLEASE_<QueueName> periodically (for example, every 5 seconds) with the latest lease token. When the work finishes, ack the message in the same transaction as the resulting writes.

  • Ack and reschedule. On arrival, ack the message and, in the same transaction, send a new message with a delivery time beyond the expected processing time. Process the work, then ack the new message.

-- GoogleSQL: ack and reschedule in one read-write transaction
DELETE FROM UserTasks WHERE UserId = @userId AND MessageId = @messageId ASSERT_ROWS_MODIFIED 1;
INSERT INTO UserTasks (UserId, MessageId, Payload, DeliverTime)
VALUES (@userId, @newMessageId, @payload, TIMESTAMP_ADD(CURRENT_TIMESTAMP(), INTERVAL 30 MINUTE));

Ack and reschedule needs no renewal loop, and a crash is covered because the new message is redelivered at its delivery time. If the initial ack succeeds, it achieves at-most-once processing. It is also the recommended checkpoint for tasks lasting minutes to hours: store task state in a table and have each rescheduled message point to the latest checkpoint.


Constraints Worth Knowing Before You Design

Durable behaviors that shape architecture, and that are easy to get wrong:

  • A queue holds only its primary key columns and Payload. No extra columns. Application state belongs in regular tables.

  • Keep payloads small (< 4 KB). Small messages take a faster delivery path. Store blobs in a table or Cloud Storage and enqueue a key.

  • Receive queries are restricted. They must be strong, single-use, read-only, and streamed, and they cannot be joined against other tables. Filtering is supported.

  • Lease tokens rotate on renewal. A successful renewal returns a new token (SpannerNewLeaseToken / spanner_new_lease_token) that supersedes the old one; carry it forward or the next renewal fails. If SpannerNewLeaseToken is NULL, the message is no longer renewable.

  • Guard your ack. A plain delete silently succeeds when the row is already gone, hiding a lost race. Always use ASSERT_ROWS_MODIFIED 1 or the dedicated Ack mutation.

  • Receiver concurrency is quota-limited per project per region; exceeding it returns RESOURCE_EXHAUSTED. Size worker fleets with that in mind.

  • Retention is a row deletion policy (TTL), the same mechanism used for tables.


Observability

Queue metrics are published to Cloud Monitoring under the spanner.googleapis.com/queue/* prefix, on the spanner_instance resource, labeled by database and queue. For the current list of names, kinds, and units, search the metrics reference for queue/: Spanner Cloud Monitoring Metrics

The signal to alert on is the age of the oldest unacknowledged message: it is the end-to-end measure of a queue falling behind. Send and ack counts show whether consumers keep up with producers, and lease expirations point at slow handlers, crashes, or a missing renewal loop.

There are no queue-specific SPANNER_SYS tables. Receive queries and ack transactions show up in the general introspection views, and tagging those statements with request tags makes them easy to find. See Spanner Introspection Overview.


Agent Verification Checklist

  • [ ] Docs consulted: Current queue pages were fetched; syntax was not guessed from memory.

  • [ ] Edition: Instance is Enterprise or Enterprise Plus.

  • [ ] Dialect: GoogleSQL versus PostgreSQL-dialect syntax and system column names match the target database.

  • [ ] Schema: No columns beyond the primary key and Payload (DeliverTime is implicit); payloads are kept small (< 4 KB).

  • [ ] Receive: Strong, single-use, read-only, streamed; no joins on the TVF.

  • [ ] Leases: Work that can outlast the 10s lease renews in a loop and carries the rotated token, or uses an ack-and-reschedule checkpoint instead.

  • [ ] Ack: Guarded with ASSERT_ROWS_MODIFIED 1 or Ack mutation, and committed in the same transaction as the resulting application writes.

  • [ ] Idempotency: Redelivery is safe.

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Needs: Needs an MCP server

Security

What our scanner noticed· Low risk

  • Instructions that use the network

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Published by
Google
Publisher
Google (Official)
Source
google/skills · skills/cloud/spanner-basics · commit 2194d3b
Licence
Apache License 2.0 (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by Google or Google.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download spanner-basics.zip