Skip to content

The backup was written five years ago. How do we know its bytes are still correct?

The Object Exists. Is It Safe? · Part 5 of 6 · 6 min read

Read the worked explanation ↓

Interview question. An archive service stores 100 PB of customer backups. Objects are rarely read after upload. One day a restore request returns a corrupted file even though the original upload succeeded and no disk reported an obvious outage. Design checksums, background scrubbing, detection, and repair so silent corruption does not accumulate unnoticed for years.

The frightening part is that the monitoring can look healthy until the day somebody actually needs the data. A storage service can preserve an object name, size, and creation timestamp while one of its underlying data fragments has changed.

I would start with an end-to-end integrity claim: when a caller downloads object version V, the service can establish that the returned bytes match the content committed as V. Durability without an integrity check is incomplete. Merely keeping three copies is not enough if corrupted bytes can be replicated, or if the system has no way to distinguish the valid copy from a bad one.

A committed object checksum anchors periodic scrub checks, quarantine, trusted reconstruction and repair verification.
A committed object checksum anchors periodic scrub checks, quarantine, trusted reconstruction and repair verification.
Think first

You own 80 PB of rarely accessed backups on three replicas. A subset of disks begins returning silently wrong bytes. Design checksums, prioritized scrubbing, quarantine, repair and customer-visible alerts, with a 21-day verification objective.

Take a few minutes to form an approach, then compare it with the worked explanation.

Check the exercise numbers

For an 80 PB decimal dataset, 21 days is 1,814,400 seconds. One logical full pass needs about 44.1 GB/s on average. Validating every byte of all three replicas needs about 132.3 GB/s before retries, metadata, repairs and placement imbalance. A logical pass that reads only one replica does not verify the other two copies. Reserve per-device and per-rack capacity and track overdue objects so a fleet average cannot hide unvisited cold copies.

Reveal the worked explanation

Where the checksum is created matters

On upload, the client can compute a checksum over the expected content and send it with the request. The storage service independently computes its own checksum and rejects a mismatch. This catches failures on the upload path, subject to using a suitable algorithm and trusting the client's original bytes. For a security-sensitive untrusted-content identity or deduplication design, a cryptographic digest such as SHA-256 may be necessary because checksums intended for random errors are not collision resistant against malicious inputs.

The service stores a durable object-version identity and its authoritative checksum alongside the appropriate metadata. If an implementation recomputes the stored checksum from a damaged replica and overwrites the original expected checksum, it has normalized the corruption instead of detecting it. Keep the trust boundary clear between what the object was at commit time and what any single storage node claims today.

Multiple checksum granularities are useful. A full-object checksum validates a complete download or restore. Chunk checksums locate damage without reading or retransferring an entire multi-GB object. In an erasure-coded system, the parity and fragment layout also need validation, because one wrong fragment can affect reconstruction. A read of only one byte range may not be verifiable using a provider's full-object hash unless the service exposes checksums for the relevant chunks.

Read-time verification cannot protect cold data

Consider an object uploaded in 2021 that nobody reads until 2026. If corruption appears in 2023 and stays undetected, normal request monitoring sees nothing. A periodic scrub must proactively visit stored data, verify it against independent metadata, and detect unreadable or mismatched sectors long before the next restore.

A light scrub can examine placement and metadata consistency. A deep scrub actually reads data and validates content. Systems such as Ceph distinguish these forms. The deep operation costs bandwidth, IOPS, CPU, and cache pollution, so it must run with a schedule and resource budget. Scrubbing the most critical copies during a repair emergency can also compete with the very rebuild work that restores redundancy.

Put a number on a 100 PB scrub

Suppose we want to read all 100 PB once every 30 days. Using decimal units, 100 PB is 100,000,000,000 MB. Spread evenly over 2,592,000 seconds, that requires about 38.6 GB per second of sustained aggregate read throughput. That is an illustrative lower bound for one full logical pass, not a guarantee about the real physical bytes. Three replicas, erasure-coded fragments, retries, index reads, and geographic placement change the actual work. A seven-day full pass would require roughly 165 GB per second, before overhead. Those are cluster-wide numbers, which still have to be budgeted per rack and failure domain.

