← Back to Insights

Debugging workflows

Building a Failure Model From Partial Data

Written by:Better SoftwareBetter Software TeamUpdated 7 min read
Building a Failure Model From Partial Data

Quick Answer

A mental model of a production failure is a testable hypothesis built from partial data such as logs, metrics, traces and anecdotal reports. The process runs from collecting and centralizing data and setting a baseline to naming the failure signature, forming several hypotheses and actively seeking data that contradicts them. A good model explains how the failure progressed, acknowledges its data gaps and is validated against other observable effects.

A mental model of a production failure from partial data involves synthesizing all available signals. This includes logs, metrics, traces, and anecdotal reports. In our experience the goal is to create a testable hypothesis explaining observed system behavior. This hypothesis must account for missing or ambiguous information. Its development allows for targeted investigation and efficient restoration of service.

Why Partial Data Makes Failures Hard to Read

System observability is rarely complete. Production systems are complex and distributed. Data sources are often disconnected or time-asynchronous. Different components emit different levels of detail. Metrics may show an anomaly. Logs may not contain specific error messages. Distributed traces might be incomplete due to sampling. Failures can manifest in obscure ways. They might be intermittent or specific to certain traffic profiles. This leads to an incomplete picture. Engineers must infer causality from correlation. They use fragmented information to reconstruct a failure's timeline and root cause. Organizational silos also contribute. Different teams own different services and data. Accessing full data sets can be cumbersome.

A Step by Step Process for Building the Model

  1. Collect and Centralize Data. Gather all available data streams. This includes application logs, infrastructure metrics, system traces, and deployment history. Use a centralized logging or observability platform if available.
  2. Establish a Baseline. Compare current anomalous data to normal system behavior. Look for deviations in metrics such as latency, error rates and resource utilization. Review recent changes such as deployments, configuration updates and external service issues.
  3. Identify the Failure Signature. Pinpoint the primary symptom experienced by users or downstream systems. Is it high latency, outright errors, data inconsistency, or service unavailability?
  4. Formulate Initial Hypotheses. Based on the signature and baseline, propose multiple potential causes. Consider common failure modes such as resource exhaustion, code defects, network issues and external service outages.
  5. Correlate and Contradict Data Points. Search for correlations across different data types. Do error logs align with spikes in CPU usage? Does a trace show a specific service call timing out? Crucially, identify data points that contradict a hypothesis. These contradictions help prune unlikely causes.
  6. Narrow Down the Scope. Use filtering and aggregation to focus on specific components or time windows. Is the issue global or localized? Does it affect all users or a subset? Tracing a request failure across distributed systems can be instrumental here.
  7. Iterate and Refine Hypotheses. As new data emerges, update or discard hypotheses. Design small, testable interventions if safe. This might involve restarting a service or rolling back a recent change.
  8. Synthesize a Coherent Model. Construct a narrative that explains the failure's progression. This model should account for all observed symptoms and available data. It should also acknowledge data gaps.
  9. Validate the Model. If possible, use the model to predict other observable effects. This strengthens its accuracy.

A Practical Example of Payment Service Timeouts

A payment processing service experienced intermittent failures. Users reported transaction timeouts. The service's error rate metric showed brief, sporadic spikes. Application logs showed no explicit errors for timed-out requests. Service A, a database interaction service, showed increased latency. Database connection pools were not exhausted. Network monitoring showed no packet loss. Distributed traces appeared incomplete or stopped prematurely for failing requests. Engineers correlated the error spikes with high CPU utilization on Service A instances. High CPU coincided with increased garbage collection pauses, indicated by JVM metrics. These pauses directly mapped to the transaction timeouts at the application layer. The incomplete traces were a symptom of the JVM pauses. They prevented traces from being fully emitted. The mental model became that high CPU in Service A causes JVM pauses, leading to request timeouts. The investigation revealed a recent deployment to Service A. It introduced a new data serialization library. This library caused excessive object allocations. This drove up garbage collection activity and CPU. Rolling back the deployment resolved the issue.

Preventing Recurrence With Better Observability

Improve observability for common failure modes. Enhance logging granularity for key transaction steps. Add metrics for critical system resources, like JVM heap usage and garbage collection pauses. Implement end-to-end distributed tracing with lower sampling rates for critical paths. This ensures full visibility during failures. Develop automated alerts for significant deviations in these new metrics. Implement canary deployments for all new code. This isolates issues to a small subset of traffic. Conduct thorough post-incident reviews. Document the investigation process and learnings. Integrate these findings into future system design and testing. Maintain runbooks for common diagnoses involving partial data. Explicitly instrument potential performance bottlenecks to detect gradual performance degradation.

What Teams Usually Do Instead

Many teams focus on a single data source in isolation. Operators might only check primary service logs. This often leads to misdiagnosis or prolonged investigation. They might restart services without understanding the root cause. This temporarily alleviates symptoms without resolving the underlying problem. Teams may also prematurely blame external dependencies. They assume a third-party issue without verifying their own systems first. This wastes time and diverts attention. Some teams might also collect too much data without correlation tooling. This creates data swamps. Engineers spend excessive time manually sifting irrelevant information. Reactive changes to system configurations are also common. These changes are often without clear hypotheses or roll-back plans, compounding the problem. We treat these practices as part of product engineering, not as an afterthought once an incident has happened.

Key Takeaways for Partial Data Investigations

  • Collect all available data, even if partial.
  • Formulate multiple, testable hypotheses.
  • Correlate data across different observability signals.
  • Actively seek data that contradicts initial theories.
  • Iterate on hypotheses with new information.

We cover related ground in debugging a problem when logs are incomplete. To work through a production problem with a team, talk to Better Software.

Frequently Asked Questions

What Is a Mental Model of a Production Failure?

We use the term for a testable hypothesis, built from logs, metrics, traces and anecdotal reports, that explains observed system behavior. It has to account for missing or ambiguous information, and it makes targeted investigation and efficient restoration of service possible.

Why Is Production Data Often Incomplete?

In our experience observability is rarely complete. Systems are complex and distributed, data sources are disconnected or time-asynchronous, components emit different levels of detail, and sampling leaves traces incomplete. Organizational silos also make full data sets cumbersome to access.

How Do I Build a Model From Partial Data?

We start by collecting and centralizing all available data, then establish a baseline and identify the failure signature. From there we form several hypotheses, correlate and contradict data points, narrow the scope, refine the hypotheses, and synthesize a narrative that acknowledges data gaps.

Why Should I Look for Data That Contradicts a Hypothesis?

Because contradictions help prune unlikely causes. We correlate across data types, for example checking whether error logs align with spikes in CPU usage, and we deliberately look for data points that conflict with the current theory before settling on one.

How Can Teams Prevent Repeat Investigations?

We improve observability for common failure modes, add metrics for critical resources, use end-to-end tracing on critical paths, set automated alerts, run canary deployments, hold post-incident reviews and maintain runbooks for diagnoses involving partial data. We also document each investigation.

About the author

Better Software

Better Software Team

Product and engineering team

Better Software Team is the product and engineering team at Better Software. We build new software products and improve existing applications and systems, with deeper experience in healthcare, finance and energy.