Browse documentation Spanner emulator features
Learn Spanner emulator features

Spanner emulator feature reference

LocalCloud packages an extended Cloud Spanner emulator for bounded local SDK and API workflows. The dependency has useful semantic coverage, but the exact assembled LocalCloud image has not been qualified.

Connection and persistence

SurfaceValueBoundary
gRPClocalhost:24085Primary official Spanner SDK endpoint through SPANNER_EMULATOR_HOST.
RESThttp://localhost:24086HTTP/grpc-gateway, not PGAdapter.
SQL dialectsGoogleSQL and PostgreSQL dialect through the Spanner APIPostgreSQL dialect support does not imply PostgreSQL-wire support.
StorageLevelDB rows plus JSON metadata under /var/lib/localcloud/spanner-dataOrdinary stop/start retains state; mount the LocalCloud volume for container removal or replacement.
Aggregate staterelease-unverifiedDependency behavior has not been qualified in an identified assembled image.

Official Python SDK example

import os
from google.cloud import spanner

os.environ["SPANNER_EMULATOR_HOST"] = "localhost:24085"

client = spanner.Client(project="local-gcp-project")
instance = client.instance("test-instance")
database = instance.database("test-database")

with database.snapshot() as snapshot:
    rows = snapshot.execute_sql("SELECT 1 AS value")
    print(list(rows))

Create the instance and database through the Spanner API before running the query. Do not replace this with a guessed PostgreSQL-wire URL.

Current operation contract

Operation areaStateBoundary
Native SQL, read, and streaming readunknownChange-stream reads use native ExecuteStreamingSql. Unary ExecuteSql intentionally retains the emulator's rejection of change-stream queries.
Sessions, transactions, and batch DMLunknownExisting native transaction and session behavior remains authoritative.
Partition query/read and batch writeunknownExisting native partition and batch-write behavior remains authoritative.
Instance, configuration, and instance-partition administrationunknownExisting native instance-admin behavior remains authoritative.
Database administration and DDLunknownExisting native database-admin behavior remains authoritative.
Instance and database IAM policiesunknownPolicies are stored durably and returned through native endpoints. Authorization remains intentionally permissive and TestIamPermissions returns requested permissions.
Backup, copy, restore, and backup schedulesunknownBackups and schedules use LevelDB-backed metadata and compatible long-running operations.
Long-running operation lifecycleunknownNative operation polling and lifecycle behavior is shared by instance, database, backup, copy, and restore calls.

Feature-specific interpretation

Core API, SQL, and transactions

Instance/database administration, schema, SQL/DML, transactions, indexes, generated columns, commit timestamps, JSON, NUMERIC, and partitioned paths are dependency-backed local workflows. Keep them release-unverified until an immutable dependency and assembled image are qualified. MERGE remains unsupported.

PostgreSQL dialect

The Spanner PostgreSQL dialect is processed through the Spanner API. It does not make port 24086 a PostgreSQL server and does not establish compatibility with generic PostgreSQL drivers or ORMs. A separate tested PGAdapter process and dedicated port would be required for those clients.

TABLESAMPLE

Dependency evidence supports bounded BERNOULLI and RESERVOIR behavior. SYSTEM and REPEATABLE remain unsupported, and the assembled image is not qualified.

Change streams

The dependency implements change-stream paths for GoogleSQL and PostgreSQL dialects with limitations. Treat them as release-unverified until the exact dependency revision and assembled LocalCloud image pass targeted conformance tests.

IAM

LocalCloud registers setIamPolicy, getIamPolicy, and testIamPermissions gateway stubs. This is a partial permissive compatibility surface, not production IAM enforcement.

Backups and internal snapshots

Cloud Spanner Backup APIs are unsupported. Internal safety snapshots used for emulator recovery must not be documented as backup API support or as a production recovery guarantee.

Recovery and operations

Rows are stored in LevelDB and metadata in JSON files. Mounting the LocalCloud volume protects state across container removal or replacement, not just ordinary stop/start. Known corruption and recovery risk remains; test restore and replacement workflows before relying on local state.

Production concurrency, scale, quota, IAM, backup, monitoring, audit, performance, regional, and operational behavior still requires real Cloud Spanner validation.

Publication exit criteria

A verified release claim requires the dependency source revision or image digest, assembled LocalCloud image digest, gRPC and REST smoke results, change-stream and TABLESAMPLE conformance evidence, persistence/replacement tests, negative PostgreSQL-wire and Backup/IAM enforcement tests, evidence path, and release association.

Maintained by LocalCloud