Back to articles
Production-level
12 min read

Observability Before Deployment

A production-focused argument for designing observability before rollout so releases can be detected, understood, and recovered under pressure.

observabilityrelease-engineeringdeployment-automationincident-responsedevopsproductionarchitecture
João Gustavo Camilo JúniorEngineering Lead
Engineering

Observability Before Deployment

If you cannot see the failure mode before deployment, you are not ready to deploy.

You may still choose to ship.

That is different.

Production does not care that the build passed, the migration ran, the feature flag is off by default, or the release manager approved the change. Production cares whether the system can reveal what changed, who is affected, how fast the damage is spreading, and which recovery action will actually reduce impact.

Observability is often treated as something added after deployment.

That is backwards.

The moment to design observability is when the change is still small enough to understand. Before rollout. Before the incident. Before the team is staring at a graph that shows "errors increased" without enough context to explain why.

Deployment without observability is not confidence.

It is delayed discovery.

The Context Teams Usually Accept

Most teams have some monitoring.

They have dashboards, logs, alerts, traces, uptime checks, error tracking, cloud metrics, and deployment notifications. The problem is not always absence of data. The problem is that the data was not designed around the change being deployed.

A release changes a billing calculation, but the dashboard shows CPU and HTTP 500s.

A new worker changes queue throughput, but the alert watches only process health.

A feature flag exposes a new checkout path, but traces do not carry flag state.

A migration changes read behavior, but logs do not include schema version or fallback path.

The system is "monitored."

The release is still opaque.

Google SRE's monitoring guidance separates the question of what is broken from why it is broken, and emphasizes signals such as latency, traffic, errors, and saturation. DORA's monitoring and observability guidance adds another important distinction: monitoring watches predefined signals, while observability helps teams debug patterns they did not know in advance.

Both matter during deployment.

Monitoring tells the team whether known guardrails are failing.

Observability lets the team investigate the failure mode the release just created.

The Problem Is Release Blindness

Release blindness happens when the deployment changes production behavior faster than the team can understand it.

The service may be up. The error rate may be stable. The deployment tool may report success. The real regression may sit in a business workflow, a tenant cohort, a retry path, a background job, a third-party dependency, or a data shape only one customer segment uses.

The team detects it later through support tickets, manual reconciliation, customer escalation, or a dashboard built after the incident.

That is not bad luck.

It is missing release observability.

Observability before deployment means defining how the system will prove the change is healthy before the change is exposed to real users.

This changes the release conversation.

Instead of asking only "did tests pass?" the team asks:

  • What production signal should move?
  • What signal must not move?
  • Which cohort receives the change first?
  • How do we compare old and new behavior?
  • What labels identify this version, flag, tenant, region, or workflow?
  • What alert stops rollout?
  • What evidence tells us rollback is working?

These questions belong in design review and pull request review.

Not only in incident response.

Observability Is Part Of The Release Contract

A release contract should define more than artifact, environment, and approval.

It should define the evidence expected after deployment.

For a production service, that evidence usually includes:

  • Version identity.
  • Deployment marker.
  • Feature flag state.
  • Cohort or tenant scope.
  • Request path.
  • Dependency behavior.
  • Error classification.
  • Latency distribution.
  • Saturation signal.
  • Business outcome.
  • Recovery signal.

The exact set depends on the change.

A payment change needs provider response codes, authorization rate, duplicate attempt rate, settlement consistency, and reconciliation signals.

A search change needs latency, zero-result rate, click-through behavior, indexing lag, and fallback usage.

A background worker change needs queue age, throughput, retry rate, dead-letter volume, downstream saturation, and idempotency errors.

A schema migration needs lock time, replication lag, read fallback rate, backfill progress, and old-versus-new path usage.

Generic dashboards are not enough.

The release needs telemetry aligned with the failure mode.

The Technical Discussion

Good release observability starts with correlation.

When production changes, the telemetry needs to answer what version, path, tenant, region, cohort, flag state, and dependency state were involved. Without correlation, engineers end up comparing unrelated graphs and guessing.

OpenTelemetry's model of metrics, logs, traces, and related signals is useful here because it encourages consistent context propagation across services. DORA's observability guidance also calls out metrics, logs, traces, events, and the need to connect data across distributed systems.

The practical engineering concern is not whether the team uses a specific tool.

The concern is whether release context survives the path through the system.

Version Context

Every service should expose the running artifact identity.

Logs should include version or deployment ID. Metrics should be attributable to version where cardinality allows. Traces should carry service version. Dashboards should show deployment markers. Rollback verification should compare old and new version behavior.

Without version context, the team cannot tell whether a regression belongs to the release or background noise.

Flag Context

Feature flags are release controls.

They should be observable.

If a request entered the new invoice path because new_invoice_engine was enabled for a tenant, traces and logs should make that visible. Metrics should allow comparison between enabled and disabled cohorts for important business and operational signals.

This does not mean adding every flag to every metric. That can destroy cardinality and cost.

It means instrumenting the flags that matter to the release risk.

Business Context

HTTP 200 is not always success.

Google SRE's monitoring chapter explicitly notes that errors can be implicit: a request can technically succeed while returning wrong content or violating a policy. This matters during deployment because many regressions are semantic.

An invoice generated with the wrong line items is not an HTTP failure.

A checkout flow that silently increases abandonment may not show up as an exception.

A worker that processes jobs twice may look healthy until reconciliation fails.

Release observability must include business guardrails where the production risk is business behavior.

Dependency Context

Deployments often change dependency pressure.

A new cache path changes hit rate. A new worker increases database writes. A new provider integration shifts error modes. A new retry policy amplifies traffic during partial failure.