I would schedule scrubs with bounded tokens per device, rack, and region, then prioritize objects whose redundancy is low, whose last successful check is old, or whose storage devices show rising error signals. At the same time, I would prevent cold objects from being ignored forever just because hot objects continually generate higher-priority work. Track the age distribution since last validated read, not simply the aggregate count of successful scans.

Repair from evidence, not from a guess

When a fragment fails verification, quarantine it. Do not let a normal anti-entropy process silently spread its bytes to otherwise healthy copies. Identify a trusted full replica or enough independently validated erasure-coded fragments to reconstruct the expected content. Repair the damaged placement, verify the new copy against the authoritative checksum, and only then mark redundancy restored. If no valid reconstruction exists, the system must report irrecoverable corruption rather than return guessed bytes.

This interacts with normal lifecycle work. A scrub may be checking an old version that the deletion system is about to remove. It should either hold an appropriate lease or use a version and generation protocol so it does not accidentally recreate deleted data as if it were current. Conversely, a restore workflow should be able to pin the exact object version and its checksum, even if newer versions have replaced the visible key.

I would test by injecting corrupted bytes below the application layer, not merely by making a GET return an error. Flip one bit on one replica, corrupt parity while data fragments remain valid, corrupt metadata, and crash halfway through repair. Check that corruption is detected, the original expected checksum is not overwritten, readers never receive unverified bytes, and recovery survives a second crash. Measure mean detection delay and time spent with inadequate valid redundancy.

The strongest interview answer isn't 'use SHA-256' or 'run a cron job every week'. It establishes independent evidence of what the object should be, a bounded process that eventually checks cold data, and a repair protocol that restores valid copies without turning one silent error into permanent widespread corruption.

Go deeper

Google Cloud Storage documents CRC32C validation and special considerations for range reads and transcoding. Ceph has light and deep scrubbing operations, and an implementation may verify stored object metadata, replicas, or actual data bytes at different expense. A scrub frequency should be chosen using expected latent-fault rates, object criticality, available read capacity, and time-to-repair, not an arbitrary global interval. Cryptographic hashes provide stronger adversarial integrity properties but may cost more and require careful canonicalization of input bytes. Authentication of metadata and object version IDs is necessary when a malicious node, rather than accidental bit rot, is part of the threat model.

Check your reasoning

  • Capture trustworthy upload-time expected checksum independent from replicas.
  • Explain chunk checksums, full-object checks and ranged-read limitations.
  • Derive 100 PB / 30 days minimum 38.6 GB/s logical scan.
  • Quarantine corrupted copies and verify repairs against authoritative evidence.
  • Plan scrub rate, overdue-object fairness and fault-injection tests.

Common mistake: As long as a disk reports healthy SMART status, cold objects require no verification.

Which strategy detects latent corruption without redefining damaged bytes as correct?

Read the answer explanation

Scrub data under an IO budget and validate committed checksums — Latent byte corruption needs independent evidence and active periodic validation.

Apply it elsewhere

A model registry stores immutable 40 GB weights for compliance audits. Design an integrity scheme that validates full uploads, ranged reads, background cold-store checks and five-year restores.

Compare your approach

Distinguish commit-time and computed checksums, separate accidental CRC checks from cryptographic identities, quantify scrub bandwidth, bound repair competition, quarantine bad fragments, and verify repair against an independent expected value.

One more constraint

If two replicas disagree, does taking the majority byte value always prove which replica contains the originally committed content?

Quick revision

Silent corruption can exist for years if a cold object is never read. Capture a trusted expected checksum when a version is committed, verify upload and download data, and retain chunk checksums for localized repair. Run bounded background scrubs and track time since the last full validation. Quarantine bad fragments, reconstruct from independently validated copies, and recheck the repair before declaring success. For 100 PB in 30 days, even one logical full scan averages about 38.6 GB/s across the cluster, before redundancy and retry overhead.

References