28 min readAI-assisted

Chapter Self-Check

.mdPDF

Part 1 Questions: SLIs, SLOs, Error Budgets & Service Lifecycle#

Conceptual#

What's the difference between basicSli, requestBased, and windowsBased SLIs in Cloud Monitoring's Service Monitoring?

basicSli is a small set of pre-built indicators (availability, latency) Cloud Monitoring computes automatically for GKE/App Engine/Cloud Run services with almost no configuration. requestBased is a custom SLI expressed as a ratio of good to total requests (goodTotalRatio) or a latency-threshold cut (distributionCut) against your own metrics. windowsBased instead evaluates whether each fixed time window met a goodness criterion, useful for services where "percentage of good requests" isn't the natural unit, like a batch pipeline.

What does the select_slo_burn_rate filter function do, and what two arguments does it take?

It's a Cloud Monitoring filter that returns an SLO's error-budget burn rate as a time series any alerting policy condition can evaluate. It takes the target SLO's full resource name and a lookback period (e.g., "3600s") — the burn rate is computed over that lookback window.

Why does a real multi-window burn-rate alert need two select_slo_burn_rate conditions instead of one?

A single short lookback window alone fires on transient, self-resolving blips (like a brief Cloud Run cold-start 503); a single long lookback window alone reacts too slowly to a genuinely fast-burning incident. Pairing a short and long window, AND-combined, requires both to agree before paging — responsive to real incidents, resilient to noise.

What's the actual difference between a Cloud Service Mesh SLO and a Cloud Monitoring Service Monitoring SLO?

A Cloud Service Mesh SLO is derived automatically from the Envoy sidecar's own request telemetry — no application code changes needed, but it only sees network-facing behavior (HTTP status, latency), not application correctness. A Service Monitoring SLO is built from metrics you define yourself, and can capture failure modes a sidecar can't see, like a request that returns a 200 with a logically wrong result.

Why can a service's own customer-facing SLA never honestly exceed the weakest published SLA of the GCP building blocks in its critical path?

Meridian has no ability to make Google Cloud's own infrastructure more available than Google itself contracts to deliver — composite availability across a request path is the product of each stage's uptime, not the maximum of them, so a service built on components rated at 99.95% can't honestly promise higher than that (and in practice slightly less, once composed across multiple stages).

Applied / Scenario#

shipment-api's error budget just entered the "frozen" tier after a real incident. A developer wants to ship an unrelated, already-finished feature flag change. Should the release gate allow it?

No. The frozen tier exists to stop new risk while the team recovers from a reliability breach — an unrelated change, however finished, is exactly the kind of new risk the tier is meant to block. The override mechanism exists for the incident fix itself, not for other ready work, or the frozen tier's actual purpose quietly erodes.

A team's first burn-rate alert used only a 5-minute lookback window and started firing on routine, self-resolving Cloud Run cold-start blips. What's the fix, and why did the single-window version fail?

Add a second, longer-lookback condition (e.g., 1 hour) AND-combined with the short one, so both must exceed the threshold before paging. The single-window version failed because a brief blip alone was enough to trip it — there was no requirement that the burn also be sustained over a longer period, which is exactly what separates a real incident from noise.

route-optimizer has a healthy Cloud Service Mesh SLO (99.98% compliance) but customers report it's returning geographically nonsensical routes. Why doesn't the existing SLO catch this?

The mesh-derived SLO is computed from sidecar telemetry — it sees the request succeed with a 200 response regardless of whether the returned route is actually correct. A wrong-but-successfully-returned response is invisible to that SLI by construction; catching it requires a second, application-level SLI that specifically validates response correctness.

A stakeholder asks to raise a service's SLO target from 99.5% to 99.95% "because it's customer-facing." What should happen before agreeing?

Price the specific GCP architecture change that target actually requires (typically multi-region active-active infrastructure, automated failover, dedicated on-call) rather than treating "more nines" as a free request, and confirm the business case still holds once the real infrastructure and operational cost is quoted.

