External Consistency Explained: Spanner, TrueTime, and Commit Wait

Aug 30

External consistency means transactions behave as if they executed serially in an order that respects real time. If transaction A finishes before B starts, that serial order must place A before B. Overlapping transactions do not have the same real-time ordering constraint.

Google Spanner documents this guarantee through TrueTime and external consistency. The design question is where a product needs this ordering and what latency it can afford.

External consistency provides that guarantee. It is powerful—and it has a latency, replication, and operational cost.

The invariant is:

Once a committed result is acknowledged, no later transaction may be ordered before it.

TrueTime represents uncertainty honestly

Serializable transactions alone can admit a serial order that differs from real time. External consistency adds the real-time requirement, commonly called strict serializability. Linearizability expresses a related real-time condition for individual operations; do not assume that a linearizable register automatically provides multi-object transactions.

Google Spanner’s TrueTime API returns an interval in which absolute time is guaranteed to lie, rather than pretending a machine clock is exact. Spanner assigns a commit timestamp and waits until the uncertainty interval has passed before exposing the commit. This “commit wait” ensures the timestamp is in the past when the client receives success, preserving real-time order.

choose commit timestamp s
replicate and commit transaction at s
wait until TT.after(s)
acknowledge success

TrueTime is not merely synchronized clocks, and clocks alone do not provide transaction isolation. Spanner also uses concurrency control, replication, and MVCC. TrueTime connects the serialization order to externally observed time.

The guarantee changes application design

With external consistency, a service can write a policy, return success, and know that a later strong read will not observe an older world that excludes that policy. Cross-region workflows become easier to reason about because the database behaves like one serial machine with real-time ordering.

But not every read needs the newest state. Spanner supports timestamp-bound reads, including stale reads, which can reduce latency or move work closer to replicas. The architectural move is to classify reads by correctness need:

ReadRequired semantics
confirm a payment immediately after commitstrong, read-your-write path
authorize using a newly revoked credentialstrong or tightly bounded staleness
render yesterday’s analyticsstale snapshot is acceptable
build a historical reportexact timestamp or bounded-staleness read

Paying the strongest consistency cost for every analytics query wastes latency and capacity. Using stale reads for authorization silently weakens the security model.

Geography remains physics

A synchronous replicated write must communicate with enough replicas to commit. Leader placement and quorum geography shape latency. TrueTime reduces some coordination needs for timestamp assignment and supports efficient strong reads, but it does not remove wide-area round trips or the speed of light.

Before selecting a multi-region database configuration, place the write leader near the dominant writers, model cross-region quorum latency, and quantify recovery objectives. A globally distributed logo on an architecture diagram is not evidence of a globally low-latency write path.

Model an application-level ordering token

Even with a strongly ordered database, messages and caches can arrive out of order. Carry a monotonic commit version or timestamp across derived systems and reject regressions:

function applyPolicy(current: Policy, incoming: Policy) {
  if (incoming.commitVersion <= current.commitVersion)
    return current
  return incoming
}

The token does not manufacture consistency. It allows downstream components to preserve the database’s ordering instead of overwriting new state with delayed old events.

Common mistakes

  1. Treating “serializable” and “external consistency” as synonyms; serializability alone need not respect real-time order.
  2. Assuming global replication means local write latency everywhere.
  3. Using wall-clock timestamps from ordinary application hosts as ordering authority.
  4. Mixing strong database writes with unordered cache invalidation and declaring the whole system strongly consistent.
  5. Selecting the guarantee before identifying which business invariant requires it.

The CTO decision

Specify consistency per decision, not per product. If real-time transaction order eliminates dangerous application reconciliation, external consistency may justify its cost. If a workflow can tolerate bounded staleness, use that freedom deliberately. Measure end-to-end correctness through caches, queues, and read paths—not only the database contract.

The strongest system is not the one with the strongest setting. It is the one whose consistency cost matches the invariant it protects.

References

>