# Spanner emulator

> Run Spanner locally: GoogleSQL and PostgreSQL queries, transactions, graph and vector search, and administration on ports 5386 and 5387.
>
> Source: https://local.cloud/services/spanner/

Spanner is a distributed database with SQL and transactional consistency. Use its relational model when application workflows need coordinated updates across related records.

## Typical uses

Use when related records need transactional consistency and SQL queries, and your production architecture requires a database that can scale across nodes.

Examples

- Transactional order and inventory systems
- Relational applications using GoogleSQL or PostgreSQL

Connection

Environment variable

`SPANNER_EMULATOR_HOST=localhost:5386`

Runtime details

- **Endpoints:** gRPC :5386 · HTTP/REST :5387
- **Minimum tier:** [Pro tier, free during preview](https://local.cloud/pricing/#pro-tier)
- **Persistence:** service-data
- **Implementation:** Extended Official

## Example usage

Service ID: `spanner`. Starts by default. Use an already running LocalCloud runtime for the examples below.

Export the local project and mapped endpoints in your client process, then use the client settings below. [First-time setup](https://local.cloud/docs/)

```bash
# Export GOOGLE_CLOUD_PROJECT and SPANNER_EMULATOR_HOST
eval "$(localcloud env)"
```

REST gateway examples use the generated HTTP address in `SERVICE_USAGE_EMULATOR_HOST`; native SDKs can use a different protocol.

Python:

### Python

### Create a database and query a row

Create a schema, insert a row, and query it; Spanner combines relational SQL with transactional consistency.

Apply DDL, insert a fixture, query through the native SDK, and remove owned resources.

SDK dependencies

Run in a new example directory

```bash
python3 -m venv .venv
source .venv/bin/activate
python -m pip install google-cloud-spanner
```

#### Save as hello.py

```python
import os
from uuid import uuid4
from google.cloud import spanner

assert os.environ['SPANNER_EMULATOR_HOST']
client = spanner.Client(project=os.environ['GOOGLE_CLOUD_PROJECT'])
instance = client.instance('guide-' + uuid4().hex[:12], configuration_name='projects/' + client.project + '/instanceConfigs/emulator-config', display_name='Guide', node_count=1)
instance.create().result(timeout=60)
try:
    database = instance.database('messages', ddl_statements=['CREATE TABLE Messages (Id INT64 NOT NULL, Message STRING(100)) PRIMARY KEY (Id)'])
    database.create().result(timeout=60)
    with database.batch() as batch:
        batch.insert('Messages', columns=('Id', 'Message'), values=[(1, 'hello')])
    with database.snapshot() as snapshot:
        rows = list(snapshot.execute_sql('SELECT Message FROM Messages WHERE Id = 1'))
        assert rows == [['hello']]
        print(rows[0][0])
    database.drop()
finally:
    instance.delete()
    client.close()
```

#### Run the example

```bash
python hello.py
```

#### Verify the result

The command completes successfully and prints the expected output shown below.

#### Expected output

```
hello
```

[Full example guide](https://local.cloud/docs/sdk-examples/#spanner-python)

Java:

### Java

### List local Spanner instances

List database instances; Spanner groups relational databases that provide SQL queries and consistent transactions.

Configure the generated emulator endpoint on the Spanner client. Requires JDK 17+ and Maven.

Discovery check · reads existing local state.

SDK dependencies

Run in a new example directory

```bash
cat > pom.xml <<'XML'
<project xmlns="http://maven.apache.org/POM/4.0.0">
  <modelVersion>4.0.0</modelVersion>
  <groupId>example</groupId><artifactId>local-example</artifactId><version>1</version>
  <dependencies><dependency>
    <groupId>com.google.cloud</groupId><artifactId>google-cloud-spanner</artifactId><version>6.124.0</version>
  </dependency></dependencies>
</project>
XML
mvn -q dependency:build-classpath -Dmdep.outputFile=classpath.txt
```

#### Save as Hello.java

```java
import com.google.cloud.spanner.SpannerOptions;
import java.util.Objects;

public class Hello {
  public static void main(String[] args) {
    var options = SpannerOptions.newBuilder()
        .setProjectId(Objects.requireNonNull(System.getenv("GOOGLE_CLOUD_PROJECT")))
        .setEmulatorHost(Objects.requireNonNull(System.getenv("SPANNER_EMULATOR_HOST"))).build();
    try (var spanner = options.getService()) {
      for (var instance : spanner.getInstanceAdminClient().listInstances().iterateAll()) {
        System.out.println(instance.getId().getInstance());
      }
    }
  }
}
```

#### Run the example

```bash
java --class-path "$(cat classpath.txt)" Hello.java
```

#### Verify the result

The request succeeds. An empty list or no printed rows is valid before matching resources exist. Continue with the documented workflows for a resource test.

gcloud CLI:

### gcloud CLI

### List local Spanner instances

List database instances; Spanner groups the SQL databases used by transactional application workflows.

Use the gateway REST endpoint for gcloud; the SDK uses SPANNER\_EMULATOR\_HOST.

Discovery check · reads existing local state.

#### Configure gcloud CLI

```bash
: "${SERVICE_USAGE_EMULATOR_HOST:?Export the LocalCloud environment first}"
export CLOUDSDK_CORE_PROJECT="${GOOGLE_CLOUD_PROJECT:?Export the LocalCloud environment first}"
export CLOUDSDK_AUTH_DISABLE_CREDENTIALS=true
export CLOUDSDK_API_ENDPOINT_OVERRIDES_SPANNER="${SERVICE_USAGE_EMULATOR_HOST%/}/"
```

#### Run in your terminal

```bash
gcloud spanner instances list
```

#### Verify the result

The request succeeds. An empty list or no printed rows is valid before matching resources exist. Continue with the documented workflows for a resource test.

Verify a resource workflow by creating isolated state, performing the operation, and reading the result back. Run cleanup even after a failure; delete only test-owned resources.

Connection failed? Check `localcloud status --verbose`, enabled services, and client exports. Stop accidental Google Cloud calls; correct local routing before retrying.

## Documented workflows

- ### GoogleSQL/PostgreSQL queries, UUIDs, and change streams

    Create a database in the chosen dialect, apply DDL, insert fixtures, and assert query results. For change streams, use streaming SQL and verify records produced by committed writes.

- ### Full-text/vector search, property graphs, and graph algorithms

    Build small text, vector, or property-graph fixtures, run the application query, and assert matched rows or paths. Keep input shape and expected ordering explicit for search and graph tests.

- ### Sessions, serializable/repeatable-read transactions, and batch DML

    Open sessions and commit related writes in a transaction. Exercise the selected isolation level, conflicting updates, retries, and batch-DML results with application assertions.

- ### Partitioned queries/reads and batch writes

    Partition a read or query, process every returned token, and compare the combined result with a normal read. For batch writes, inspect each mutation-group result before retrying failures.

- ### Instance/database administration, DDL, and long-running operations

    Create an instance and database, apply schema changes, and poll the returned operation. Read back configuration and DDL so provisioning tests verify the resulting resource.

- ### Database roles and fine-grained access control

    Create database roles and a session with creator\_role, then test allowed and denied queries and mutations. Stored network IAM policies and database-role enforcement are distinct checks.

- ### Backup creation, copy, restore, and schedules

    Use persistent storage, create a backup of known data, and restore it into a separate database. Compare rows and schema after restore, and inspect schedules independently of backup creation.

## Service boundaries

- Change streams require streaming SQL
- Backups and durable stream recovery require a persistent data directory
- Unauthenticated emulator connections bypass network IAM
- No CMEK; Google TrueTime and regional infrastructure are cloud-only

## Code examples and integrations

- [Build an integration test loop](https://local.cloud/gcp-integration-testing/): Start the runtime, verify readiness, exercise your SDK, and clean up test state.
- [Spanner emulator feature comparison](https://local.cloud/compare/emulators/?service=spanner): Browse features by category, see which ones only LocalCloud offers, and open Google's documentation for each.
- [Official SDK code samples](https://docs.cloud.google.com/spanner/docs/samples): Browse language-specific samples. Adapt endpoints and use the local workflows listed above.

Agent testing

## Use Spanner with an AI agent

Before the agent changes application logic, have it create local Spanner state, read it back with the project SDK, and note which feature the check covered. That first local call catches accidental production routing and needs no GCP account, service-account key, or billing project.

### Configure this repo

```
Set up this repository to use LocalCloud for local GCP development. First read https://local.cloud/ai/agents.md, then inspect this repo, identify the GCP services and SDK language, configure emulator environment variables, and run the narrowest integration test against localhost. Do not use real GCP credentials or production endpoints.
```

Production endpoints, auth, IAM, quotas, regional behavior, and final release validation still need the target Google Cloud project.

[Agent resources](https://local.cloud/ai/) has more prompts and the AGENTS.md template.

## Spanner emulator FAQ

### How do I run Spanner locally?

Start LocalCloud using the setup guide, then export its environment in the same terminal as your application.

### Which environment variable points the SDK at the local Spanner?

LocalCloud exports SPANNER\_EMULATOR\_HOST=localhost:5386. Use the generated value, because the CLI picks another port when the default is in use. Some SDKs also need explicit client endpoint options; the variable alone does not route them locally.

### Does the local Spanner behave exactly like Google Cloud?

No. LocalCloud runs the documented workflows on this page within the service boundaries listed here. Validate behavior against real Spanner before production deployment.

## Related guides

- [Compatibility](https://local.cloud/compatibility/): compare all 27 service guides.
- [Configuration](https://local.cloud/docs/configuration/): service selection and runtime settings.
- [Spanner feature reference](https://local.cloud/docs/spanner-emulator-features/): detailed operation and recovery notes.
- [Official Spanner documentation](https://cloud.google.com/spanner): service concepts and cloud usage.