A Compute Engine instance flagged as idle by Active Assist's IdleResourceRecommender is a candidate for retirement. What should happen before decommissioning it?

Verify zero real consumers over a full business cycle, not just a quiet observation window — an idle-looking resource (low CPU, no recent deploys) is not the same as confirmed zero downstream dependents. Meridian's own legacy-invoice-sync retirement found an undocumented nightly job still consuming a file it wrote, discovered only because the team watched for consumers rather than assuming none existed.

Quick-Fire Recall#

PromptAnswer
Fastest way to get some SLO live on a new servicebasicSli — near-zero config, revisit with a custom SLI later
Function that exposes an SLO's burn rate to alerting policiesselect_slo_burn_rate(SLO_NAME, lookback)
Why pair a short and long lookback windowShort window alone = false positives from blips; long window alone = slow to react; AND requires both
What a Cloud Service Mesh SLO sees that an application SLO doesn'tNetwork-facing behavior via the Envoy sidecar, with zero app code changes
What a Cloud Service Mesh SLO can't seeApplication-level correctness — a wrong-but-successful response
Compute Engine multi-zone instance SLA≥ 99.99%
Cloud Run / Cloud SQL HA SLA≥ 99.95% each
What an SLA breach credit does NOT compensateThe downstream business cost of the outage — only future billing
Where an error budget policy should be enforced, not just documentedAn automated pre-promotion check the pipeline itself runs (e.g., a Cloud Build step reading a Firestore-backed tier)
What a "frozen" error budget tier should still allowAn explicit, auditable override for the incident fix itself — not unrelated ready work

Part 2 Questions: Capacity Planning, Autoscaling & Mitigating Incident Impact#

Conceptual#

What's the difference between a quota, a limit, and a reservation on GCP?

A quota is a per-project or per-region cap GCP enforces on a resource, and can typically be raised by request. A limit is a hard, non-negotiable system limit that can't be raised at all. A reservation is pre-purchased, guaranteed capacity for a specific machine type/zone that matching VMs consume automatically — it guarantees availability, not just permission to request it.

Why can't a quota increase request be used as a real-time incident-mitigation lever?

Even an automatically-approved quota increase typically takes minutes to process, and one requiring manual Google review can take days — neither is fast enough to help during an active incident. Quota headroom has to already exist before the incident starts; requesting more mid-incident helps the next incident, not the current one.

What does Cloud Quotas' Quota Adjuster do differently from a manual quota increase request?

It observes real usage trends and proactively submits increase requests automatically before a project gets close to its ceiling, rather than waiting for a human to notice during a capacity review or an incident — turning quota management from reactive to proactive.

When does Dynamic Workload Scheduler's Flex-Start mode fit better than Calendar mode, and vice versa?

Flex-Start mode fits a workload with a flexible start time but a real deadline — it requests capacity for a bounded duration (1 minute to 7 days), fulfilled as soon as available, billed only for actual usage. Calendar mode fits a planned, time-critical event where "as soon as available" isn't good enough — it reserves capacity for a specific future window up to 90 days out, paid for the full reserved duration regardless of usage.

Name the three GCP incident-mitigation levers this chapter covers, and the trigger condition each one addresses.

Draining/redirecting traffic addresses a localized unhealthy backend. Adding capacity addresses a genuine demand spike with no recent deploy. Rollback addresses an error signature that correlates with a specific recent release.

Applied / Scenario#

shipment-api's error rate spikes at the exact timestamp a new release finished deploying, and traffic volume is at a normal baseline. Which lever fits, and which two don't?

Rollback fits — the timing correlation with a release, combined with normal traffic, points at the deployed code itself. Adding capacity doesn't fit (there's no volume problem, and more instances just run the bad code faster); draining a specific backend doesn't fit either (the problem is the deployed code, not one unhealthy instance among healthy ones).

