Bigtable emulator feature reference
LocalCloud runs a separately maintained Bigtable emulator for row and administration APIs. The current Docker build pins a source commit.
Connection and persistence
| Surface | Canonical value | Boundary |
|---|---|---|
| Primary API | gRPC on localhost:5385 | Use BIGTABLE_EMULATOR_HOST from localcloud env for actual mapped ports. |
| Backing store | PostgreSQL under the mounted LocalCloud volume | A standalone dependency’s SQLite configuration is not the LocalCloud default. |
| Console SQL | LocalCloud SQL-to-row-API translator | Separate from native GoogleSQL PrepareQuery / ExecuteQuery and session protocols. |
Current operation contract
| Operation area | Status | Boundary |
|---|---|---|
| instances/tables/families | Supported | The pinned little_bigtable v0.5.0 emulates instance, cluster, app-profile, table and schema-bundle administration as validated metadata (ID and field rules, response views, update masks, pagination, deletion protection, soft delete and 7-day undelete, atomic column-family changes, initial splits, row key schema) with a durable long-running-operation registry. Cluster nodes and autoscaling settings are stored without capacity effects. Dependency conformance tests pass. |
| row mutations and reads | Supported | The emulator validates every mutation before applying any (single-row atomicity), reports real per-entry MutateRows codes, honors idempotency tokens and aggregate (Sum/Min/Max, HLL++) families, implements every RowFilter including Interleave duplicates, Sink (cells bypass subsequent filters; invalid inside Condition) and ValueBitmask, chunks ReadRows like production with request stats, samples SampleRowKeys within row ranges, enforces authorized-view, materialized-view and app-profile targets, and serves the OpenTable/OpenAuthorizedView/OpenMaterializedView session protocol. last_scanned_row_key is not emitted. Sink output and rejection inside Condition have named dependency conformance tests; validate Sink filters in your own test suite. Dependency conformance tests pass. |
| cbt CLI compatibility | Supported | The `cbt` CLI works with BIGTABLE_EMULATOR_HOST env var. Arbitrary project and instance IDs are accepted on-demand without pre-registration, matching Google Cloud SDK CBT emulator behavior. The gRPC data plane accepts requests without an authorization header or credential provider. Instance CRUD (create/list/get/delete instance) is supported via gRPC. Table and row operations work as expected. The pinned cbt conformance test was skipped because cbt was not installed; validate cbt scripts in your own test suite. |
| localcloud console data browser | Supported | REST endpoints for instance/table/row CRUD exposed via BigtableAdminService: - GET /.../tables/{table}/rows — browse rows - POST /.../tables/{table}/rows — write cells - DELETE /.../tables/{table}/rows/{rowKey} — delete row SDK and console share the same PostgreSQL-backed emulator state. Instance, table and backup routes forward to the emulator and return its errors with the Google API HTTP mapping (FAILED_PRECONDITION as 400, for example). Row writes and deletes, app-profile and view routes still ignore emulator errors and report success from local placeholder state, and instance PATCH/PUT and table PATCH answer locally without reaching the emulator, so a rejected request on those routes can appear to succeed. |
| data survives emulator restart | Supported | The emulator persists all resource state in PostgreSQL, including table policy fields, views, schema bundles, backups and their row snapshots, IAM policies, long-running operations, the change-stream outbox and idempotency tokens. On first start it migrates table metadata in place (one-way). Its restart tests ran on SQLite; validate PostgreSQL restart durability in your own test suite. |
| materialized views (CMVs) | Supported | The emulator implements continuous materialized views from GoogleSQL GROUP BY or ORDER BY definitions over existing tables. Views are read-only, read through materialized_view_name (ReadRows, SampleRowKeys, sessions) or GoogleSQL, recomputed before a read when stale, limited to 50 per instance and 5 per source table, and their query is immutable. Multi-column row-key encoding is emulator-specific. |
| GoogleSQL queries and logical views | Supported | The emulator builds its GoogleSQL engine by default. PrepareQuery returns a prepared-query token valid for one hour; ExecuteQuery streams typed ProtoRows batches with CRC32C checksums and resume tokens, and returns FailedPrecondition (PREPARED_QUERY_EXPIRED) after a schema change. Logical-view queries are validated against existing tables and are queryable. Query statistics and view parameters are not emulated. The Console SQL editor uses LocalCloud's separate translator. |
| change streams | Supported | The emulator records changes only for tables with change_stream_config (1-7 day retention). ReadChangeStream returns one grouped record per row commit, garbage-collection and DropRowRange records, heartbeats with continuation tokens and low watermarks, resumes from tokens and closes at end_time. It requires a single-cluster app profile. One partition covers the whole key space, so partition split and merge are not exercised. |
| snapshots and backups | Supported | Backups are immutable schema-and-row snapshots with create, get, list (filter, order, pagination), update, copy, delete and restore to a new table independent of the live source, including expire-time, backup-type and quota rules. UndeleteTable restores a deleted table within 7 days. Legacy table snapshot RPCs return Unimplemented because they are a deprecated private-alpha API. The LocalCloud REST facade forwards backup create, get, list, update (with the required updateMask), copy, delete, restore and undelete to the emulator and returns its errors. |
| IAM policy management | Supported | The emulator persists policies on existing Bigtable resources with etags (Aborted on mismatch) and update masks, and returns NotFound for missing resources. Policies are permissive. TestIamPermissions grants every requested permission and nothing is enforced on the direct gRPC listener, because the emulator is unauthenticated. |
| new proto methods return Unimplemented (no panics) | Supported | The executable ledger dispositions all 89 registered RPCs of the cloud.google.com/go/bigtable v1.58.0 interface, and a test fails if one is missing. Intentionally unsupported RPCs (legacy snapshots, hot tablets, memory layers) return Unimplemented instead of panicking. PingAndWarm validates the instance name and app profile. |
Runtime and recovery limits
- The pinned little_bigtable v0.5.0 passes its dependency test suite, and its executable ledger covers all 89 registered RPCs. Those tests cover the dependency source, not the LocalCloud image. It ran on SQLite rather than LocalCloud's PostgreSQL backend and skipped the pinned cbt test. Confirm project deletion and backup listing through the native admin API. The LocalCloud fixes for both pass BigtablePlatformTest with a source JAR over that image.
- IAM policies persist but are not enforced. TestIamPermissions grants every requested permission because the emulator is unauthenticated; the direct gRPC listener also bypasses gateway IAM.
- Change streams use one partition with no split or merge. last_scanned_row_key is not emitted, logical views do not support view parameters, query statistics are not recorded, and google.cloud.location.Locations is not served.
- HLL++ aggregate sketch bytes and multi-column materialized-view row keys use emulator-specific encodings that are not byte-compatible with production.
- Legacy table snapshot RPCs (SnapshotTable, GetSnapshot, ListSnapshots, DeleteSnapshot, CreateTableFromSnapshot) return Unimplemented; they are a deprecated private-alpha API. Use backups for data protection.
- The Console REST admin facade ignores emulator errors on row writes and deletes and on app-profile and view routes, then reports success from local placeholder state. Instance PATCH/PUT and table PATCH answer locally without reaching the emulator, and logical and materialized view updates drop their update masks. Verify through the native API when a result must reflect emulator validation.
- LocalCloud Docker is intended to retain PostgreSQL-backed service data while the mounted /var/lib/localcloud volume is retained
- The machine-local cached artifact can use PostgreSQL or SQLite, but the LocalCloud Docker product is configured for PostgreSQL.
- Test restart recovery with the exact LocalCloud image you run.
Metadata-only backup, view, or IAM operations do not prove data restoration, query execution, or authorization enforcement. Assert exact row bytes through the application data client and test required connector behavior separately. Validate production-managed behavior in Google Cloud.
This comment is sent to PostHog. Do not include secrets, personal data, or customer data. See Privacy.