Design, migrate, and run scalable, highly available databases on Google Cloud across relational and NoSQL services, and track your readiness for the Professional Cloud Database Engineer exam.
Prepare and test your skills
Prepare and test your skills
Assessing slow queries, locking, and missing indexes means tracing why reads are slow and whether contention or a missing index is the cause. Slow reads increase input/output (I/O), raise latency, and can overload a primary instance and its replicas. The work flows from latency measurement to query review to lock and storage checks, so each layer either explains the delay or points to the next layer.
A missing index is found by comparing the fields used for filtering and sorting in slow queries with the indexes defined on the schema. In Firestore, a query that needs a composite index returns an error with a link to create the required index. A Firestore composite index names a collectionGroup, a queryScope of COLLECTION, and an ordered list of fields with a fieldPath and an order of ASCENDING or DESCENDING.
The order of fields in the definition must match the query filter and sort, including nested paths such as price.currency. For sharded time-series queries, each pattern needs its own index that leads with the shard key and ends with the timestamp, such as shard plus exchange plus timestamp. New definitions are added to the indexes array in the index file and deployed with firebase deploy --only firestore:indexes, after which reads flow from the query to the pre-sorted index entries.
Isolating latency determines whether delay comes from the database instance, the client, or the network between them. For Memorystore for Valkey (opens in a new tab), the test runs from a Compute Engine virtual machine (VM) in the same region and virtual private cloud (VPC) network as the instance. The valkey-cli tool pings the server for a few minutes, and an average of 1 millisecond or less means the instance is healthy.
Run the isolation test in order:
valkey-tools with apt-get or yum depending on the operating system.redis-cli --latency against the endpoint address and port, adding transport layer security (TLS) options when needed.Ctrl+C and compare minimum, maximum, and average latency to the 1-millisecond baseline.If the instance test is fast but the application is still slow, the delay sits outside the instance in cross-region distance, high client central processing unit (CPU) or memory use, exhausted connection pools, or application logic. On the instance itself, replace operations that block the single Valkey main thread, use SCAN instead of KEYS to iterate the keyspace, use read replicas when slightly stale data is acceptable, set expiration times, and check audit logs for changed access patterns.
Exam tip: Use SCAN, not KEYS, to scan the keyspace because KEYS blocks the main thread while SCAN iterates without blocking.
Data contention in Firestore occurs when a transaction needs documents it read to stay consistent while another operation tries to update the same documents. Firestore resolves contention by delaying or failing one operation and automatically retrying transactions, then returning ABORTED: Too much contention on these documents after a finite number of retries. Firestore guarantees serializable isolation by commit time, so transactions behave as if they ran in series ordered by commit time even while they execute in parallel.
The two concurrency modes differ in how they protect reads:
| Mode | How it protects reads | Effect on other writers |
|---|---|---|
| PESSIMISTIC | Places locks on documents read and holds them until commit, timeout, or failure | Other transactions and writes must wait; locks are acquired in chronological order |
| OPTIMISTIC | Tracks documents read and commits only if none changed, retrying on change | Other operations are not blocked, but the transaction retries and then fails |
Server client libraries follow the database setting, with Standard edition defaulting to PESSIMISTIC and Enterprise edition defaulting to OPTIMISTIC. Mobile and web software development kits (SDKs) always emulate optimistic concurrency and do not use built-in transactions, even when the database is set to PESSIMISTIC. Within a transaction, reads must come before writes and reads see the version as of commit time, not the transaction's own prior writes. The mode can be viewed with gcloud firestore databases describe and changed with gcloud firestore databases update --concurrency-mode. When slow behavior remains after indexing and contention checks, confirm underlying disk and memory pressure with slow-log entries, high p99 disk timings, memory use near 80%, and rejected-connection counts.
Monitoring database vitals means tracking compute, memory, storage, and audit signals to keep instances healthy and explainable. Cloud SQL (opens in a new tab) telemetry flows from built-in agents and the Ops Agent into Cloud Monitoring, where Overview, CPU, Memory, Network, and Disk views support dashboards and alerts. Teams use the same signals to right-size instances, grow storage, and answer who changed what and when.
CPU Utilization is the percent of virtual CPU used by the instance, and Memory Utilization is the percent of memory used excluding disk caches and, on Linux, kernel memory. Sustained high values mean the workload is pressing against capacity, while consistently low values mean the instance is overprovisioned. Full memory and disk-space signals require the Ops Agent on the virtual machine (VM), because default metrics do not show complete behavior.
High CPU slows queries and should trigger root-cause analysis for poorly written queries, long-running transactions, and many concurrent connections. Query Insights shows which queries consume the most CPU with visual plans and tracing, while pg_stat_activity and per-process tools isolate long sessions and blocking states such as active, idle, and idle in transaction. For memory, a rising Number of Reads served from disk suggests the working set no longer fits in cache, even though managed instances also write to a system table about every second when idle.
| Recommender signal | Meaning | Sizing action |
|---|---|---|
| Overprovisioned instance | Instance is unnecessarily large for the workload | Resize to a smaller machine type to reduce cost |
| Underprovisioned instance | High CPU or memory use with bottleneck or out-of-memory risk | Increase machine size to relieve pressure |
| Idle instance | Instance is inadvertently idle | Shut down the instance rather than resizing it |
Exam tip: Memory Utilization excludes disk caches and, on Linux, kernel memory, so confirm pressure with disk-served reads and sustained high utilization.
Storage performance is judged from throughput, input/output operations per second (IOPS), I/O size, queue depth, and disk-space utilization. Disk Throughput is the average bytes read and written, Disk IOPS is the average operations rate, I/O Size Avg is the average operation size, and Queue Length Avg is queued plus running operations. A full disk can halt writes, so disk-space utilization must be watched continuously.
Small 4 to 16 KiB random operations are usually limited by IOPS, while large 256 KiB to 1 MiB sequential operations are usually limited by throughput. To reach disk limits, use high queue depth. For Cloud SQL instances, disk performance depends on disk size and virtual CPU count, while for Hyperdisk volumes it depends on provisioned IOPS, throughput, size, and the attached machine type. Choose solid-state drive (SSD) for most databases where consistent performance matters, and choose hard disk drive (HDD) only for very large 10 TB or larger, infrequently accessed, latency-tolerant datasets.
Capacity work combines automatic growth with cleanup:
Cloud Audit Logs record activity when projects, Cloud SQL instances, and service accounts are created, changed, or accessed. Admin Activity logs record configuration changes and are always written and cannot be disabled. Data Access logs record reads and writes of user data and must be explicitly enabled because of volume. System Event logs record Google-initiated actions such as maintenance, and Policy Denied logs record denials caused by security policy.
An investigation of administrative changes follows an ordered workflow:
SetIamPolicy and service-account creation.Cloud Logging retains logs for a default period, so longer history requires a log sink that exports copies to BigQuery or another destination for aggregate analysis. For Cloud SQL for PostgreSQL, flags for log checkpoints and log temp files extend visibility into I/O causes, while firewall, Virtual Private Cloud (VPC) flow, and Domain Name System (DNS) logging complete the network picture. Centralized dashboards combine these logs with RAM, CPU, storage, and I/O metrics and Query Insights for expensive-query analysis.
Monitoring and updating quotas keeps multi-technology database solutions running by matching limits to real demand. A quota sets the maximum amount of a resource a project, folder, or organization can use, such as virtual machines (VMs) or API calls per minute. When quota runs out, tasks fail, so teams monitor use, optimize efficiency, and justify increases with data.
Allocation, rate, and concurrent quotas restrict different kinds of consumption and recover in different ways. Allocation quotas limit how much of a resource is held at one time, such as 100 VMs, and capacity returns only when unused resources are deleted. Rate quotas limit how many operations occur in a time window, such as 1,000 API requests per day, and refill when the window resets. Concurrent quotas limit simultaneously running long operations, such as Compute Engine inserts that can run up to one hour.
| Quota type | What it limits | How to stay within it |
|---|---|---|
| Allocation quota | Quantity held at one time | Delete unused resources to free capacity |
| Rate quota | Requests per interval | Wait for reset; per-day resets at midnight Pacific Time and per-minute resets on a rolling window |
| Concurrent quota | Simultaneous long-running operations | Wait for operations to finish or reduce parallelism |
Scope adds a second dimension. Project-level quotas apply to one project, folder-level quotas are shared by child folders and projects, and organization-level quotas are shared across the organization. Location adds a third dimension: global quotas are shared across all regions and zones, regional quotas are shared within one region, and zonal quotas apply within one zone. When a resource has both regional and zonal quotas, use in one zone consumes both. A quota sets a maximum that can be created if capacity exists, but it does not guarantee capacity in that region or zone.
A quota adjustment request asks to raise a quota for a specific project, folder, or organization. Requests can be made through the Google Cloud console, through a support case, or with an account team or Technical Account Manager (TAM). The console path needs a role such as Project Owner or Editor, Quota Administrator, or a custom role with serviceusage.quotas.update, but no paid Customer Care plan is required.
To request in the console, follow the order:
Most console requests take 24 to 48 hours, while large increases can take 10 business days or more. Automated systems review most requests for availability and history, with some escalated to humans; denials can be pursued via support or the account team. Strong justification shows consumption proof such as quota exceeded errors, future growth and 24-hour patterns, region or zone spread, and related storage or networking needs. Before and after requesting, optimize with exponential backoff, client-side rate limiting, capacity reservations, and steady low-volume patterns instead of sharp bursts.
The quota adjuster (opens in a new tab) is a Google Cloud system that proactively requests increases when peak use nears the limit. When enabled, the adjuster checks consumption over a duration and typically raises the value by 10 to 20 percent if the increase is possible. The adjuster only increases values, never lowers them, does not act on manually capped quotas, covers only some services, and needs enough history for accurate prediction.
Cloud SQL Admin API rate quotas control Admin API calls from the console, gcloud CLI, service accounts, and connectors, not database queries. The quotas refill over 60-second intervals, and exceeding a limit returns HTTP 429 with rateLimitExceeded. Connect, Get, List, Mutate, and Default per region limits are per minute per user per region, while the Default limit is per minute per user globally. Daily Cloud SQL resource quotas replenish at midnight Pacific Time. Limits differ from quotas because limits are not replenished and are not shown on the Quotas page.
Exam tip: A quota sets a maximum that can be created if capacity exists, but it does not guarantee that the resource exists in that region or zone.
The Cloud Quotas dashboard in IAM and Admin shows current usage, limit, and percent consumed for project-level quotas, with display names and lowercase metric names for monitoring. Values refresh once per day, so changes can take up to 24 hours to appear. Cloud Monitoring extends the view with Consumer Quota metrics, Metrics Explorer charts, and alerting policies that notify email, SMS, or Pub/Sub.
| Approach | Where it is configured | Scope and trigger |
|---|---|---|
| Basic quota usage alerts | IAM and Admin Quotas page | Project-level quota only; fires at a percentage of maximum |
| Cloud Monitoring policies | Monitoring Alerting with Consumer Quota metrics | Supported services with custom thresholds, trends, or quota/exceeded errors |
Basic alerts support only project-level quotas. Services such as Compute Engine, Dataflow, Spanner, and Pub/Sub commonly support quota metrics, while App Engine and Cloud SQL commonly do not. Because samples can arrive daily, use stacked bar charts over at least one week for daily metrics, and set thresholds with lead time rather than expecting real-time signals.
Continue with this study guide: Monitor and update quotas
Investigating resource contention means finding where concurrent work competes for the same data, connections, CPU, memory, or disk. Contention appears as hotspots, blocking sessions, timeouts, and throughput that stops scaling even when total capacity looks large. Diagnosis flows from load signals to the hot split or blocked session, then to scaling or tuning.
A distributed hotspot is an unbalanced partition that receives a disproportionate share of reads or writes, so one server task is hot while others stay idle. Sharding splits a database by criteria such as customer or subject to scale reads and writes horizontally, but a poor key choice concentrates work on one shard. In Firestore (opens in a new tab), sequential timestamp indexes can concentrate index writes on one tablet, while a sharded key spreads entries across tablets.
Cloud Spanner distributes compute across zones in its instance configuration, with one server task per zone up to 1000 processing units (PUs) and one task per 1000 PUs above that. Storage follows compute: 1024.0 GiB per 100 PUs below 1 node and 10 TiB per node at 1 node and larger, billed only for storage used. Poor schema choices such as monotonically increasing keys or one heavily updated table concentrate work on a few splits. Detection starts with the Query insights dashboard for total and per-query CPU seconds per minute and the TopN table limited to 100 entries, then uses SPANNER_SYS.SPLIT_STATS_TOP_MINUTE ordered by CPU_USAGE_SCORE to rank the hottest splits.
Exam tip: Use the Query insights TopN table to find which query fingerprint is hot, then use SPANNER_SYS.SPLIT_STATS_TOP_MINUTE ordered by CPU_USAGE_SCORE to find which data split is hot.
Locking controls how concurrent transactions share rows and documents without corrupting data. A transaction holds locks until it finishes, so others that need the same records must wait, which appears as blocking sessions, higher latency, and timeouts. The Cloud Healthcare API FHIR server shows the pattern when parallel bundles update the same Patient resource: the first bundle locks the resource, others wait, and the server load-sheds with 429 Resource Exhausted operation_too_costly, throttling all create, read, update, and delete (CRUD) operations in the project.
The contention follows an ordered sequence:
429 throttling that affects the whole project, not just the hot resource.Throughput under lock contention flattens instead of rising with clients, which distinguishes blocking from CPU, memory, or storage shortage. Diagnosis searches Cloud Logging for operation_too_costly, reviews slow queries and plans for missing indexes and waits, and checks pg_stat_activity by state and user. Lock capacity follows max_locks_per_transaction times max_connections plus max_prepared_transactions, with a default of 64 locks per transaction. Fixes shorten lock hold time with small transaction bundles, separate independent resources, use moderate batching, add supporting indexes, remove unneeded indexes and foreign keys, and perform vacuum, statistics, and reindex maintenance.
System bottlenecks share slow responsiveness but differ in metric signature. Google Cloud Monitoring exposes resource metrics while Query Insights shows database load as CPU and CPU Wait, IO Wait, and Lock Wait against CPU capacity. CPU and CPU Wait includes time using the CPU plus time waiting for the Linux scheduler, so load above the capacity line means queries are queued for CPU.
| Bottleneck | Key signal | First response |
|---|---|---|
| CPU constraint | CPU and CPU Wait exceeds capacity; CPU seconds per minute stays elevated | Scale up virtual CPU and tune top CPU queries |
| I/O constraint | IO Wait dominates; workload hits IOPS or throughput limit | Increase disk to 4 TB or greater, increase virtual CPU, parallelize I/O, enable automatic storage increase |
| Memory constraint | Process usage near 90% or cache plus free below 10% | Tune work_mem and shared_buffers, reduce sessions, then scale memory or shard |
Memory risk in Cloud SQL for PostgreSQL uses database/memory/components.usage with a 90% alert threshold; cache plus free below 10% combined signals high out-of-memory risk. A common pattern is high work_mem with many active connections. Connection exhaustion itself can exhaust CPU and memory, hide metrics, and cause timeouts, so bounded pooling matters. Pinpointing follows an order: confirm elevated load, establish duration over a week, identify the dominant wait category, filter by database or user or tag, then open Top queries where normalized digests group similar statements. Immediate relief often comes from scaling up disk throughput, virtual CPU, and RAM, while long-term fixes add read replicas, partitioning, archiving, or sharding.
Continue with this study guide: Investigate database resource contention
Setting up alerts connects database signals to people and tools so issues trigger timely response. Log-based alerts catch error patterns in logs, metric-based policies catch numeric exhaustion, and notification channels and incident workflows carry the alert to ownership and closure. Data flows from Cloud SQL (opens in a new tab) instances and Cloud Logging into Cloud Monitoring incidents and notifications.
Log-based alerting watches the log stream for a matching filter and opens an alert when a database error, failed execution, or system failure appears. Log data flows from Cloud Logging to a Cloud Monitoring alerting policy, which forwards notifications to channels such as email, SMS, or PagerDuty. Multiple channels should be configured so one channel failure does not block a critical notice.
The policy evaluates only included logs at the Google Cloud project level and cannot filter by log buckets or other resources such as billing accounts or organizations. Filters must use correct Logging query-language field names and regular expressions. Validate the query in Logs Explorer or with Preview logs before saving, tighten the query if it creates noise, and check the Alerts page by policy name if it creates nothing. A policy is limited to 2 new alerts per minute and 20 alerts and 20 notifications per day, with the daily limit resetting at a random time. SQL-based alerting with Observability Analytics instead queries a linked BigQuery dataset from an upgraded log bucket, without a WHERE timestamp filter, using the Monitoring Service Account with Monitoring Editor, Logging SqlAlertWriter, Monitoring Service Agent, and BigQuery Data Viewer roles.
Exam tip: Do not extract the timestamp label in a log-based alerting policy, because extracting that label prevents alert creation and notification.
Metric-based policies watch numeric Cloud SQL signals and open an incident when a signal crosses a threshold for a duration. Core signals cover CPU utilization, memory usage and total_usage, disk utilization and available space, and disk throughput and IOPS. The usage metric shows database-process memory while total_usage adds operating-system cache, so comparing them shows reclaimable cache.
| Metric | Threshold or warning signal | What the signal means |
|---|---|---|
| Disk available space | Keep at least 20% free | Less space leaves no room for maintenance and risks storage-full outage |
Memory usage | Remains under 90% | Higher values predict out-of-memory errors |
| CPU and RAM utilization | Sustained use near 100% | Machine size is too small and can bring down high availability |
A condition combines metric, threshold comparison, and duration so brief spikes do not page on-call staff while sustained breaches signal overload or tuning needs such as missing indexes or stale statistics. The policy also defines auto-close behavior when metric data stops. Finalizing adds Documentation with runbook steps, a unique Alert name naming database, metric, and threshold, and Create Policy to start evaluation. Changing memory size requires a restart, and an instance at maximum memory must be sharded.
Notification and incident management connects detection to triage, investigation, and resolution. Procedures assign incident commanders, investigators, communicators, and experts, define communication and escalation paths, and document steps, tools, and contacts in a runbook that is regularly reviewed. A centralized system consolidates incident data for visibility, coordination, and clear ownership.
Investigation starts on the Incident details page, where the Logs pane shows matching entries, Labels identify the monitored resource, Documentation shows mitigation tips, and Related incidents reveal shared causes. Do not modify the alerting policy while working with support because precomputed incident data is discarded. Incidents move in order:
Snoozing stops new incidents and notifications during the period but leaves open incidents open until auto-close, which defaults to 7 days with a 30-minute minimum.
Continue with this study guide: Set up alerts for errors and performance metrics
firebase deploy --only firestore:indexes.SCAN must be used instead of KEYS to avoid blocking the main thread.Last updated