A responder wants to use Spot VMs for emergency overflow capacity during an active incident because they provision fast and cost less. What's the risk, and what should they use instead?

A Spot VM can be preempted by Google mid-incident, turning an already-degraded system into a worse one at the worst possible time. The responder should provision standard (non-Spot) capacity for incident-response overflow specifically, reserving Spot for routine, fault-tolerant elastic scaling where a preemption is a minor, expected event rather than a compounding failure.

A team applies both a rollback and a capacity increase simultaneously during an incident, and the symptom resolves. What's the actual cost of doing both at once, even though it worked?

The postmortem can't determine which change actually fixed the issue, since both were applied together — a real cost when the same failure mode recurs later and the team needs to know immediately which lever to reach for, rather than repeating the same ambiguous double-fix.

Why does gcloud deploy targets rollback not instantly bypass a configured approval gate during an emergency?

Because it re-runs the entire delivery pipeline for the prior release, including whatever approval gate that release originally required — an unreviewed emergency rollback would itself be a real risk, so the gate stays in place. A responder should know in advance whether the target has an approval gate and factor that approval time into incident response time.

Before a known seasonal traffic peak, Priya's team wants to decide whether to pre-emptively raise a MIG's minimum size. What GCP-specific technique should they use instead of relying on a felt sense of "traffic's been growing"?

Query real historical utilization data directly — a PromQL query against Cloud Monitoring's own metrics (e.g., quantile_over_time for a 95th-percentile CPU trend over the past several weeks) gives an actual trend to plan against, rather than an intuition-based guess, matching the "forecast from real data" discipline Capacity Planning & Performance already taught generically.

Quick-Fire Recall#

PromptAnswer
Why can't a quota increase fix an active incidentIt takes minutes to days to process — headroom must exist beforehand
GCP feature that proactively requests quota increasesCloud Quotas Quota Adjuster
DWS mode for a flexible-timing, bounded-duration workloadFlex-Start
DWS mode for a fixed, planned future eventCalendar mode
Fastest traffic-redirect mechanism on Cloud Rungcloud run services update-traffic --to-revisions=OLD=100
What connection draining actually doesStops new connections to a backend, lets in-flight ones finish before removal
Why Spot VMs are risky for emergency overflow capacityMid-incident preemption compounds an already-degraded system
What gcloud deploy targets rollback does NOT skipAny approval gate the rolled-back release originally required
Query language now recommended for new Cloud Monitoring workPromQL (not the older MQL)
Why never apply two mitigation levers simultaneously without diagnosing firstIt leaves the postmortem unable to determine which change actually fixed it

Part 3 Questions: Instrumenting Telemetry#

Conceptual#

What are the two sub-agents bundled inside the Ops Agent, and what does each one collect?

A metrics collector (built on the OpenTelemetry Collector) and a logging collector (built on Fluent Bit), both controlled by one YAML config file. The metrics side collects infrastructure metrics; the logging side tails and ships log files/syslog.

What's the real operational tradeoff between the OpenTelemetry Collector's agent/sidecar pattern and its gateway pattern?

Agent/sidecar runs one collector per host or pod — more collectors to manage and more base resource overhead, but no shared point of failure. Gateway runs one shared collector per cluster/region — centralizes processing like redaction or sampling in one place, but an outage of that single collector affects every workload routed through it unless it's run with real availability discipline (multiple replicas, a PodDisruptionBudget).

Why is a full exclusion filter different from a sampling exclusion filter in Cloud Logging, and when would you use each?

A full exclusion filter drops every matching entry before storage — appropriate for genuinely zero-value noise like health-check logs. A sampling exclusion filter (using sample()) keeps a configured percentage and drops the rest — appropriate for high-volume but not zero-value logs, like routine 2xx load-balancer traffic, where some representative fraction still has analytical value.

What's the difference between managed collection and self-deployed collection in Google Cloud Managed Service for Prometheus?

