The Scaling Approach We Did Not Take, and What Refusing It Costs Us

The approach described here is one we deliberately did not adopt, and the trade runs against us in at least one direction.

The problem it solves

Putting identifier operations directly on a chain is expensive. Every creation, key rotation and revocation is a transaction competing for the same block space as everything else, and identity operations are frequent and individually low-value.

So a well-known answer is to batch them. Thousands of operations are bundled into a file, the file goes somewhere cheap, and only a compact commitment to it goes on chain. The chain provides ordering and immutability; the bulk data lives elsewhere.

It is an elegant design and it is used in production by serious projects.

What it costs

Resolution becomes a multi-step process with more failure modes. A resolver reads the chain commitment, fetches the batch file from wherever it lives, replays operations in order, and computes current state. Each of those steps is a place the answer can be slow, stale or unavailable.

And availability of the bulk data becomes a separate concern from the chain. The commitment is immutable; the file it points at lives in a system with its own guarantees, and "the anchor is permanent and the content is retrievable" are two claims rather than one.

What we did instead, and what it costs us

Every one of our identifier operations is a transaction our own validator set finalises directly. No batching layer, no external file, no replay to reconstruct state.

The benefit is that resolution is one lookup against finalised state. No fetching, no replay, and no dependency on a second availability system.

At real volume it is the cost the batching design exists to avoid, and we would be paying it.

So this is a trade we have made without yet experiencing the conditions that make it expensive, which is an honest thing to say about it and not a flattering one.

The deeper trade underneath

The batching approach lets a method anchor to somebody else's chain, inheriting that chain's security and neutrality without operating one.

We operate our own, which means we inherit nothing and are responsible for everything. Our identifiers resolve because we run the infrastructure. If we stop, resolution stops, which is written up separately and is the most important sentence about our method.

A project using the batching approach on an established chain has a better answer to that question than we do. That is a real advantage of the road we did not take, and it is worth stating plainly rather than listing only the costs of the alternative.

Why we chose as we did

Because revocation timing mattered more to us than transaction cost.

When an operation is a directly finalised transaction, a revocation takes effect when the block commits. When operations are batched, they take effect when the batch is anchored and resolvers have replayed it, which is a longer and less predictable window.

For a system whose central claim is that a credential can be withdrawn, that window is the thing being sold. We chose the design where it is shortest and accepted the cost structure that comes with it.

What is already done is exactly that: operations finalised directly, resolution as a single lookup.

What would change this position, concretely: sustained operation volume high enough that per-transaction cost dominates, or a customer whose requirement is anchoring to a chain we do not run. Either one makes the batching design the better answer, and we would rather adopt it than defend the choice past its usefulness.

What to ask any identifier method about scaling

"Is an operation a transaction, or is it batched?" This single answer determines cost, revocation latency and how many systems have to be available for resolution to work.

"How long between an operation and every resolver seeing it?" Batching lengthens this, and a vendor should know the number.

"What chain do you anchor to, and do you operate it?" Operating your own means inheriting no neutrality from anyone.

"What happens to resolution if the bulk storage is unavailable?" Only applies to batched designs, and it is the question that separates the careful implementations from the rest.

Where this leaves a decision

If you need identifiers anchored to a chain you already trust and operated by nobody in particular, the batching approach on an established network is a better fit than we are, and we would rather point at it than argue.

Keep reading

The Scaling Approach We Did Not Take, and What Refusing It Costs Us · Solidus