The release needs dependency signals before rollout:

  • Provider error codes.
  • Retry count.
  • Timeout rate.
  • Circuit breaker state.
  • Queue depth.
  • Connection pool saturation.
  • Database lock and replication indicators.

Without dependency context, the team learns too late that the release was safe only inside the service boundary.

Code Only Helps When It Carries Context

Instrumentation code should explain production behavior, not decorate handlers.

This is useful when a release has cohort-specific behavior:

ts
const releaseContext = {
  service_version: process.env.SERVICE_VERSION,
  feature_flag: "new_invoice_engine",
  flag_enabled: featureDecisions.useNewInvoiceEngine(tenantId),
  tenant_tier: tenant.tier,
};
 
span.setAttributes(releaseContext);
metrics.invoiceGenerationTotal.add(1, {
  engine: releaseContext.flag_enabled ? "new" : "legacy",
  tenant_tier: tenant.tier,
});

This code exists because the release question is not "did invoice generation run?" The question is whether the new path behaves differently from the legacy path for the exposed cohort.

Use this pattern when:

  • A feature flag controls material behavior.
  • A rollout is scoped by tenant, region, or cohort.
  • A business workflow needs comparison between old and new paths.
  • The rollback decision depends on production evidence.

The trade-off is cardinality and cost. Do not attach user IDs, request IDs, or unbounded values to metrics. Keep high-cardinality investigation data in traces or structured logs where the tooling and retention model can handle it.

Instrumentation that cannot be queried during an incident is not operational evidence. It is storage cost with good intentions.

Real-World Trade-Offs

Observability before deployment has costs.

It adds work before release. It requires engineers to think about failure modes. It can increase telemetry volume. It can create noisy dashboards if the team instruments everything without discipline. It can also slow teams that are used to shipping first and learning from support tickets later.

Those costs are real.

But the alternative is more expensive when the system matters.

Without release observability, teams pay through:

  • Slower detection.
  • Longer incident triage.
  • Wider blast radius.
  • Unsafe rollbacks.
  • Ambiguous postmortems.
  • Repeated regressions.
  • Loss of trust in deployment.

The mature trade-off is risk-based.

Not every change needs custom metrics. A copy change does not need a release observability plan. A new payment workflow does. A queue backfill does. A schema migration does. A feature flag that changes authorization does.

The question is not "should we instrument everything?"

The question is "what signal would we regret not having if this release fails?"

Operational Considerations

Release observability should become part of the deployment checklist, but not as a checkbox.

It should be specific.

Before deployment, define:

  • Guardrail metrics.
  • Expected movement.
  • Stop conditions.
  • Rollback verification signals.
  • Owner of rollout observation.
  • Dashboard or query links.
  • Cohort labels.
  • Alert changes.
  • Post-deploy watch window.

For risky releases, write the observation plan in the pull request or release note. It does not need to be long. It needs to be concrete.

Example:

  • Rollout starts with internal tenants.
  • Watch invoice generation latency p95 and p99.
  • Compare legacy versus new engine mismatch count.
  • Stop if mismatch count is non-zero.
  • Stop if provider error rate increases above baseline by 2x for 10 minutes.
  • Verify rollback by watching new engine traffic return to zero.

That is release engineering.

It makes production feedback part of the plan.

A Production Story

Production Story

A team shipped a new account provisioning flow for enterprise tenants. The deployment was careful: feature flag, internal rollout, then two customer tenants. The service health dashboard stayed green. HTTP errors were flat. Latency looked normal. Two days later, support found that some accounts were missing default permissions when created through a rarely used SSO path.

The release had monitoring.

It did not have release observability.

The team could see request volume, error rate, and latency. They could not easily answer which accounts were created by the new flow, which identity provider path they used, whether the default permission writer ran, or whether the permission set matched the expected template.

The rollback stopped new damage, but cleanup took longer than the fix.

After the incident, the team changed the release process:

  • Provisioning events included flow version and identity provider type.
  • Permission assignment emitted structured success and mismatch events.
  • A dashboard compared expected versus actual permission sets by rollout cohort.
  • The feature flag state appeared in traces.
  • Rollout could not proceed until the parity dashboard stayed clean for a full business day.

The code change was smaller than the observability change.

That was the point.

The original deployment changed a business invariant without making the invariant visible.

Common Mistakes

Watching Infrastructure Instead Of Behavior

CPU, memory, and pod health matter.

They do not prove the release is correct.

If the change affects money, permissions, data integrity, or customer workflow, watch those signals directly.

Alerting On Causes First

Google SRE recommends symptom-oriented alerting for paging because pages should represent user-visible or imminent impact. Cause metrics are useful for debugging. They should not all page humans.

Release dashboards can show causes.

Release alerts should focus on impact and stop conditions.

Forgetting Rollback Observability

Rollback also needs evidence.

After disabling a flag or reverting an artifact, the team should know whether the risky path stopped, whether error rate recovered, whether queues are draining, whether bad writes stopped, and whether customer-impact indicators returned to baseline.

Ignoring Cardinality

High-cardinality telemetry can be valuable for investigation and expensive for metrics.

DORA's observability guidance calls out cardinality and dimensionality as scale concerns. Treat them as design constraints. Put bounded labels in metrics. Put richer context in traces and logs. Sample intentionally.

Key Takeaways

Further Reading

The Decision Principle

Observability is not something to add after the deployment checklist is complete.

It is part of deciding whether the deployment is ready.

If the team cannot describe what healthy looks like, what failure looks like, how to identify affected cohorts, and how to verify recovery, the release is not fully designed.

The system may still ship.

But it is shipping with a blind spot.