Managed collection runs Google-operated collectors reading your PodMonitoring/ClusterPodMonitoring resources — lowest operational burden. Self-deployed collection runs your own Prometheus server or OTel Collector configured to remote-write into the same managed storage backend — for teams with an existing Prometheus scrape-config investment who still want Google's storage/query layer.

Why is building a Prometheus federation layer on top of Managed Service for Prometheus considered an anti-pattern?

Every self-deployed collector already writes into the same shared global backend (Monarch) — a single query or a GlobalRules recording rule can already aggregate across every cluster and project directly, so a federation layer solves a problem this architecture doesn't actually have, adding real operational complexity for no benefit.

Applied / Scenario#

route-optimizer's Cloud Service Mesh SLO shows a healthy 99.9% compliance, but a real capacity incident during a GKE upgrade goes completely undetected by any alert. What's the most likely explanation?

A silent telemetry coverage gap — a subset of nodes lost sidecar injection during the upgrade, so a fraction of real traffic never emitted the telemetry the SLO's SLI depended on. The SLO is computing an accurate number from an incomplete sample, not a wrong number — the fix is verifying sidecar-proxy container counts match pod counts directly, rather than trusting the SLO's healthy output as proof telemetry itself is complete.

A team runs their gateway-pattern OTel Collector as a single replica, and a routine node drain takes it down for ninety seconds. What's the actual blast radius?

Every workload routed through that one collector silently drops telemetry for the outage's full duration — not just the drained node, since a gateway centralizes collection for potentially many services at once. This is why the collector itself needs the same availability discipline (multiple replicas, a PodDisruptionBudget) as the production services it observes.

gps-ingestion-consumer logs its own per-message processing latency to structured logs but was never instrumented with OpenTelemetry. What's the right way to get a p95 latency metric from this, and what would be the better long-term fix?

In the short term, a distribution-type log-based metric with a value-extractor pulling the latency field out of each matching log entry — this backs real percentile queries the way a counter-only log-based metric can't. The better long-term fix is adding a native OpenTelemetry histogram metric directly in the application, since log-based metrics carry real ongoing parsing cost on every matching log entry that a native metric doesn't.

Meridian's checkout flow regresses at 3am, when almost no real customer traffic exercises it, and nobody notices for hours. Which of this chapter's telemetry mechanisms would have caught this, and why did the others miss it?

A synthetic monitor — it's active, running its own scripted probe on a schedule regardless of real traffic, unlike every other mechanism in this chapter (Ops Agent, mesh telemetry, application metrics), which are all passive and only surface a problem if real traffic happens to hit the broken path during the gap.

A newly onboarded GKE service has no telemetry at all yet. Per this chapter's layering guidance, what should be instrumented first, and why that order?

Infrastructure telemetry (Ops Agent) and mesh telemetry first, since both require zero application code changes and give an immediate baseline; application-level OpenTelemetry instrumentation next, for the metrics only the application itself knows about; a synthetic monitor last, for the specific workflows where a real-traffic gap would be unacceptable to miss. The order follows cost and specificity — cheapest and most general first, most deliberate and narrowly-scoped last.

Quick-Fire Recall#

PromptAnswer
What the Ops Agent's two sub-agents are built onOpenTelemetry Collector (metrics) + Fluent Bit (logging)
When to use gateway vs. agent/sidecar OTel Collector patternGateway for centralized processing at scale (with real HA); agent/sidecar for per-workload isolation
What a full exclusion filter does vs. a sampling oneFull = drop entirely; sampling = keep a configured percentage
What exclusion filters do NOT saveentries.write API quota/cost — they save storage cost, not ingestion write cost
Why federation is unnecessary on Managed Service for PrometheusAll collectors already write into the same global backend (Monarch)
Rules vs ClusterRules vs GlobalRules scopeProject only / project+cluster / entire metrics scope
What makes a synthetic monitor different from all other telemetry in this chapterIt's active (scripted, scheduled) — not passive/traffic-dependent
When to reach for a distribution log-based metricOnly when the data exists nowhere else — prefer a native OTel histogram when available
Counter vs. Histogram in the OpenTelemetry metrics SDKCounter = only increases, for event counts; Histogram = records a distribution, backs percentile queries
Root cause of an SLO showing healthy while a real incident goes undetectedA silent telemetry coverage gap, not a broken SLO

