TL;DR: Distributing UPI payment writes does not create one trustworthy ledger. A production-grade benchmark must combine canonical identity, idempotent lifecycle processing, and continuous reconciliation with throughput, availability, and tail-latency tests.
Key Takeaways: - A shard key routes data. It does not define payment truth. - Exactly-once delivery is the wrong goal. Exactly-once monetary effect is the right one. - A useful benchmark attacks delayed, duplicate, reordered, and missing events. It must then prove every unmatched payment is explainable.
A UPI Sharding Benchmark Can Green-Light a Broken Ledger

Two placement strategies expose broken reconciliation even when distribution and throughput look sound. The lesson is uncomfortable: distributing the ledger is easier than defining one trustworthy payment truth.
Evaluate both strategies against the same complete payment lifecycle corpus. Treat the result as controlled benchmark evidence, not as a named bank’s production result.
No throughput result erases an unexplained debit, credit, reversal, or settlement mismatch. Fast payment speed does not make an unprovable payment trustworthy.
But where should each event live without making reconciliation harder?
Define the unit under test
A benchmark must test a complete payment lifecycle: debit, beneficiary credit, any applicable reversal, and settlement. A single ledger row or API request proves only a fragment.
Throughput, availability, and tail latency still matter. Correctness and recoverability must sit beside them, not below them.
A green dashboard cannot certify an unexplained balance. It shows only that the system processed the request it was watching.
The stakes are larger. The NPCI-BCG UPI report provides market context, not benchmark evidence.
That market context raises a sharper test: which placement strategies expose the most reconciliation blind spots?
Two archetypes, one missing truth
A benchmark can compare two clearly labeled designs: - Transaction-ID hash routing maps each transaction ID to a shard. - Region-first routing sends a payment to a region-owned stack.
Neither placement creates a global source of truth. One chooses where records live. Identity and reconciliation decide what those records mean.
The payment ledger sharding guide covers the placement choice. The database sharding benchmark must test lifecycle outcomes, not only row placement. This is the audit-surface trap described in Sharding cuts cost, but expands your audit surface.
To understand why placement complicates reconciliation, separate what each strategy optimized from what reconciliation requires.
Which design creates fewer blind spots when lifecycle events cross shard and region boundaries?
Why Hash and Region Sharding Complicate Reconciliation
Placement solves the hot path. It does not solve the ledger.
Strategy one: transaction-ID hash routing
Transaction ID routing optimizes stable point lookups and spreads keys across shards. It gives every request a predictable home.
Reconciliation groups records by transaction reference, remitter, beneficiary, settlement batch, or time window. These business groups cut across hash boundaries.
Imagine a debit accepted in one event and a beneficiary credit recorded in another. Both later join a settlement batch spanning many shards. A global reconciler must touch every shard and needs a cross-shard join for one payment.
That changes the problem. A distributed write becomes a full-corpus read. One payment’s lifecycle remains split across physical boundaries.
Google Cloud’s sharding overview describes key-based and hash routing to a relevant shard. That mechanism does not establish lifecycle correctness or cross-shard reconciliation behavior.
But a predictable lookup home solves only part of the lifecycle. Where does the next event land when ownership changes?
Strategy two: region-first routing
Region-first routing optimizes local writes and lowers cross-region traffic for local payment paths. A remitter’s debit and a beneficiary’s credit stay within one region-owned stack.
But cross-region payment lifecycles, settlement batches, and reversals depend on different ingestion watermarks and event orders. The result is two versions of “now.”
Region A accepts a debit and closes its local window. Region B receives the credit later. Each local view looks plausible. The global lifecycle does not.
This is why multi-region reconciliation needs explicit watermarks, checkpoints, and late-event handling. Local completeness is not global completeness.
The hard case is a failure that leaves neither region with a complete view. Without a shared lifecycle boundary, neither local view can prove which outcome is final.
Separate outages from ledger mismatches
Operational failure and ledger mismatch are different classes: - Network failures interrupt communication. - Bank server failures interrupt service. - Timeouts leave the caller unsure. - Slow beneficiary-bank responses extend the lifecycle. - Reconciliation errors expose disagreement between recorded and expected outcomes.
These events cannot share one break queue. That queue hides whether money moved, service failed, or the books disagree.
The concrete timing test is an uncompleted beneficiary credit. Under the RBI framework, a failure that persists through T+1 triggers automatic reversal.
A reconciler must distinguish a legitimate pending state from a deadline breach. It must not treat every gap as an error.
Neither strategy guarantees the required invariant: the same payment must resolve to the same deterministic lifecycle state. This must hold regardless of which shard or region processed it.
If changing the shard key cannot guarantee a canonical result, the design must change one layer deeper.
Separate Payment Identity from Physical Shard Ownership
Identity must hold even when placement changes. That makes it a separate layer from shard ownership.
Establish canonical identity
Every payment needs an immutable global `payment_id`. Every state transition needs a unique `event_id`.
A per-payment sequence expresses order within that payment. It avoids pretending the system needs a global total order.
Two unrelated payments progress concurrently. Their sequences remain independent. The debit, credit, reversal, and settlement events for one payment must remain ordered.
This is the deeper problem behind event-sourced ledgers that pass tests but still fail reconciliation. A durable event log does not automatically provide a correct payment state.
How can a shard enforce that identity without slowing the write path?
Make the local write atomic
One shard-local transaction updates payment state, appends the lifecycle event, and records the outbox entry. All three commit together.
The outbox relay then propagates the event asynchronously with at-least-once delivery. Delivery repeats when networks, queues, or consumers fail.
The wrong goal is exactly-once delivery across regions. That goal encourages fragile assumptions about networks and brokers.
The right goal is exactly-once monetary effect. Consumers deduplicate by `event_id` and apply each transition idempotently. The same debit event must never create a second debit.
The idempotent event processing pattern makes retries safe. The payment state machine must treat a repeated transition as a no-op and reject an illegal one. Otherwise, a retry becomes a monetary incident.
But safe retries do not tell an operator which payment is still wrong. Where should that view live?
Build a reconciliation projection
Build a projection from the canonical lifecycle for payment, account, corridor, and settlement queries. This avoids repeatedly joining every physical shard.
The projection is a rebuildable view, not a second authority over ledger truth. Reconcile it at three levels: - Source events against the materialized projection. - Shard checkpoints against the canonical lifecycle. - Economic invariants across debits, credits, reversals, fees, and settlement.
Use per-region checkpoints and watermarks. A late event must reopen the affected reconciliation window instead of being discarded after a shard reports completion.
Avoid global two-phase commit across shards. Local atomicity, durable event propagation, idempotent consumers, and continuous reconciliation provide a practical consistency model.
That architecture earns trust only if the benchmark deliberately attacks its weak points.
Benchmark Failure Modes, Not Synthetic CRUD

