pattern

Offload Freshness Contract

also called As-At Read Contract, Published Staleness Budget

An explicit published staleness budget for a read copy that serves traffic taken off a core system, enforced by the copy itself, so that silently stale answers become visible failures rather than wrong decisions.

mainframecdcoffloadstalenesscorrectness

A mainframe offload moves read traffic onto a modern store fed by change capture. It works: the core system's load falls, new development stops queueing behind it, and the cost linked to core capacity comes down.

Then month-end close posts a dense batch, capture lag climbs to forty minutes, and the offload serves pre-close balances to everybody. Nothing errors. The offload is up, it is fast, and it is wrong, which no ordinary dashboard distinguishes from healthy. The first visible symptom is agents telling customers the app is broken. The serious one arrives later, when a process reads a stale balance from the offload and then writes a decision back to the core.

The pattern is to stop treating freshness as an operational property and make it a contract the offload publishes and enforces on itself.

Why it matters

Offloading is the highest-value early move in most core-system modernisations, because it relieves pressure without touching the system nobody dares change. Its characteristic failure is not unavailability but silent divergence, and silent divergence is the failure class that turns a freshness problem into a correctness problem.

The distinction that carries the pattern: a stale display is an inconvenience; a stale input to a write decision is a financial error. The contract exists to make sure those two never share a code path.

Implementation patterns

  • Expose lag as a first-class value the offload reports about itself, and stamp every response with the time it is accurate as at.
  • Classify every read. Display and browse tolerate lag and are labelled. Anything feeding a write decision — a limit check, a fee waiver, an authorisation — routes to the core system or is refused. This single rule prevents the expensive failure.
  • Shed to a declared degraded mode when lag exceeds the budget, rather than continuing to serve silently. A visible degradation is actionable; a silent one is not.
  • Declare batch windows to the offload in advance, so elevated lag during a close is expected behaviour and not an alert nobody can act on.
  • Reconcile on a schedule, comparing checksums of normalised values rather than row counts, because a capture stream that has silently stopped looks exactly like a period in which nothing changed.
  • Set the budget from a consumer requirement, in seconds, and write down which consumer set it — for example 30 seconds for displayed balances and 0 seconds for anything feeding an authorisation. A budget with no named consumer will be argued down the first time it is inconvenient.

Industry example

The mechanics are visible in any change-capture deployment in production where a batch source feeds a streaming target. The general shape has been documented in the data-engineering literature since roughly 2015: apply-side throughput, not capture-side reading, is the usual bottleneck, and lag under a batch burst climbs linearly rather than spiking, which is the signature that distinguishes sustained overload from a blip.

The economics that make offload attractive are equally documented for core-system estates, where capacity-linked licensing means that moving read traffic reduces cost in a way that moving compute between commodity servers does not. The same property that makes offload valuable — the core system does not slow down when the copy falls behind — is exactly what makes lag unbounded, because there is no backpressure from a replica to its source.

Failure scenarios

  • Lag climbs during a batch close and every consumer silently receives pre-close state for the duration.
  • A read-then-write decision made on stale data, accepted by the core, producing a financial error with no error message anywhere.
  • A stopped capture stream that presents as a quiet period, discovered by reconciliation days later or by a customer immediately.
  • Two interpretations of the same field, because the offload reimplements the core's business rules and drifts from them.
  • Capacity sized for the burst, which costs peak apply throughput every day of the month and still does not bound lag when the burst is larger than planned.

Trade-offs

Offloading cuts load and capacity-linked cost on the core system and unblocks teams who were queueing behind it. It pays with a second source of truth, a reconciliation obligation, a pipeline to operate, and a new class of correctness bug that did not exist when there was one copy.

The contract itself has a narrower trade: enforcing a staleness budget means refusing or degrading some requests that would have been answered, so availability as measured by "did we return something" falls, while correctness rises. That is usually the right direction, and it needs to be agreed with the business before the first incident rather than during it.

When not to use it

When every consumer tolerates a day, do not build a stream at all. A nightly extract taken after the close is cheaper to operate, has no lag concept to get wrong, and fails loudly: the file is either yesterday's or it is missing. A continuous capture pipeline is justified only when a named consumer's requirement is measured in seconds, and "the business would like it fresher" is not such a requirement.

Equally, if the core system can carry the read traffic, keep the single copy. The offload's whole cost is the existence of a second truth, and taking that on to relieve load that is not actually binding is complexity bought with no payment received.

Interview question

Q: Your offload has been serving customer balances happily for six months. Tonight is the annual close. Walk me through what your monitoring will show, what your users will see, and what in the design decides whether this is a support ticket or a regulatory incident.

What a strong answer covers: lag climbing linearly under a sustained batch burst while every health signal stays green · the display-versus-decision classification as the thing that separates inconvenience from financial error · why adding apply capacity is a bet and a gate is bounded, given there is no backpressure to the source · declaring the close window in advance so the alert is meaningful · reconciliation by checksum rather than count to catch a stopped stream · and the case for a nightly extract instead, when no consumer needs seconds.

Quick check

Quiz: What must a read offload publish about itself, and which class of read must never be served from it? Its own lag, with an "as at" stamp on every response; and any read that feeds a write decision back into the core system must go to the core or be refused.

Flashcard: Why is extra capacity the wrong answer to change-capture lag during a batch close? — Because there is no backpressure from a replica to its source, so lag is unbounded whenever the burst exceeds the plan; sizing for peak costs peak throughput every day of the month and still does not bound it, whereas a published staleness gate does.