Part 4 Questions: Cloud Logging, Metrics, Dashboards & Alerting#

Conceptual#

What's the actual difference between a Log Analytics linked BigQuery dataset and exporting logs to BigQuery via a sink?

A Log Analytics linked dataset is a live view over the log bucket's own data — no separate copy, no ingestion/storage cost beyond the bucket itself. An export sink to BigQuery creates an actual separate copy of the data in a BigQuery table, with its own ingestion and storage cost.

What retention do the _Required and _Default log buckets carry, and which is configurable?

_Required holds Admin Activity and System Event audit logs at a fixed 400-day retention that cannot be modified. _Default holds everything else at a 30-day default retention, configurable between 1 and 3650 days.

Why does the sensitive-data redaction pipeline route logs through a Pub/Sub sink instead of letting them land in the default bucket first?

A log that reaches _Default has already been ingested unredacted — the whole point of routing through a Pub/Sub sink into a Dataflow pipeline calling Sensitive Data Protection (Cloud DLP) is intercepting and de-identifying the data before it's ever stored in a queryable bucket, not cleaning it up afterward.

Name two reversible de-identification methods and one irreversible one, and what determines which to use.

Tokenization and format-preserving encryption are reversible (with the encryption key); masking and bucketing are irreversible. The choice depends on whether there's a genuine, audited downstream need to ever recover the real value — reversible methods fit that need, irreversible methods fit a field with no legitimate reason to ever see the real value again.

Why are PagerDuty, webhook, Slack, and Cloud Mobile App notification channels not actually independent failure domains from each other?

All four route through a single shared Google-internal delivery service — a failure in that shared service affects all of them simultaneously, even though they appear to be separate integrations configured independently.

Applied / Scenario#

A burn-rate alerting policy fires correctly, but the page never reaches the on-call engineer for forty minutes. The policy's condition and threshold are confirmed correct. What's the likely cause, and what's the fix?

The likely cause is an outage in the shared Google-internal delivery backend that PagerDuty, webhook, Slack, and Cloud Mobile App channels all route through — not a misconfigured policy. The fix is adding a genuinely independent-backend redundant channel (email or Pub/Sub) alongside the primary consolidated channel specifically for high-stakes alerts.

A compliance review requires a full year of log lookback for shipment-api, but the _Default bucket is still at its 30-day default. What should Meridian's team do, and what should they be careful of if they ever need to shorten it back?

Increase the _Default bucket's retention to 365 days via gcloud logging buckets update. If retention is ever shortened later, logs older than the new period become immediately unqueryable (with only a 7-day grace period to undo it by raising retention again) — shortening should be a deliberate, compliance-reviewed decision, not a routine cost-cutting move.

A postmortem team wants to correlate error rate against total request volume per customer segment across a full incident window. Why is this the wrong job for Logs Explorer, and what's the right tool?

Logs Explorer and LQL are built for filtered, targeted lookups, not multi-field aggregation and correlation across a whole dataset. Log Analytics' linked BigQuery dataset, queried with real SQL (a GROUP BY with computed ratios per segment), is the right tool for this class of analytical question.

shipment-api's monthly Cloud Billing budget alert hasn't fired, but costs have been accelerating unusually fast for the past six hours due to a runaway autoscaling misconfiguration. Why didn't the budget alert catch this, and what would?

A budget alert only fires once cumulative spend crosses a threshold — six hours of acceleration may not yet have pushed the cumulative total past that threshold, even though the rate of spend is clearly abnormal. A separate Cloud Monitoring alert on the billing metric's rate of change (e.g., daily spend 3x above a 7-day average) catches the acceleration itself, independent of the cumulative budget check.