CRUD benchmarks test ordinary writes. Payment systems fail on delayed, duplicated, reordered, and missing events.
Publish the corpus and methodology
The test corpus should contain complete payment lifecycles. Publish the conditions needed to reproduce them: - Schema version and deterministic seed. - Retention period and retry policy. - Region topology and event mix. - Privacy treatment for payment records.
The event mix must include normal debits and credits. It must also include timeouts, delayed and out-of-order events, duplicate deliveries, reversals, and settlement records.
A workload containing only successful writes measures the easy path. It does not measure the system buyers depend on.
Without a shared contract, two strategies can pass for different reasons.
Publish the minimum data contract
Each `payment_events` record should carry: - `payment_id`, `event_id`, and `event_type`. - `payment_sequence`, `occurred_at`, and `ingested_at`. - `source_region`, `reversal_of`, and `payload_hash`.
Enforce a unique `event_id` and a unique `(payment_id, payment_sequence)` pair. These constraints detect duplicate delivery and sequence conflicts early.
One shard-local transaction updates `payment_state`, inserts the lifecycle event, and inserts the outbox record before committing. Replaying the outbox rebuilds state without creating a second monetary effect.
The next challenge is making both placement strategies answer the same test.
Run the same test across both strategies
Both strategies must face the same corpus, configuration, retry budget, retention window, and fault schedule. Otherwise, the comparison measures different systems.
Maintain a centralized reference implementation as a differential correctness oracle. The distributed result must not validate itself.
Write performance belongs to the distributed platform. Expected economic outcomes belong to the reference model. That separation turns “the system looks healthy” into a testable claim.
Healthy metrics alone still hide broken lifecycle effects. Which faults should expose them?
Inject realistic faults
A reproducible benchmark harness should attack the architecture with: - Duplicate, delayed, reordered, and missing events. - Consumer crashes after commit. - Regional isolation and shard failover. - Clock skew and projection rebuilds. - Outbox replay and consumer restart.
Measure throughput and p50, p95, and p99 commit and acknowledgement latency. Also record reconciliation completeness, false-break rate, unmatched-payment age, and T+1 classification.
Track cross-shard amplification, duplicate monetary effects, repair time, recovery point, recovery time, and infrastructure cost.
This is where tail-latency testing becomes a business test. A slow commit that misses a reversal deadline is not merely a slow commit.
Define pass conditions as invariants, not promotional numbers: - No duplicate monetary effect. - No unexplained economic imbalance. - Every unmatched payment is classified as pending, expected-late, reversed, or actionable.
Publish the schema, fixed workload seed, documented fault-injection controls, replay procedure, and machine-readable result format. Another team must be able to challenge the result.
Passing the harness is still not the same as operating the system at 3:00 a.m.
Which failures must operators handle after the benchmark ends?
Turn Reconciliation into a 3 A.M. Operating System
Production readiness starts after the benchmark ends. Operators need a system that stays explainable at 3:00 a.m.
Run reconciliation continuously
Compare source checkpoints, canonical projections, shard summaries, and settlement totals. Use explicit per-region watermarks and grace windows based on business rules.
A beneficiary response expected after the current cutoff remains pending. A response arriving after the applicable reversal deadline needs a breach classification.
Arbitrary batch cutoffs hide both cases. They make clean reports while leaving real exceptions unresolved.
The reconciliation runbook should define who acts, which evidence they inspect, and how they prove the repair worked.
A runbook helps only when each exception has a safe, repeatable repair.
Build an exception workflow
Assign stable reason codes for missing events, duplicates, out-of-order delivery, terminal-state conflicts, late reversals, and settlement mismatches.
Route every exception to an idempotent repair process. A repair should append a linked corrective event, not silently edit the original ledger history.
Otherwise, teams lose the ability to explain what changed. The event-driven pattern described in Why event-driven banking wins demos and fails in production repeats here.
A repair trail matters only if one audit view can expose it.
Make every payment explainable
Expose the payment’s event sequence, source shard and region, and state transitions. Add the settlement batch, reconciliation result, and repair history to one traceable audit view.
Protect that view with least-privilege access, encryption, immutable audit records, and role-based break handling. The reconciliation tool must not become an ungoverned shadow administration database.
A support engineer should not need to ask which database answered last. The answer should already be linked to the payment’s lifecycle evidence.
The final proof comes when teams rehearse this view under real failure conditions.
Rehearse the runbook
Rehearse delayed bank responses, reversal deadlines, shard failover, regional partition, projection corruption, and complete rebuild from the event log.
Roll out through a shadow projection, historical backfill, parallel verification, controlled ownership cutover, and a retained rollback path. Do not introduce dual writes as a second source of truth.
Deployment planning belongs beside this operating model, not inside the benchmark.
Which controls must be visible before the CTO approves production?
What Changes When Every Payment Has One Explainable Truth
Write paths scale without global transactions. Mismatches are isolated to a specific lifecycle event. Failover and replay no longer depend on whichever shard answered last.
This changes the CTO’s approval checklist: - Canonical payment and event identifiers. - Per-payment sequencing. - Idempotent consumers. - Durable outboxes. - Regional watermarks and checkpoints. - Reason-coded exceptions. - Economic-invariant checks. - Immutable audit trails. - Rehearsed recovery procedures.
The shard key serves the hot path. The reconciliation plane, failure semantics, observability, and operating ownership determine whether the platform is production-ready.
The benchmark question should therefore be:
Can the system prove what happened to every payment under failure?
Not: How many writes per second can it sustain?
The next question is practical: what should a UPI sharding benchmark actually measure?
Frequently Asked Questions
Q: What should a UPI sharding benchmark measure?
A: A UPI sharding benchmark should measure more than insert throughput or point-read latency. It should validate lifecycle completeness, duplicate monetary effects, and cross-shard reconciliation accuracy. It should also cover recovery from delayed or duplicated events, plus the age and reason code for every unmatched payment.
Q: Which shard key works best for a payment ledger?
A: No shard key is universally best. Payment or transaction IDs improve key stability, but they do not reduce lifecycle reconciliation work. Region-first routing lowers cross-region traffic for local paths, but it does not remove cross-region settlement and reversal dependencies.
Compare both under the same correctness and fault conditions. The deciding result is proof of correctness under failure.
About the author
Mayank Singh is a software developer at Levitation Infotech, where he builds web and AI-powered applications across the company’s fintech, healthcare, and enterprise projects.
