Database / Google Cloud Bigtable Interview questions
Last updated
1. What is Google Cloud Bigtable?
Cloud Bigtable is Google Cloud's fully managed, wide-column NoSQL database for very large workloads that need consistently low latency. It grows from a few gigabytes to petabytes, and it is built on the same ideas as the internal system behind products like Search and Maps.
Data lives in tables as a sorted map: each row is found by a single row key, and each row can hold millions of sparse columns. You scale throughput by adding nodes, and Google handles patching, replication and failover.
There are no joins and no multi-row transactions, so it fits key-based access patterns (time series, user profiles, events) better than relational reporting.
Take quiz
A sorted, sparse wide-column map addressed by row key
Normalized relational tables joined with foreign keys
JSON documents organised in nested collections
A property graph of vertices and edges
Create secondary indexes on hot columns
Add nodes to the cluster
Increase the number of column families
Upgrade the tables to a larger machine type
2. What type of NoSQL database is Bigtable?
Bigtable is a wide-column store. Conceptually it is a persistent, sorted, multi-dimensional map: (row key, column family:qualifier, timestamp) maps to a value. Rows are stored in lexicographic order of the row key, which is what makes range scans fast.
It is often confused with plain key-value or document stores, so the table below shows where it sits.
| Type | Typical example | How data is addressed |
| Key-value | Redis | One key, one opaque value |
| Document | Firestore | Document ID, with indexed fields |
| Wide-column | Bigtable, Cassandra | Row key, then family:qualifier, then timestamp |
| Graph | Neo4j | Nodes and relationships |
One important catch: Bigtable has no built-in secondary indexes. If you need to look data up two ways, you design two row key layouts or keep a second table.
Take quiz
Every column is indexed automatically
Only the timestamp is indexed by default
Lookups rely on the row key, so alternate access paths need extra tables or views
You create B-tree indexes with CREATE INDEX
By the first column family alphabetically
By insertion time
By a hash of the row key
Lexicographically by row key bytes
3. What are the main components of a Bigtable deployment?
A deployment is built from four pieces: instance, cluster, node and table.
- Instance - the top-level container. It holds clusters and tables, and carries the instance-level settings such as app profiles.
- Cluster - a set of nodes living in one zone. You pick SSD or HDD storage when you create it. An instance can have several clusters, and that is how replication is set up.
- Node - the compute unit that serves reads and writes for the tablets assigned to it. Nodes do not hold the data themselves.
- Table - belongs to the instance, so every cluster in that instance serves the same tables.
A common slip is to think each cluster has its own tables. It does not: tables are instance-wide and replication keeps the clusters in sync.
Take quiz
To the instance, shared by every cluster in it
To a zone, independent of any instance
To one node that owns all of its rows
To a single cluster chosen at creation time
A separate schema namespace
Compute to serve requests for assigned tablets
Permanent local disk holding the only copy of the data
A dedicated backup target
4. What is a row key in Bigtable?
The row key is the unique identifier of a row and the only indexed field in a table. Bigtable keeps rows sorted by it, so every read is either a point lookup on a key, a prefix scan, or a range between two keys.
Keys are plain byte strings with a hard limit of 4 KB, though you should keep them far shorter. A good key puts data you read together next to each other and avoids sequential prefixes that pile traffic onto one node.
user#00417#2026-10-22 device#thermo-9#sensor#temp
Because the key drives performance and cost more than anything else in the schema, changing it later means rewriting the table.
Take quiz
256 MB
64 bytes
4 KB
1 MB
A random UUID per order
order#...#customer#417 so the customer id is at the end
The order timestamp alone
customer#417#order#... so the customer id is a prefix
5. What are column families in Bigtable?
A column family is a named group of related columns inside a table. You must create the family before writing data into it, and every column belongs to exactly one family.
Families matter for two practical reasons. First, garbage collection policies are set per family, so you can keep one family's cells for 7 days and another's forever. Second, a read can ask for only certain families, which keeps responses small.
Keep the number small. Google recommends staying around 100 families per table at most, and short family names save space because the name is repeated in storage. Put data that is read together in the same family, and data with different retention in separate ones.
cbt createfamily events metrics cbt createfamily events profile
Take quiz
On each column family
On the whole instance only
On each individual row
On each node
One part uses string values and the other uses integers
One part expires after 7 days while the other is kept long term
Two teams prefer different naming styles
To get a second row key per row
6. What is a column qualifier in Bigtable?
A column qualifier is the name of a column inside a column family. A full column is written as family:qualifier, for example profile:email.
Unlike a relational schema, qualifiers are not declared up front. A write simply names a new qualifier and it exists, and rows in the same table can use completely different sets. Because empty cells cost nothing, tables stay sparse.
This also lets you store data in the qualifier. A common trick is one family called follows where each qualifier is a followed user's ID and the value is empty, giving you a compact adjacency list in one row. Qualifiers can be up to 16 KB, but keeping them short pays off.
Take quiz
At instance creation only
Before the first row is inserted, using ALTER TABLE
It does not need to be declared; a write can create it
Only by an admin through the console
qualifier/timestamp/family
family->row key
table.row.column
family:qualifier
7. What is a cell in Bigtable?
A cell is the value stored where a row key meets a column (family:qualifier). Each cell carries a timestamp, and a column can hold many timestamped versions of the same cell.
So the real address of a value is three-part: row key, column, and timestamp. By default Bigtable stamps a write with the server time in microseconds, but your client can supply one, which is how you control versioning or make a retry idempotent.
| Row key | Column | Timestamp | Value |
| user#417 | profile:city | 1729600000000000 | Charlotte |
| user#417 | profile:city | 1729500000000000 | Raleigh |
A read returns the newest version unless you filter otherwise, and garbage collection removes older ones. Cells are capped at 100 MB, though around 10 MB is the sensible ceiling.
Take quiz
Row key, column, and timestamp
Row key, partition key, and version vector
Table, shard, and offset
Column family, node ID, and checksum
Only the second write; the first is overwritten immediately
Two versions of the cell, until garbage collection removes the older
A conflict error that needs resolving
Two separate rows
8. What is a tablet in Bigtable?
A tablet is a contiguous range of rows from a table. Bigtable splits tables into tablets automatically and treats the tablet as the unit it balances across nodes.
Tablets are stored as SSTable files in Google's distributed file system, Colossus, not on the nodes. A node just holds pointers to the tablets it currently serves. That is why moving a tablet to another node is cheap: only the assignment changes, no data is copied.
Bigtable splits a tablet when it grows large or gets busy, and merges small neighbours back together. You do not manage this by hand, but your row key design decides whether the load spreads across many tablets or lands on one.
Take quiz
In memory on the frontend
On the local disk of the serving node only
In Colossus as SSTable files
In Cloud Storage buckets you manage
It waits for a maintenance window
It rebuilds the tablet from a backup
It streams the whole tablet over the network first
Only the node assignment changes because the data stays in Colossus
9. What storage types are available in Bigtable?
You choose the storage type when you create a cluster, and you cannot switch it afterwards on that cluster.
| Storage | Best for | Rough per-node capacity guidance |
| SSD | Latency-sensitive reads and writes, most workloads | Up to about 5 TB per node |
| HDD | Large, mostly sequential scans where latency is less critical | Up to about 16 TB per node |
| Infrequent access | Large volumes of rarely read data at lower storage cost | Far lower read throughput per node; check current docs |
SSD is the default recommendation. HDD saves money per gigabyte, but random reads are slow, and Google's guidance is that it only makes sense above 10 TB with mostly scans and little latency sensitivity. Because it cannot be changed in place, a wrong pick means creating a new cluster and moving the data.
Take quiz
SSD
All three behave identically for random reads
Infrequent access
HDD
Yes, with a single gcloud command and no downtime
No, storage type is fixed at cluster creation
Only after deleting every table
Yes, but only on weekends
10. What are common use cases for Bigtable?
Bigtable suits workloads with huge volume, high write rates and lookups by key.
- Time series and IoT - sensor readings, metrics and logs, with keys like device ID plus time.
- Ad tech and marketing - impression and click events, user segments and real-time bidding profiles.
- Fintech - transaction history, fraud signals and ledgers read by account.
- Personalization and recommendations - per-user feature rows served in milliseconds.
- ML feature stores - online serving of precomputed features.
- Graph and social data - adjacency lists stored one row per entity.
What these share is a predictable access path through the row key. If your workload needs ad-hoc joins or multi-row transactions, look at BigQuery or Spanner instead.
Take quiz
A 200 MB product catalog with complex joins
Ad-hoc SQL exploration across many unrelated tables
Billions of device readings written continuously and read by device and time range
Monthly accounting that needs multi-table ACID transactions
A need for foreign key constraints
Heavy use of secondary indexes
Small datasets under 1 GB
A predictable access path through the row key
11. What are the size limits for rows, cells and row keys in Bigtable?
Bigtable enforces some hard limits and gives softer recommendations that you should treat as the real targets.
| Item | Hard limit | Recommended |
| Row key | 4 KB | Keep as short as practical |
| Column qualifier | 16 KB | Short names |
| Cell value | 100 MB | 10 MB or less |
| Row (all cells) | 256 MB | 100 MB or less |
| Column families per table | No fixed small cap | About 100 or fewer |
Staying well under the hard limits matters because very large rows cause slow reads, memory pressure and compaction trouble. If a row keeps growing, for example appending every event to one user's row, switch to a taller, narrower design with one row per event.
Take quiz
100 MB
16 KB
4 KB
1 GB
Raise the cell limit in the console
Store each event in its own row using a longer key
Add more column families
Move the row key to the qualifier
12. What is garbage collection in Bigtable?
Garbage collection (GC) is how Bigtable deletes old cells automatically, based on a policy you set on each column family. It is not related to JVM memory management.
Two rules are available, and you can combine them:
- Max age - delete cells older than a duration, such as 30 days.
- Max versions - keep only the newest N versions of each column.
- Union (either rule matches) or intersection (both must match).
cbt setgcpolicy metrics readings maxage=30d or maxversions=2
GC runs in the background during compaction, so expired data may still be returned for a while, sometimes up to a week. If a query must never see expired cells, filter by timestamp in the read as well.
Take quiz
Only when 30 days pass
Only when it breaks both rules
When it breaks either rule
Never; the policy is advisory
GC policies apply to tables only after a backup
Expired cells are moved to a hidden family
Bigtable only deletes data on instance restart
GC runs lazily during compaction rather than instantly
13. What is the cbt command-line tool?
cbt is a command-line tool, written in Go, for basic Bigtable administration and data operations. It is handy for quick checks, scripts and demos, though production traffic goes through client libraries.
It reads the project and instance from a ~/.cbtrc file, so you do not repeat them on each call.
echo project = my-project > ~/.cbtrc echo instance = my-instance >> ~/.cbtrc cbt createtable orders cbt createfamily orders cf cbt set orders order#1001 cf:status=PENDING cbt read orders prefix=order# count=5 cbt count orders
Typical commands include createtable, createfamily, set, read, lookup, ls, deleterow and setgcpolicy. Remember that cbt count scans every row, so avoid it on very large tables.
Take quiz
The ~/.cbtrc file
The Cloud Console URL
A table named _config
The BIGTABLE_HOME registry key only
It only works on HDD clusters
It has to scan every row
It deletes expired cells first
It locks the table for writes
14. Which client libraries can you use to access Bigtable?
Bigtable's data API is based on gRPC, and Google ships Cloud client libraries for the common languages: Java, Go, Python, C++, C#, Node.js, PHP and Ruby.
There are also integrations rather than raw libraries:
- Bigtable HBase client for Java - lets existing HBase code talk to Bigtable.
- Apache Beam / Dataflow connector - for batch and streaming pipelines.
- Spark and Hadoop connectors - used from Dataproc.
- cbt and gcloud bigtable - command-line administration.
Whichever library you use, create the client once and reuse it. Each client keeps a pool of gRPC channels, and opening a new client per request is a common reason for high latency.
Take quiz
JDBC
SOAP over HTTP
gRPC
GraphQL
Close it after each write to free channels
Open a new client for every read
Create one per row key
Create it once and reuse it across requests
15. What is HBase API compatibility in Bigtable?
Bigtable's data model is close to Apache HBase's, so Google provides a Bigtable HBase client library that implements the HBase Java API on top of Bigtable. Existing HBase applications can usually switch with a dependency and configuration change rather than a rewrite.
Connection conn = BigtableConfiguration.connect("my-project", "my-instance"); Table table = conn.getTable(TableName.valueOf("orders")); table.put(new Put(Bytes.toBytes("order#1001")) .addColumn(Bytes.toBytes("cf"), Bytes.toBytes("status"), Bytes.toBytes("PENDING")));
Compatibility is not total. Server-side extras such as coprocessors are not supported, some filters behave differently, and HBase snapshots are replaced by Bigtable backups. Check the compatibility notes before assuming a drop-in migration.
Take quiz
Coprocessors
Scans with row ranges
Column families
Put and Get operations
The entire data model must become relational
The dependency and connection configuration
All code must move to Python
Every table must be renamed
16. What is replication in Bigtable?
Replication keeps copies of your data in several clusters of the same instance, in different zones or regions. You turn it on simply by adding another cluster; Bigtable then copies writes between clusters automatically and asynchronously.
It buys you three things:
- Availability - if one cluster becomes unreachable, traffic can fail over to another.
- Workload isolation - run batch analytics on one cluster while another serves live traffic.
- Proximity - place clusters near users to reduce latency.
An instance can have up to 8 clusters, each in a different zone. Because copying is asynchronous, a read from a different cluster may briefly show older data. That is the price of the extra availability.
Take quiz
Export a backup every hour
Flip a replication flag on each table
Add another cluster to the instance
Create a read replica table per column family
With synchronous two-phase commit
By Pub/Sub messages you configure yourself
Only when you run a manual sync job
Asynchronously in the background
17. What is an app profile in Bigtable?
An app profile is an instance-level setting that tells Bigtable how to handle requests coming from a particular application. Each client connects using an app profile ID, and a default one exists if you do not pick.
The main settings are:
- Routing policy - single-cluster routing sends everything to one chosen cluster, while multi-cluster routing sends each request to the nearest available cluster.
- Single-row transactions - allowed only with single-cluster routing.
- Request priority - low, medium or high, so a batch job does not starve user-facing traffic.
A tidy pattern is one profile per workload: checkout-api with multi-cluster routing for live traffic, and nightly-etl pinned to a secondary cluster at low priority.
Take quiz
Single-row transactions such as check-and-mutate
Storing more than 100 column families
Key Visualizer scans
Garbage collection
To get its own copy of every table
To pin it to one cluster at low priority away from live traffic
To raise the cell size limit
To bypass IAM permissions
18. What is autoscaling in Bigtable?
Autoscaling lets Bigtable add or remove nodes in a cluster on its own, so you do not provision for the peak all day. You configure it per cluster.
You set three things: a minimum and maximum node count, a CPU utilization target, and a storage utilization target. Bigtable adds nodes when CPU or storage exceeds the target and removes them when load drops, never going outside the min and max you set.
Scale-up reacts faster than scale-down, which is deliberate because a cluster that shrinks too eagerly can hurt latency. Set the minimum high enough to hold your stored data and cover expected baseline traffic, and the maximum as a cost guard rail.
Take quiz
A cron schedule of node counts only
Read replica count per table
Min and max nodes plus CPU and storage utilization targets
Target row count and a maintenance window
To keep tablets from splitting
To enforce row-level security
To stop replication
To cap cost if load spikes unexpectedly
19. What is the Key Visualizer in Bigtable?
Key Visualizer is a diagnostic tool that draws a heatmap of how your table is being used. The horizontal axis is time and the vertical axis is the row key space, with colour showing activity such as read or write rate, latency or row size.
Its main job is to reveal hotspots. A bright horizontal band means a narrow key range is taking a disproportionate share of traffic, and a diagonal pattern often means sequential keys marching across the table. It also helps spot oversized rows and verify that a new key design actually spreads load.
It only produces scans for tables that are large and busy enough, so a tiny test table may show nothing. Check the current documentation for the exact thresholds.
Take quiz
Time and the row key range
Node ID and CPU percent
Cluster zone and storage type
Column family and timestamp
A table with no data
A hotspot on a small range of row keys
Replication lag between clusters
A healthy, evenly spread workload
20. What are Bigtable backups?
A Bigtable backup is a managed, point-in-time copy of a table's schema and data. You can create one on demand or on a schedule, and it is stored alongside a cluster separately from the live table.
Key points to remember:
- A backup has an expiration time; the maximum retention is up to 90 days.
- Restoring always creates a new table, so you can compare or swap it in. It does not overwrite the original.
- You can copy a backup to another cluster, region or project for extra protection.
- Backups protect against logical mistakes like a bad delete, which replication does not, since replication copies the mistake too.
You are billed for backup storage, so set sensible expiry times.
Take quiz
A read-only cluster
An overwritten original table
A new table
A new instance
Backups are faster than replication for reads
Replication never copies deletes
Replication only works for HDD clusters
Replication also copies accidental deletes and bad writes
21. What is Bigtable Data Boost?
Data Boost is a serverless compute option for reading Bigtable data without using your cluster's nodes. It is aimed at big analytical or batch reads that would otherwise compete with live traffic.
You access it through a dedicated Data Boost app profile. Jobs from Dataflow, Spark or BigQuery read the stored data directly, so your production cluster's CPU is not affected. Billing is by serverless processing units used rather than by nodes.
Limits to keep in mind: it is read-only, and it targets throughput-oriented scans, not low-latency point lookups.
Take quiz
Batch and analytics reads competing with production traffic on cluster nodes
Using replication
The need to design row keys
Paying for storage
Single-row transactions
Read-only access
Schema changes
Both reads and writes
22. What are change streams in Bigtable?
A change stream records every data change on a table - inserts, updates and deletes - so other systems can react to them. You enable it per table and choose a retention period between 1 and 7 days.
Records are grouped by row key ranges, and each carries the mutation along with its commit time. The standard way to consume them is the Dataflow connector (BigtableIO.readChangeStream) or the Java client.
Typical uses are replicating changes to BigQuery for analytics, publishing to Pub/Sub to trigger downstream services, and building audit trails. Keep in mind that change streams add some storage and processing cost, and that a pipeline that falls behind longer than the retention window loses the ability to catch up.
Take quiz
Exactly 24 hours, fixed
Up to 90 days
Between 1 and 7 days
Indefinitely until deleted
Changing the table's storage type
Resizing the cluster
Creating secondary indexes
Pushing row updates to BigQuery or Pub/Sub
23. What is GoogleSQL for Bigtable?
GoogleSQL for Bigtable lets you query Bigtable tables with SQL, so teams do not have to write low-level read calls for everything. The row key is exposed as _key, and column families appear as maps you index by qualifier.
SELECT _key, cf['status'] AS status FROM orders WHERE _key >= b'order#2026-10' AND _key < b'order#2026-11' LIMIT 50;
It is a good fit for exploration, dashboards and simple aggregation. But SQL does not change how Bigtable stores data: a query that cannot narrow by row key still scans a lot of rows, and the cost shows up as CPU on your nodes. Write queries with row key ranges first.
Take quiz
As the _key column (a BYTES value)
As ROWID
As PRIMARY
As _id
Adding ORDER BY on a qualifier
Constraining the row key to a prefix or range
Running it on an HDD cluster
Selecting more columns
24. What are aggregate cells in Bigtable?
Aggregate cells let Bigtable combine writes on the server, so you can keep counters and similar totals without reading the value first. You create a column family with an aggregate type, then send add-to-cell mutations.
Supported aggregates include sum, min, max and approximate distinct counts using HyperLogLog. Each write is merged into the existing value instead of replacing it.
This beats the old read-modify-write approach for counters in two ways: it needs no round trip, and it works safely with replication and multi-cluster routing, where read-modify-write is not allowed. Typical uses are page view counters, running totals and unique visitor estimates.
Take quiz
A client-side read then overwrite
A CheckAndMutate on every update
An add-to-cell mutation merged on the server
A full row delete and reinsert
They disable garbage collection
They store values in plain text
They need no column family
They avoid a round trip and work with multi-cluster routing
25. How does Bigtable store data internally?
Bigtable separates compute from storage. Nodes serve requests, but the data itself lives in Colossus, Google's distributed file system, as immutable SSTable files. A table is cut into tablets, and each tablet is assigned to one node at a time.
When a write arrives, the node appends it to a commit log and places it in an in-memory memtable. When the memtable fills, it is flushed as a new SSTable. Over time compaction merges SSTables, drops deleted and expired cells, and keeps reads from checking too many files.
flowchart LR C[Client] --> N["Node serving the tablet"] N --> L["Commit log in Colossus"] N --> M["Memtable in memory"] M -- flush --> S["SSTable files in Colossus"] S -- compaction --> S2["Merged SSTable"]
This design explains two behaviours. Rebalancing is fast because moving a tablet only changes who serves it. And node failure does not lose data, since everything durable is already in Colossus.
Take quiz
As SSTable files in Colossus
On SSDs attached to the serving node only
In a Cloud SQL metadata table
In the memtable until a backup runs
Create secondary indexes
Merge SSTables and remove deleted or expired cells
Copy data between clusters
Split the row key into shards
26. Explain the write path of a Bigtable request?
A write starts at the client, which routes it according to its app profile to a cluster, then to the node that currently serves the tablet holding that row key.
sequenceDiagram participant App as Client participant Node as Tablet node participant Log as Commit log (Colossus) participant Mem as Memtable participant Rep as Other clusters App->>Node: MutateRow(row key, cells) Node->>Log: Append mutation Node->>Mem: Apply to memtable Node-->>App: Success Node--)Rep: Asynchronous replication
- The node appends the mutation to the commit log, which makes it durable.
- It applies the change to the in-memory memtable.
- It acknowledges the client. All cells of one row change atomically.
- Later, the memtable is flushed to an SSTable, and replication ships the change to other clusters in the background.
The acknowledgement does not wait for replication, which is why other clusters can lag slightly.
Take quiz
After the next compaction finishes
After every replica cluster confirms it
After the mutation is durable in the log and applied in memory
Only after the memtable is flushed to an SSTable
Writes are queued until midnight
The commit log is skipped on replicated instances
Memtables are never shared
Replication happens asynchronously after the acknowledgement
27. Explain the read path in Bigtable?
A read goes to the node serving the tablet that contains the requested row key or range. The node must produce a merged view because the newest data may sit in the memtable while older versions are spread across several SSTables.
- Locate the tablet and node from the row key.
- Check caches first: Bigtable keeps frequently read data in memory, including a cache of rows and blocks.
- Read the memtable and the relevant SSTable blocks from Colossus on a cache miss.
- Merge the results by timestamp, apply filters such as column and version limits, and drop cells already marked deleted.
- Stream the rows back to the client in key order.
Scans are efficient because rows are sorted and contiguous. Point reads on hot rows are typically served from cache, which is why read latency is so low once data is warm. Reads that bypass filters and pull wide rows cost much more.
Take quiz
Recent writes sit in the memtable while older ones are in SSTables
Rows are split across zones randomly
Each column family is a separate database
Bigtable stores every cell three times in different formats
Large one-off exports
Repeated point reads of the same rows
Full table scans on first run
Schema administration calls
28. Why is row key design so important in Bigtable?
The row key is the only index, so it decides which queries are fast, how data is grouped on disk, and how evenly load spreads across nodes. A schema that is perfect in every other way still fails with a poor key.
Three things follow from that:
- Query speed - prefix and range scans only work on the leading part of the key.
- Locality - rows with adjacent keys land in the same tablet, so related data read together should share a prefix.
- Distribution - sequential prefixes such as timestamps push all new writes onto the last tablet.
| Key pattern | Result |
2026-10-22T10:15:01#sensor9 |
Hotspot: every write hits the newest range |
sensor9#2026-10-22T10:15:01 |
Writes spread across sensors; time range scans per sensor |
sensor9#9223372036854775807-ts |
Newest-first reads per sensor |
Since you cannot rename keys in place, test the design with realistic data and Key Visualizer before launch.
Take quiz
It disables compaction
Timestamps cannot be stored in keys
All new writes concentrate on the most recent key range
It forces HDD storage
sensor name stored only in a column
timestamp#sensor
random UUID
sensor#timestamp
29. What is hotspotting in Bigtable and how do you avoid it?
Hotspotting happens when a small part of the key space takes most of the traffic, so one node's CPU is saturated while the others sit idle. Adding nodes does not help, because the busy tablet is still served by only one node.
Common causes are timestamp or auto-increment prefixes, reversed domain names that cluster popular sites, and a single very popular row.
Ways to avoid it:
- Field promotion - move a well-distributed field, such as device ID, to the front of the key.
- Salting - prefix the key with a hash bucket. It spreads writes but turns one range scan into several, one per bucket.
- Hashing the leading field, when you only do point lookups.
- Splitting a hot row into several rows, for example one counter row per shard.
bucket = hash(device_id) % 20 row_key = f"{bucket:02d}#{device_id}#{event_ts}"
Use Key Visualizer and the hot tablets view to confirm the fix worked.
Take quiz
That tablet is still served by only one node
New nodes are always slower
Nodes cannot be added to busy clusters
Hotspots only occur on HDD
Writes become synchronous
A range scan must query every salt bucket
Keys become longer than 4 KB
Column families stop working
30. How do you design a row key for time-series data?
Start with the entity you query by, then add time. A typical key is metric#device_id#timestamp. Because the entity comes first, writes from many devices spread across the table, and one device's readings stay together for a fast time-range scan.
Two further choices matter:
- Tall and narrow vs short and wide - Bigtable generally prefers one row per measurement (or per small time bucket) to one ever-growing row per device.
- Newest first - use a reverse timestamp (
Long.MAX_VALUE - ts) when the common query is 'latest N readings'.
| Design | Good for | Watch out for |
| Row per reading | Simple writes, flexible scans | More rows and key overhead |
| Row per device per hour | Fewer rows, compact reads | Needs qualifiers for time within the hour |
| One row per device forever | Nothing in particular | Rows exceed size limits |
Always put a bounded retention policy in place with garbage collection, or the table keeps growing.
Take quiz
timestamp#device
device stored in a qualifier only
device#reverse_timestamp
A hash of the reading value
Timestamps cannot be repeated
It disables replication
Bigtable allows only one row per device
The row would grow past recommended and hard size limits
31. What is the difference between Bigtable and BigQuery?
They solve different problems. Bigtable is an operational database for high-throughput, low-latency reads and writes by key. BigQuery is an analytical data warehouse for large SQL scans and aggregation across whole datasets.
| Aspect | Bigtable | BigQuery |
| Workload | Serving, ingestion, point and range reads | Analytics, reporting, ML on large tables |
| Latency | Single-digit milliseconds | Seconds, per query |
| Access | Row key, plus SQL for simple queries | Full SQL with joins |
| Writes | Millions of small writes per second | Batch loads and streaming inserts |
| Billing | Nodes plus storage | Storage plus bytes scanned or slots |
They are often used together. Data lands in Bigtable for serving, then BigQuery queries it through an external table (ideally with Data Boost), and BigQuery can also export results back into Bigtable for fast serving.
Take quiz
Bigtable
BigQuery
Cloud Storage archive class
Looker Studio
Per replicated cluster only
By storage and data processed or slots, not by provisioned nodes
Per row key written
A flat monthly fee regardless of use
32. When would you choose Bigtable over Cloud Spanner?
Pick Bigtable when your access path is mostly by key, volume or write throughput is very high, and single-row atomicity is enough. Pick Spanner when you need relational features: joins, secondary indexes, foreign keys and ACID transactions across rows or even regions.
| Need | Better fit |
| Billions of time-series or event rows with key lookups | Bigtable |
| Multi-row ACID transactions, e.g. money transfer between accounts | Spanner |
| Ad-hoc SQL with joins on normalized data | Spanner |
| Cheapest scalable throughput for simple access patterns | Bigtable |
| Global strong consistency across regions | Spanner |
A useful rule of thumb: if you find yourself wanting transactions and secondary indexes, you are probably describing Spanner. If you can express every read as a row key range, Bigtable is usually cheaper at scale.
Take quiz
BigQuery streaming inserts
Bigtable, using two separate MutateRows calls
Spanner, for multi-row ACID transactions
HDD-backed Bigtable with replication
Normalized order data joined across six tables
A cross-region ledger needing strong consistency
Small reference data with foreign keys
A telemetry stream read by device ID and time range
33. Which is better, Bigtable or Firestore, and why?
Neither is better in general; they target different applications. Firestore is a document database aimed at app developers, with mobile and web SDKs, realtime listeners, offline sync and automatic indexes. Bigtable is built for massive throughput and large data volumes behind backend services.
| Factor | Firestore | Bigtable |
| Data model | Documents and collections | Wide-column rows |
| Client access | Mobile and web SDKs, security rules | Server-side clients only |
| Queries | Automatically indexed fields | Row key ranges, SQL on keys |
| Scale sweet spot | App data, moderate throughput | Very high ingest, terabytes to petabytes |
| Minimum cost | Pay per operation | Provisioned nodes |
Choose Firestore for a mobile app's user data with realtime sync. Choose Bigtable for an event pipeline writing hundreds of thousands of rows per second.
Take quiz
Mobile and web SDKs with realtime listeners
Row key range scans
Higher raw ingest throughput
HBase API compatibility
A chat app needing realtime updates on phones
An ingestion pipeline writing hundreds of thousands of rows per second
A to-do list with offline editing
A small blog's comments section
34. What is the difference between single-cluster and multi-cluster routing?
Both are app profile routing policies in a replicated instance. Single-cluster routing sends every request from that profile to one named cluster. Multi-cluster routing sends each request to the nearest available cluster and fails over automatically.
| Single-cluster routing | Multi-cluster routing | |
| Consistency | Read-your-writes, strong within the cluster | Eventual between clusters |
| Failover | Manual: you switch the profile | Automatic |
| Single-row transactions | Supported | Not supported |
| Best for | Workloads needing read-after-write and conditional updates | High availability, latency-sensitive reads |
The practical trade-off is consistency against availability. Many teams run live traffic on multi-cluster routing and keep batch jobs on a single-cluster profile pinned to another cluster.
Take quiz
Plain reads
Plain writes
Single-row transactions like check-and-mutate
Scans with filters
The table is deleted from that cluster
All requests fail until an operator changes the profile
Writes are queued for 24 hours
Requests automatically go to another cluster
35. What consistency guarantees does Bigtable provide?
Consistency depends on whether you use replication and how you route requests.
- Single cluster - reads and writes are strongly consistent. After a write is acknowledged, a read of that row from the same cluster sees it.
- Replicated, single-cluster routing - each profile still reads its own cluster, giving read-your-writes there. Other clusters catch up later.
- Replicated, multi-cluster routing - eventual consistency: a read may be served by a cluster that has not yet received the latest write.
When two clusters accept conflicting writes to the same cell, the one with the later timestamp wins, with a deterministic tiebreak if timestamps are equal. This is effectively last-write-wins.
Atomicity is only guaranteed within a single row. That is why related fields that must change together belong in the same row.
Take quiz
The write with the later timestamp wins
The write is rejected with a conflict error
Both are kept and the client must merge them
The first write always wins
Mutations across two rows in one request
All mutations to a single row
Every write in a batch to one table
All writes within one tablet
36. What happens when a write spans multiple rows in Bigtable?
Bigtable only guarantees atomicity per row. A batch sent with MutateRows is just a way to send many row mutations in one request; each row's mutation is applied independently.
That means partial success is possible. Some rows can succeed while others fail, for example because of a timeout or a transient server error. The response contains a status for each entry, and your client must look at them instead of assuming all-or-nothing.
statuses = table.mutate_rows(rows) failed = [i for i, s in enumerate(statuses) if s.code != 0] # retry only the failed rows
To make retries safe, write idempotent mutations by setting explicit timestamps, since replaying a write with the same timestamp has no extra effect. And if two values must always change together, model them as cells in the same row.
Take quiz
Roll back the whole batch automatically
Assume every row succeeded if no exception was thrown
Inspect the status for each entry and retry the failures
Wait for a global commit message
They allow cells larger than 100 MB
They disable the commit log
They make multi-row writes atomic
A replay with the same timestamp does not create a duplicate version
37. What is the difference between CheckAndMutate and ReadModifyWrite?
Both are atomic single-row operations, and both need single-cluster routing. They answer different needs.
| CheckAndMutate | ReadModifyWrite | |
| Idea | Apply mutations only if a filter matches | Increment or append to the current value |
| Typical use | Update status only if still PENDING | Counters, appending a string |
| Returns | Whether the predicate matched | The new cell value |
# CheckAndMutate: ship only if the order is still pending row = table.conditional_row(b"order#1001", filter_=ValueRegexFilter(b"PENDING")) row.set_cell("cf", b"status", b"SHIPPED", state=True) row.commit() # ReadModifyWrite: atomic increment r = table.append_row(b"page#home") r.increment_cell_value("stats", b"views", 1) r.commit()
Use CheckAndMutate when the new value depends on a condition, such as optimistic locking or claiming a task so only one worker wins. Use ReadModifyWrite when the new value depends on the old one and you need it returned. Both run atomically on one row, so two clients racing on the same row are serialized rather than overwriting each other.
Neither works under multi-cluster routing. For high-volume counters, consider aggregate cells instead, since read-modify-write on one hot row can itself become a bottleneck.
Take quiz
CheckAndMutate
ReadModifyWrite
A plain MutateRows batch
DropRowRange
The previous replica's value
The new value of the modified cell
A snapshot of the entire table
Only a success flag
38. How does Bigtable rebalance load across nodes?
Bigtable watches the load and size of every tablet and adjusts automatically. A tablet that is too large or too busy is split, tiny neighbours are merged, and tablets are reassigned between nodes so each node carries a similar share.
Reassignment is quick because data is not copied. It lives in Colossus, so the new node just starts serving the tablet. That is also why a freshly added node needs a little time before it helps: tablets must be moved to it and its caches warm up.
Rebalancing has limits worth knowing:
- It cannot split a single hot row, because a row is the smallest unit.
- It needs traffic patterns to be reasonably stable; sudden shifts in the key range take minutes to absorb.
- It cannot fix poor key design, only spread what the keys allow.
Take quiz
Nodes mirror each other's disks
It sends rows through Pub/Sub
The data lives in Colossus and only the serving assignment changes
It pauses writes and rebuilds from a backup
Two adjacent tablets of equal load
A table whose rows are all small
A cluster with too few tablets
One single row receiving most of the traffic
39. How do you scale a Bigtable cluster?
Bigtable scales horizontally. Add nodes and throughput grows roughly linearly, remove them to cut cost. You can resize manually in the console, with gcloud, or turn on autoscaling and let CPU and storage targets drive it.
gcloud bigtable clusters update my-cluster --instance=my-instance --num-nodes=12
A few rules decide how many nodes you need:
- CPU - keep average utilization around 70% or lower on a single cluster, and lower for replicated clusters that must absorb a failover.
- Storage per node - stay inside the per-node limits, and leave headroom rather than running close to full.
- Replicated instances - each cluster is sized on its own.
After a resize, give Bigtable some time to rebalance tablets before judging performance, and load-test a new size before the big traffic event, not during it.
Take quiz
CPU and storage utilization targets within min and max nodes
Key Visualizer colours
Number of app profiles
Row count and column family count
Switch to HDD storage
Allow time for tablets to rebalance before measuring
Restart every client immediately
Delete and recreate the table
40. How can you optimize Bigtable read performance?
Most gains come from reading less data and reading it in a way that suits how Bigtable stores it.
- Use row key ranges or prefixes instead of full table scans.
- Filter on the server - restrict by column family, qualifier, timestamp range or number of versions so unneeded cells never leave the node.
- Limit the result with a row limit when you only need the first rows.
- Keep rows small - very wide rows slow every read that touches them.
- Reuse the client so connections are pooled, and keep the client close to the cluster.
- Use SSD for random reads, and keep node CPU below the recommended level.
rows = table.read_rows( row_set=RowSet(), # add a prefix or range here filter_=RowFilterChain(filters=[ FamilyNameRegexFilter("stats"), CellsColumnLimitFilter(1)]), limit=100)
For heavy repeated lookups, ask whether a continuous materialized view could precompute the answer.
Take quiz
Adding a second cluster
Disabling garbage collection
Applying a column family and version-limit filter
Converting keys to uppercase
It bypasses IAM checks
It caches whole tables locally
It makes writes synchronous
It keeps a warm pool of connections and avoids setup latency
41. How do you troubleshoot slow Bigtable performance?
Work from the cluster outward, checking the usual suspects in order:
- Cluster CPU and the hottest node. High max CPU with low average points to a hotspot, not a lack of nodes.
- Key Visualizer and the hot tablets view. Look for bright bands and sequential key patterns.
- Storage per node. A nearly full cluster slows down because background work has little room.
- Row and cell size. Oversized rows or large values make reads and compactions expensive.
- Workload mix. A batch job or large scan may be crowding out live traffic. Move it to a separate app profile with low priority, another cluster, or Data Boost.
- Client side. New clients per request, high network distance, or aggressive retries can look like server slowness.
- Recent changes - a new key format, a deployment, a schema change.
Cloud Monitoring graphs for latency, rows read and written, and error rates tell you whether the slowness began at a specific time, which narrows the cause quickly.
Take quiz
A hotspot in the key space
The cluster has too many nodes
The instance is using multi-cluster routing
Backups are failing
Disable replication
Run it under a separate low-priority app profile or Data Boost
Run it with the same profile at midnight
Increase the cell size limit
42. How do you migrate data from HBase to Bigtable?
There are two broad approaches, depending on how much downtime you can accept.
| Approach | How it works | Downtime |
| Offline | Snapshot the HBase tables, export to Cloud Storage, import into Bigtable with a Dataflow job | Writes stop during the move |
| Online | Keep HBase live and use HBase replication to stream changes into Bigtable while it catches up | Minimal cutover window |
flowchart LR A["Create HBase snapshot"] --> B["Export to Cloud Storage"] B --> C["Dataflow import to Bigtable"] C --> D["Validate row counts and hashes"] D --> E["Switch application to Bigtable HBase client"]
Before starting, create the Bigtable tables with matching column families and sensible GC policies, since HBase version settings map to GC rules. Then run a validation step comparing hashes of both sides, update the application to the Bigtable HBase client, and cut over once the data matches. Test coprocessors and custom filters early because they are not supported.
Take quiz
Manual re-entry through cbt
Exporting CSV from the HBase shell
Online migration using HBase replication into Bigtable
Offline snapshot export and import
To enable replication
To compact SSTables
To change the storage type
To confirm the data in Bigtable matches the source before cutover
43. How do you secure data in Bigtable?
Security is layered across identity, encryption and network controls.
- IAM - predefined roles such as Bigtable Admin, User, Reader and Viewer can be granted at the project, instance or table level. Follow least privilege and give applications service accounts rather than user accounts.
- Authorized views - for finer control, expose only certain rows and columns to a given identity.
- Encryption at rest - on by default with Google-managed keys. Choose CMEK with Cloud KMS if you must control the key; it is set per cluster.
- Encryption in transit - TLS for client connections.
- Network perimeter - VPC Service Controls and Private Google Access reduce exfiltration risk.
- Audit logging - Admin Activity logs are on, and Data Access logs can be enabled to record reads and writes.
- Deletion protection - guards instances and tables against accidental removal.
Plain IAM does not filter rows. If tenants share a table, use authorized views.
Take quiz
Grant access through an authorized view limited to their data
Enable HDD storage
Create a column family per customer password
Give them Bigtable Reader on the instance
Per row key prefix
For each cluster
Per cell
Per app profile
44. What are authorized views in Bigtable?
An authorized view is a defined slice of a table that you share with an identity without giving it access to the whole table. You describe the slice in a definition: which row key prefixes, column families and qualifiers are included.
Unlike logical and continuous materialized views, authorized views control both reads and writes, and permissions are granted on the view itself. They store no extra data, so there is no extra storage cost.
The classic use is multi-tenant data: one table with a key like tenantA#..., and a separate authorized view per customer limited to its own prefix. The customer's service account can then read and write only inside that slice, even though the data physically lives in one shared table.
Take quiz
Only the order in which rows are returned
The size of the underlying SSTables
Which row key prefixes and column families an identity can access
The cluster used for replication
A full duplicate of the table
A backup per grantee
One extra column family per view
None, because it does not copy data
45. What are continuous materialized views in Bigtable?
A continuous materialized view is a read-only table that Bigtable builds by continuously running a SQL query against a source table and keeping the result in sync. The view has its own schema, usually pre-aggregated or reshaped for a different access pattern.
That solves a familiar problem: your source keys serve one query well, but a dashboard needs hourly totals by region. Instead of aggregating on each request, you let Bigtable maintain the totals and read them directly.
| Logical view | Continuous materialized view | |
| Data stored | No, query runs at read time | Yes, a separate maintained table |
| Read cost | Computed per query | Cheap, already computed |
| Extra cost | None for storage | Storage plus ongoing processing |
Check the current documentation for the feature's launch stage, since it has been released in phases.
Take quiz
It stores precomputed results that are kept in sync with the source
It cannot be queried with SQL
It can be written to by clients
It replaces the source table
Accepting direct writes from mobile apps
Hourly totals by region read repeatedly by a dashboard
Storing raw images
Backing up the table
46. How do you import and export data in Bigtable?
For bulk movement, Google provides Dataflow templates. They run as managed pipelines, so no cluster to build.
- Export - Bigtable to Cloud Storage as Avro, Parquet or SequenceFile.
- Import - Cloud Storage back into Bigtable from the same kinds of files.
- BigQuery to Bigtable - export query results into Bigtable for serving (reverse ETL).
- Backups - for restoring within Google Cloud, simpler than exporting files.
- cbt - only for small tests.
Run exports with care. A big export reads the whole table, so schedule it off-peak, give the job its own app profile at low priority, or use Data Boost to keep it off production nodes. Also, import tables in key order where possible or presplit them, so the load does not hit one tablet first.
Take quiz
App Engine cron
Cloud Functions
Dataflow
Cloud Composer only
Convert the table to HDD first
Run it from cbt count
Disable GC beforehand
Use Data Boost or a low-priority app profile
47. How can you query Bigtable data from BigQuery?
There are two main routes. The first is a BigQuery external table over Bigtable, which lets you run SQL joins and aggregates against live Bigtable data without copying it.
CREATE EXTERNAL TABLE mydataset.bt_orders OPTIONS ( format = 'CLOUD_BIGTABLE', uris = ['https://googleapis.com/bigtable/projects/my-proj/instances/my-instance/tables/orders'], bigtable_options = '''{"readRowkeyAsString": true, "columnFamilies": [{"familyId": "cf", "onlyReadLatest": true, "columns": [{"qualifierString": "status", "type": "STRING"}]}]}''' );
The mapping tells BigQuery which families and qualifiers to expose and how to decode them. The second route is reverse ETL: BigQuery exports query results into Bigtable so applications can read them in milliseconds.
Queries over an external table read from your cluster, so a heavy scan can compete with production traffic. Prefer Data Boost for analytical reads, or a separate cluster and app profile.
Take quiz
Copying the data into BigQuery storage first
Needing any column mapping
Reading from Bigtable at all
Using SQL
To avoid the BigQuery bill
To keep the scan off the production nodes
To change the row key
To enable single-row transactions
48. How is Bigtable priced?
Bigtable billing has a few independent parts, so the final bill depends on how you size and use the instance.
| Component | How it is charged |
| Nodes | Per node per hour, for every cluster. Autoscaling changes the number billed |
| Storage | Per GB per month, with different rates for SSD, HDD and infrequent access |
| Backups | Per GB per month of backup storage |
| Network | Egress, including traffic between regions for replication |
| Data Boost | By serverless processing units consumed |
| Committed use | Discounts for committing to a baseline of nodes |
Node cost is usually the biggest piece, and every replicated cluster adds its own nodes and storage, so replication roughly multiplies the footprint. To control cost: use autoscaling with a realistic minimum, expire old data with GC policies, keep backup retention short, and check the pricing page for current rates.
Take quiz
Replication is billed per row key
It disables committed use discounts
Each added cluster has its own nodes and storage
Replicated tables are charged double per query only
Larger cell values
A longer row key
More column families
Autoscaling with a sensible minimum and maximum
49. When should you not use Bigtable?
Bigtable is a poor choice when the workload needs features it does not offer, or when it is simply too small to justify it.
| Requirement | Better fit |
| Multi-row ACID transactions | Spanner or Cloud SQL |
| Joins and complex relational queries | Spanner, Cloud SQL or BigQuery |
| Ad-hoc analytics across the whole dataset | BigQuery |
| Several different lookup paths with secondary indexes | Firestore, Spanner or Cloud SQL |
| Small datasets, well under 1 TB, with light traffic | Cloud SQL, Firestore or Spanner |
Cost matters too. Bigtable is billed by provisioned nodes, so a tiny, rarely used dataset costs more than it would on a pay-per-use service. If you cannot describe your reads as row key lookups or ranges, that alone is a warning sign.
Take quiz
Atomic transactions spanning several rows
Millions of writes per second
Key-based lookups
Storing time-series sensor data
Row keys must exceed 4 KB
Provisioned node cost outweighs the benefit at that scale
Bigtable cannot store under 1 GB
Small tables disable replication
50. What happens when a Bigtable node fails?
Very little data risk, because nodes do not own the durable data. Tablets and the commit log live in Colossus, so a failure only affects who serves them.
flowchart TD A["Node becomes unavailable"] --> B["Bigtable detects the failure"] B --> C["Its tablets are reassigned to healthy nodes"] C --> D["New nodes replay the commit log into memtables"] D --> E["Clients retry and traffic resumes"]
During reassignment, requests to the affected key ranges can see a short spike in latency or transient errors. Client libraries retry such errors automatically, so well-written applications usually notice only a blip. Caches on the new node start cold, so latency can stay slightly higher for a short time.
A node failure is different from losing a zone. In a single-cluster instance a zonal outage makes the cluster unavailable until it recovers. With replication and multi-cluster routing, requests move to a cluster in another zone automatically.