A team manages their production dashboards by clicking them together in the console, one engineer at a time. What's the risk, and what's the fix?

Console-built dashboards are undocumented and unreviewed — easy for engineers to silently duplicate effort, let drift from what the team actually needs, or lose when the one engineer who built it leaves. The fix is managing dashboards as Terraform (google_monitoring_dashboard), reviewed in the same pull request as the service's own infrastructure changes, the same discipline this course has applied to every other piece of Meridian's infrastructure.

Quick-Fire Recall#

PromptAnswer
What a Log Analytics linked dataset actually isA live view over the log bucket, not a copy
_Required vs _Default bucket retention400 days fixed / 30 days, configurable 1-3650
Grace period after shortening retention7 days before logs are actually deleted
Where PII/PHI redaction should happenBefore storage — Pub/Sub sink → Dataflow → Sensitive Data Protection (DLP)
Reversible de-identification methodsTokenization, format-preserving encryption
Irreversible de-identification methodsMasking, bucketing
Channels sharing one Google-internal delivery backendPagerDuty, webhook, Slack, Cloud Mobile App
Genuinely independent notification channel typesEmail, Pub/Sub
Query language now unified across Metrics Explorer, recording rules, and alertingPromQL
Where a budget alert falls short of catching a cost spikeIt only fires on cumulative total, not rate of acceleration

Part 5 Questions: Distributed Tracing & Troubleshooting Workflows#

Conceptual#

What's the difference between the longest span in a trace waterfall and the span actually on the critical path?

The longest span isn't necessarily on the critical path if it runs concurrently with other work — the critical path is the sequential chain of spans that actually determines total request time. A concurrent span, however long, contributes nothing to total latency if it finishes before the longest sequential chain does.

What mechanism propagates trace context across a service boundary, and what happens when a service fails to forward it?

