Why an exchange's limit system fails under peak load
The limit system of an exchange is normally a single source of truth: thresholds per customer, intake channel, and operation, a counter in transactional storage, and a check before confirming a request.
It breaks not on threshold values but on consistency: as soon as requests come from several points and are processed in parallel, counters diverge, and operations pass above the threshold.
Limit accounting by channel is more often done separately: the website, partner integrations, and the operator terminal write to their own tables, while the summary is assembled on a schedule with a delay of minutes.
During this time, the customer submits a second request — the check sees the old value and lets both through.
Parallel requests from one customer produce the same effect even in a single storage: reads and writes are not serialized, two operations read the same balance and both debit it.
A separate source of discrepancies is manual edits in the operator panel: removing a block or raising a threshold is applied to the profile, but not to the accumulated counter and without an entry in the audit log.
After that, disputed exchange operations grow: the customer contests a refusal, and the actual picture can no longer be restored from logs. A discrepancy of a couple of percent of requests per day means hours of manual investigation and lost inquiries.
Requirements for thresholds and source-of-funds checks are set by FATF recommendations, but counter consistency remains an engineering task.
We analyze how this is addressed: by reserving the limit during processing, idempotent requests, and an audit from which the state can be restored at any point in time.
What automatic control of limits and verification levels provides
Limit rules live in the core, not in each channel. Customer verification levels turn into a set of thresholds: total volume per period, number of operations, available exchange directions.
Automatic limit control calculates accumulation from a single journal, so switching between the web portal, mobile application, and programmatic interface does not reset the balance — the unified counter across channels is always the same.
Each operation receives an idempotency key, and each accrual receives a link to the original event.
Resending a request on the customer side or a duplicate from the payment provider does not create a second credit: the system sees an already applied event and returns the previous result.
This eliminates an entire class of failures — 'double crediting' ceases to be an incident and becomes impossible by design.
The time to investigate a disputed operation is determined by the fact that the journal stores a snapshot of the rules in effect at the time it was performed.
The reviewer sees which customer verification level was active, which threshold was applied, and why the operation passed or was stopped — without reconstructing context from logs of different services.
- Manual investigations. The share of operations that an employee opens manually falls due to automatic stopping at the threshold and a clear refusal reason in the interface.
- Disputed operations. Investigation is based on a snapshot of the rules, not on correspondence with support: a typical case is closed in minutes instead of hours of searching through logs.
- Channel reconciliation. Discrepancies between the web portal, application, and programmatic interface disappear: the source of accumulation is the same.
Customer verification levels are updated automatically based on provider data — when integrated with Sumsub, a status change immediately changes thresholds, without manual editing in the accounting system. A level downgrade tightens limits instantly, while an upgrade opens new exchange directions.
Accounting methods: comparison of approaches and limitations
Limit accounting is rarely moved to a separate component at the start — first, the rules live in the operator panel or inside the exchange service itself.
The discrepancy surfaces later: parallel transactions calculate the balance from different data snapshots, and there is no way to restore the picture — the history of changes is not recorded anywhere.
The choice of approach determines two things: how quickly you can change a rule and how you prove its enforcement during an investigation. Below are the options that are actually chosen between during implementation.
| Option | When it fits | Limitations |
|---|---|---|
| Manual rules in the panel | Few operators, low volume, rules change rarely | Edits are not versioned, the balance diverges during concurrent operations, there is no decision history |
| Limits inside the exchange service | One intake channel, limits are simple and static | Accounting logic is mixed with transaction calculations: changing a rule requires redeploying the exchange, some scenarios cannot be covered |
| Dedicated limit accounting service with an operation journal | Several channels, rules depend on customer level and currency | A separate environment, migration of accumulated counters, reconciliation with the source of transactions is needed |
| External customer verification provider | Fast basic identification is needed without in-house expertise | The provider's policy does not cover internal limits, data goes to a third party, integration with accounting is weak |
| Hybrid verification scheme | Both external verification and own rules on top of it are needed | Harder to debug: two sources require regular reconciliation |
In practice, the last option is chosen more often: an external customer verification provider covers basic identification, while a dedicated limit accounting service keeps the exchange's operation journal and applies rules on top of the verification result.
Reconciliation becomes a daily procedure, and a discrepancy becomes a reason to reject an operation rather than investigate after the fact.
Work stages: from analyzing request flows to handing over regulations
Each stage ends with an artifact that can be verified: a flow map, a threshold table, a storage schema, a set of tests. This way, implementing a limit system does not stretch over months and does not turn into 'by eye' edits after the first incidents.
- Audit of request flows. We capture a map of request movement: which channels, which fields arrive, where a human makes the decision, where automation does. We separately record the points where the limit is checked now and the places where the check is bypassed — for example, on resubmission or when the payment method changes.
- Threshold model. We break limits down along axes: customer verification level, operation amount and frequency, payment method, region, and device. For each threshold, we describe the owner, behavior when exceeded, and reset condition.
- State storage schema. Counters per window, customer status history, keys protecting against double limit debiting, decision journal — from it, one can later see why a request passed automatically or went to manual investigation.
- Customer check setup. We link verification levels to thresholds, define escalation rules and manual queue investigation with a response time. Thresholds change via configuration, not a code release.
- Failure run-through. We test not only the happy path: exceeding, parallel requests, resubmission, external service unavailability, status rollback. The goal is for the limit not to 'stick' and not be bypassed during a failure.
- Handover and support training. We provide regulations, a decision tree, and a dashboard with the share of automatic refusals and manual investigations, and conduct shift training.
After handover, threshold changes remain manageable: behavior is predictable, and limit decisions are reproducible.
Delivery composition: configurations, schemas, regulations, documentation
Delivery is completed not by launch, but by what remains in the customer's team's hands after handover. Below is the kit with which you can change rules, investigate disputed operations, and onboard new operators without us.
- Limit configurations as a rule repository: levels by verification, daily and monthly thresholds per customer, currency pair, payment method, country, and behavior history. Each change is a separate revision with the author, rationale, and the ability to roll back to the previous version.
- Request flow schemas: from intake to final status, including manual review branches, waiting timeouts, and points where a request automatically goes to investigation. The schemas mark the places where limits and address checks are invoked.
- Operator access rights matrix: role, which operations are available, which fields are visible, what requires second confirmation. Separately — separation between shifts and escalation levels.
- Operation investigation regulation: a step-by-step procedure for a triggered limit, status discrepancies, and a customer inquiry about a stuck request. With recording of the decision, reason, and a link to the rule that triggered.
- Limit documentation: the purpose of each parameter, what it changes in system behavior, which values are considered operational, and which require approval.
- Instructions for operators — short scenarios for each common case: how to raise a threshold within authority, how to process a manual review, what to do when amount splitting is suspected.
- Change and access journal: who and when edited a rule, who viewed customer data, who confirmed a manual operation.
- Handover plan: review of the kit with the customer's team, run-through of typical scenarios on a staging environment, checkpoints for independently changing a limit and investigating an operation.
Such a kit removes the main risk — that the rules live only in the contractor's head. Describe your task: we will assemble a list for your environment and come back with an estimate and a handover plan.
Case study: how an exchange eliminated double crediting at peak
At peak, the exchange kept limits in a single field: the code read the balance, checked it, and wrote a new value.
Between the read and the write, a second request from the same customer managed to slip through — both passed the check, and the second was credited against an already exhausted limit. The discrepancy was found during reconciliation, that is, hours after the operation.
Before the changes, the share of refusals due to concurrent requests stayed around 4% of daily volume, an operator manually closed more than thirty discrepancies per shift, and a disputed operation hung for up to several hours. Peak request load only amplified the effect.
The limit stopped being a field in a table and became a separate reserve record. The transaction takes the row under a lock, checks the balance, and debits it before calling the external service — the race window is closed at the storage level, not at the handler code level.
A request arrives with an idempotency key: a repeat does not create a second reserve but returns the result of the first. Cancellation does not delete the record but adds a compensating one — the operation history remains auditable.
The storage was built on PostgreSQL: a unique index on the request key plus row locking for the reserve. Manual adjustments remained only for refunds due to external reasons.
Metrics before and after: share of refusals due to concurrent requests — 4% versus 0.1%, manual adjustments per shift — 34 versus 2, time to close a disputed operation — hours versus 10 minutes. At the same time, peak request load tripled — no queues or repeat crediting appeared.
How does document-based verification differ from behavioral verification?
Document-based verification answers the question 'who is this person': it matches the document with a selfie, filters out forgery, checks age and sanctions lists. The result is deterministic — a legally significant trail remains at the output.
But the document describes the state at entry and says nothing about how the customer will behave afterward.
Behavioral verification looks at actions: operation speed, splitting amounts around limit thresholds, the number of linked addresses, recurring 'device — network' combinations across different accounts.
It catches a network of straw men with genuine passports — something a document will not show. The price for this is sensitivity to context: a corporate VPN gives the same signal as an attempt to bypass.
This is where false positives in checks appear. A rule like 'frequently changes the withdrawal address' without calibration against historical data flags an active trader the same way as someone who splits limits.
If the behavioral layer works as a hard block, a noticeable share of triggers falls on bona fide customers — that means lost turnover and support load.
That is why levels are separated by role. Documents are the base layer: without a passed check, the limit is zero. Behavior is an add-on that does not block but manages thresholds: increased risk lowers the daily limit and sends the operation to manual investigation.
Auto-blocking is enabled only when two independent signals coincide — for example, a discrepancy in the document and a link to an already closed account.
The threshold for external services is configured separately: Sumsub and similar services return a risk score, and we tie it to limit levels rather than to a 'yes or no' answer. A bona fide customer passes verification in minutes, while analyst attention goes to real overlaps.
Common technical questions about operation accounting and checks
Doubts about the limit system and operation accounting arise not during design but at the interface with operations: rules change on the fly, a customer gains a second channel, an external check responds with a delay. Below is how these cases are covered in the configuration.
What happens if the rules change while requests are open?
Each request references the version of the rules in effect at the time it was created.
New conditions apply to new requests, while already open ones are completed under the previous revision — there is no retroactive recalculation, and the journal shows which version the decision was made under.
The customer has several channels — are limits calculated together?
The counter is shared per customer, not per channel: attributes are linked into one profile, so the threshold cannot be bypassed through a second channel.
Thresholds are set at the level of the customer, channel, or their pair — what counts as one customer is determined during setup.
Can an external customer check be connected?
Yes, a third-party verification service is integrated as a separate step and works asynchronously.
When it is unavailable, the request goes to manual investigation rather than auto-approval, and the verification result is saved together with the version of the rules under which the decision was made.
How does acceptance before launch work?
We run scenarios on a test environment: boundary amounts, repeated requests, rule changes with an open request, external service failure. Acceptance is passed when the decision journal for each request is reproducible and matches expectations.
Let's discuss the task: we'll analyze your flows and come back with an estimate
To discuss the implementation task concretely rather than using general templates, we need a snapshot of your current configuration: how requests enter the system, where limits are calculated, and what a human currently decides.
Without this, estimating timelines would be guesswork — we calculate based on your data, not averages.
- List of request intake channels — API, web form, bot, requests from managers: for each, it is important where the limit is calculated and how the customer identifier is passed.
- Current threshold rules — by which attribute volume is cut off: amount per period, number of operations, verification level, country, payment method; separately — where rules conflict.
- Manual intervention points — what decisions an operator makes, for what reason, and what happens when they are not on shift.
- Disputed scenarios — splitting an amount into several operations, changing payment details, linked accounts: these most often break automation.
- Load priorities — peak check frequency, allowable response delay, and the share of operations that must pass without a human.
- Accesses and constraints — test environment, provider sandbox, requirements for storing verification logs.
With this set, we come back with an estimate and work plan: a check scheme, a priority-ordered task queue, control points, and a rollout sequence without stopping the exchange.
If some data is restricted — describe it in words; that will be enough for the first version of the architecture.







