← Back to Insights

Production investigation

Finding Data Inconsistencies in Production

Written by:Better SoftwareBetter Software TeamUpdated 6 min read
Finding Data Inconsistencies in Production

Quick Answer

Production data inconsistencies appear when data states diverge from expected values, across data stores or within a single system. Typical causes include race conditions, failed distributed transactions, asynchronous lag, application bugs, partial updates and missing idempotency. Investigation verifies the anomaly, defines the expected state, traces data flow and transaction boundaries, and tests a root cause hypothesis, while prevention relies on idempotent writes, retries, dead-letter queues and reconciliation checks.

In our experience, production data inconsistencies arise when data states diverge from expected values. This includes mismatches between data stores or incorrect data within a single system. These issues compromise system reliability and data integrity.

Why Production Data Becomes Inconsistent

Data inconsistencies typically result from race conditions or failed distributed transactions. Asynchronous processing can also introduce lags that appear as inconsistencies. Intermittent issues often involve complex timing dependencies. Application bugs can fail to write data correctly. Network partitions or service outages can lead to partial updates. Overlooked rollback mechanisms also contribute to inconsistent states. Manual data modifications bypass system validation rules. External system integrations may introduce incorrect data. Data replication failures between primary and secondary systems are common. Lack of idempotent operations can lead to duplicate processing.

How to Investigate a Data Inconsistency Step by Step

  1. Verify the Inconsistency. Confirm the reported anomaly. Use direct database queries or API calls. Do not rely solely on UI reports.
  2. Reproduce and Isolate. Attempt to reproduce the inconsistency in a staging environment. If not possible, analyze production logs. Identify specific transactions or events involved.
  3. Define Expected State. Determine the correct state for the affected data point. Consult business logic specifications and data models. Clarify what 'consistent' means in this context.
  4. Identify Divergent Systems/Components. Pinpoint where data differs. Check primary databases, caches, search indices, and replicas. Examine external services that consume or produce this data.
  5. Trace Data Flow. Follow the data's journey through the system. Review application logs for write operations. Check message queues for unprocessed or failed messages. Examine audit logs for manual changes.
  6. Inspect Transaction Boundaries. Evaluate the atomic units of work. Look for transactions that failed mid-commit. Check for unhandled exceptions during data updates.
  7. Review Time-Based Factors. Analyze timestamps across data stores. Determine if data propagation delays are causing perceived inconsistency. Investigate potential race conditions in concurrent writes.
  8. Examine Data Integrity Constraints. Verify database constraints are active. Check for application-level validation bypasses.
  9. Consult Relevant Codebases. Review code sections responsible for data modification. Look for logical errors or missing error handling.
  10. Formulate Hypothesis. Based on evidence, propose the root cause. This could be a code bug, infrastructure issue, or external factor.
  11. Test Hypothesis. Validate the hypothesis with further investigation or experiments. Simulate the suspected failure mode if safe.

A Practical Example of a Missing Order

Here is an illustrative example we use to show the pattern. A user reported a purchased item not appearing in their order history. The payment gateway confirmed a successful transaction ID. The customer service portal showed no corresponding order. Investigation steps began with verifying the inconsistency. Direct database queries for the order by transaction ID returned no results. Checking the payments table confirmed the successful transaction. The expected state was a completed order with associated items. Tracing data flow involved reviewing application logs. Logs showed the payment callback POST request was received by the API. The order processing service logs showed no entry for that transaction ID. The message queue between the API and the order service indicated no message for this payment. A deeper dive into application logs revealed a transient network error when publishing to the message queue. The API marked the payment as processed but failed to enqueue the order creation message. The payments table was updated successfully. The order service never received the instruction to create an order. The API code lacked a retry mechanism or robust error handling for queue publishing failures. Remediation involved manually creating the missing order. A patch added retry logic and dead-letter queueing for similar dispatch failures. Context switching costs were factored into the incident review.

Preventing Recurrence With Idempotent Writes

Implement robust transaction management across services. Use distributed transaction patterns where necessary or rethink architecture to avoid them. Ensure idempotent operations are standard for all write paths. Validate all incoming and outgoing data at service boundaries. Introduce robust retry mechanisms with exponential backoff for external calls. Implement dead-letter queues for failed message processing. Enhance monitoring for queue depths and message processing failures. Use CRC checks or similar for data integrity during transfer. Regularly audit data using reconciliation checks. Alert when discrepancies are found between key data stores. Design for eventual consistency where appropriate, but understand its implications. Automate data consistency checks to reduce manual effort.

What Teams Usually Do Instead

Teams often immediately blame the database. They spend time optimizing database queries. This is before understanding the data flow problem. They might manually fix data without documenting the root cause. This leads to repeated incidents. Some teams implement complex, ad-hoc compensation logic. This adds system complexity without addressing the original defect. Others focus on UI fixes to hide the inconsistency. The underlying data remains corrupted. They may also escalate to multiple teams simultaneously. This creates noise and diffusion of responsibility. This prolongs resolution and increases incidental communication overhead. Without a structured process, efforts are reactive, not preventative. These checks belong in product engineering from the start, not after an incident.

Key Takeaways for Data Inconsistencies

  • Verify reported inconsistencies directly.
  • Trace data flow across system components.
  • Examine transaction boundaries for failures.
  • Implement idempotent operations to prevent duplicates.
  • Automate data integrity checks proactively.

If your systems keep disagreeing about the truth, talk to Better Software about where to start.

Frequently Asked Questions

What Is a Production Data Inconsistency?

In our experience it is a case where data states diverge from expected values, either as mismatches between data stores or as incorrect data within one system. These issues compromise system reliability and data integrity.

What Causes Data Inconsistencies in Production?

We typically see race conditions, failed distributed transactions, asynchronous lag, application bugs that write data incorrectly, network partitions causing partial updates, replication failures, manual data changes and missing idempotency. Overlooked rollback mechanisms and incorrect data from external integrations also contribute.

How Do I Investigate a Data Inconsistency?

We verify the anomaly with direct queries rather than UI reports, define the expected state, and pinpoint which systems diverge. Then we trace the data flow, inspect transaction boundaries and time-based factors, check integrity constraints, review the code, and test a hypothesis.

Why Is the Database Not Always the Culprit?

We find teams often blame the database and optimize queries before understanding the data flow. In the example above the payment was recorded but a transient error stopped the message that creates the order, so the root cause was missing retry logic in the API.

How Can I Prevent Data Inconsistencies?

We use idempotent operations on all write paths, validate data at service boundaries, retry external calls with exponential backoff, add dead-letter queues, monitor queue depths and run reconciliation checks that alert on discrepancies. We also automate those checks to reduce manual effort.

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.