The W3C traceparent header (or GCP's legacy X-Cloud-Trace-Context) carries the trace ID and parent span ID forward on outbound calls. A service that receives it but doesn't forward it on its own outbound calls silently breaks the chain — every span downstream starts a new, disconnected trace, with no error or warning to indicate propagation failed.

What two fields does a structured log entry need for automatic trace-log correlation in Cloud Logging?

logging.googleapis.com/trace (formatted as projects/PROJECT_ID/traces/TRACE_ID) and logging.googleapis.com/spanId.

What's the core difference between head-based and tail-based sampling, and why does it matter for a rare but important failure?

Head-based sampling decides whether to keep a trace before the request runs, blind to outcome — a rare failure has the same small chance of being sampled as any routine request. Tail-based sampling decides after the full trace is available, so it can guarantee every error or genuinely slow trace is kept regardless of the overall sample rate, at the cost of buffering complete traces before deciding.

What is an exemplar, and why can only histogram metrics carry one?

An exemplar is a specific trace ID attached to one observed data point inside a metric's distribution, letting a chart click jump directly to the trace behind that exact point. Only histograms can carry one because an exemplar attaches to an individual observation within a distribution — a counter metric has no distribution, just a running total, so there's no individual data point to attach a trace ID to.

Applied / Scenario#

shipment-api's SLO burn-rate alert fires, a recent deploy and a traffic spike are both ruled out, and the dashboard shows elevated latency with no errors. What's the next diagnostic step, and why?

Pull a trace waterfall for a currently-slow request — metrics already confirmed that something is slow, and the absence of errors rules out a simple log search finding a stack trace, so the trace waterfall is the tool that can show where specifically the time is going, which neither metrics nor logs alone can answer.

A team sets route-optimizer's head-based sampling to 100% after being burned by a missed incident, and Cloud Trace ingestion cost triples while the Trace UI becomes slower during the next real incident. What was the actual mistake, and what should have been done instead?

The mistake was treating "more sampling volume" as strictly safer without distinguishing volume from relevance — a much larger set of mostly-routine traces made the UI slower to surface the one trace that actually mattered. Tail-based sampling at a much lower overall rate, biased toward keeping errors and high-latency traces specifically, gives better diagnostic coverage at a fraction of the cost and query overhead.

A Cloud Run service calls a downstream API over a raw TCP socket instead of a supported HTTP/gRPC client library. What's the risk to trace propagation, and why might it go unnoticed?

The OpenTelemetry SDK's automatic instrumentation only handles propagation for supported client libraries — a raw socket call needs the traceparent header propagated by hand, and if that's missed, the downstream service's spans silently start a new, disconnected trace instead of continuing the original one. It goes unnoticed because there's no error — the waterfall just quietly stops showing anything past that point, which looks identical to "no interesting spans downstream."

An engineer wants to use an exemplar to link a spike in shipment-api's total request-count metric to a specific trace. Why won't this work?

Request-count is a counter, not a histogram — it has no distribution of individual observed values, only a running total, so there's no single data point within it to attach a trace ID to. Exemplars only work on histogram-type metrics, like a latency distribution, where each bucket represents real individual observations.

A team without a Premium Support contract designs their incident runbook assuming Gemini Cloud Assist Investigations will always be available to synthesize a root cause automatically. What's the risk?

As of April 2026, creating, running, and editing an Investigation requires a Premium Support contract or account-team-granted access — a team without that access has no working fallback if the runbook's primary step assumes Investigations is available. The manual, systematic five-category troubleshooting workflow should be the actual default, with Investigations treated as an acceleration layer only where access is confirmed to exist.

Quick-Fire Recall#

PromptAnswer
What determines whether a span is worth optimizingWhether it's on the critical path, not just its raw duration
Header that propagates trace context across servicesW3C traceparent (or legacy X-Cloud-Trace-Context)
Silent failure mode when propagation breaksDownstream spans start a new, disconnected trace — no error shown
Two structured-log fields for automatic trace-log correlationlogging.googleapis.com/trace, logging.googleapis.com/spanId
When tail-based sampling decides vs. head-basedAfter the full trace completes vs. before the request runs
Why tail-based sampling guarantees error/slow traces are keptThe decision is based on the full outcome, not a blind probability
What an exemplar attaches a trace ID toOne observed data point inside a histogram's distribution
Metric type required for exemplar supportHistogram only — not counters
Managed Service for Prometheus exemplar retention24 months (vs. typical sub-14-day upstream Prometheus default)
The five PCDE troubleshooting issue categoriesInfrastructure, CI/CD pipeline, application, observability, performance/latency

Part 6 Questions: Performance Monitoring & FinOps on GCP#

Conceptual#

What's the difference between what a CPU flame graph shows and what a heap allocation flame graph shows?

A CPU flame graph's bar width represents time spent executing — it finds the function actually burning CPU cycles. A heap allocation flame graph's bar width represents bytes allocated during the profiling window regardless of whether the objects are still alive — it finds a function creating excessive temporary objects and generating garbage-collection pressure, a different problem from a genuine memory leak.

Why does a trace waterfall and a CPU flame graph answer genuinely different questions, even though both are "performance tools"?

A trace waterfall shows where time goes across a request's path through multiple services, treating each service as a black box. A CPU flame graph shows where time goes inside one application's own code, function by function — it can identify a specific function consuming a given percentage of CPU time, a level of detail no trace span alone provides.

Name the three phases of the FinOps operating model, and what each one covers.

Inform (billing export, dashboards, cost attribution via labels — establishing visibility), Optimize (CUD purchases, Recommender-driven rightsizing, Spot strategy — active waste reduction), and Operate (budgets, labeling enforcement, a recurring review cadence — ongoing governance).

Why can a Managed Service for Prometheus recording rule that groups by a high-cardinality label silently inflate monitoring cost?

Each unique label value combination becomes its own permanently stored time series — grouping by something like a raw device ID or request ID with tens of thousands of distinct values creates tens of thousands of stored series, none of which existed before the rule was added, with no obvious single moment where the cost jump would be noticed without a deliberate review.

What's the core tradeoff between GKE Autopilot's billing model and GKE Standard's, and what determines which is cheaper?

Autopilot bills per pod resource request and rewards accurate requests; Standard bills per node regardless of pod density and rewards active, deliberate bin-packing. A team that won't actively bin-pack is usually cheaper on Autopilot; a dense fleet of many small microservices that will be actively bin-packed (especially with Spot node pools) can be dramatically cheaper on Standard.

Applied / Scenario#

Meridian's Managed Service for Prometheus bill grows 4x over two months with no corresponding growth in traffic or service count. What's the likely cause, and how would a quarterly FinOps review have caught it sooner?

The likely cause is a recording rule or query grouping by a high-cardinality label added for a legitimate but narrow debugging purpose (in Meridian's real case, grouping by a 40,000-value device ID field), silently multiplying stored time series. A regular FinOps "Inform" review, tracking cost by label/service trend over time, would have surfaced the unexplained cost jump within the first review cycle after the change, rather than two months later.

A team purchases a 3-year CUD sized against their current Compute Engine footprint, then migrates half that workload to GKE over the following two quarters. What's the risk, and what would have reduced it?

Over half the committed capacity goes unused once the migration completes, while the CUD continues billing at the full committed rate for the remaining commitment term regardless of actual usage — a fixed cost paid for capacity that no longer exists. A shorter commitment term (1-year instead of 3-year), reviewed and re-committed at renewal once the migration's real trajectory is known, captures most of the same discount with far less stranded-commitment risk.

shipment-api has steady, high-volume traffic on Cloud Run. Which billing model should it use, and why not the default?

Instance-based billing — Cloud Run's default is request-based billing (no charge while idle), which is optimized for bursty, sporadic traffic. For steady, high-volume traffic, instance-based billing's lower per-second rate wins out despite billing for the instance's full lifecycle, since there's little idle time being paid for unnecessarily in the first place.

Meridian is deciding between Premium and Standard network tier for two different workloads: a customer-facing tracking API and a nightly internal BigQuery export job. Which tier fits each, and why?

The customer-facing tracking API should stay on Premium — its lower latency (Google's private backbone) is worth the higher per-GB egress cost for a latency-sensitive, customer-facing path. The nightly BigQuery export job should use Standard — it's not latency-sensitive, and Standard's notably lower per-GB egress cost (roughly 30-60% less) is pure savings with no real downside for a bulk, non-interactive transfer.

A team has only ever used Active Assist's cost-category recommendations. What are they missing, and how would they access it?

They're missing four other value categories — security, performance, reliability, and manageability — all served by the same underlying Recommender API, just via a different --recommender type in the same gcloud recommender recommendations list command. A performance-category recommender, for instance, can surface a Compute Engine instance pegged near 100% CPU, a signal just as actionable as an idle-resource cost recommendation but answering a completely different question.

Quick-Fire Recall#

PromptAnswer
What a CPU flame graph's bar width representsTime spent executing
What a heap allocation flame graph's bar width representsBytes allocated during the window
Cloud Profiler's typical amortized overheadUnder 0.5% across a fleet
The three FinOps phasesInform, Optimize, Operate
Why high-cardinality label grouping inflates monitoring costEach unique label combination becomes its own stored time series
Automatic, no-commitment GCP discountSustained Use Discount (SUD)
Committed, multi-year GCP discountCommitted Use Discount (CUD), up to ~57%
Where to pull real usage data before a CUD purchaseThe CommitmentRecommender
Premium vs. Standard network tier tradeoffLower latency, higher cost vs. higher latency, lower cost (~30-60% less)
What determines GKE Autopilot vs. Standard cost-effectivenessWhether the team will actively bin-pack — Standard wins if yes, Autopilot if no