Scalability Strategies
In this page you will find the strategies to ensure your Midaz deployment scales effectively for high transaction volumes, multi-currency and multi-entity operations, and remains performant.
Midaz is designed to be highly scalable and to support banks as they grow to large volumes of accounts and transactions. However, how you structure and use Midaz can impact performance and scalability.
Structuring Entities for High Transaction Volumes
Partition by Organizations/Ledgers/Accounts
If your bank expects extremely high volumes (millions of transactions per day, tens of millions of accounts), consider partitioning workloads across multiple accounts, ledgers or even organizations. For example, you might split customers across ledgers by last name initials, or have separate ledgers per region.
Each ledger in Midaz can be thought of as an isolated book – operations within a ledger are handled together. By splitting load, you ensure no single ledger’s database becomes a bottleneck.
Midaz’s architecture supports this kind of scaling out since each ledger’s operations could potentially be handled by separate instances or database partitions.
Lock-oriented Operation
Note concurrent transactions are locked at the account level, under each ledger/organization. This method avoids any kind of "race condition" to affect the same account, implementing a FIFO (first in, first out) queue to process transactions.
The @external
account is implemented with no-lock, which means concurrent transactions can happen at this account but are restricted by the atomicity of the transaction itself.
Horizontal Scaling of Services
Leverage the fact Midaz is built with a microservices architecture, although you can start operating small. This means different components (transaction processing, querying, etc.) can be scaled independently.
Under high load, ensure you run multiple instances of the transaction processing service behind a load balancer and leveraging K8S pods scaling.
The modular design allows scaling specific services without affecting others. For instance, if read requests (balance inquiries) grow, scale out the query service, whereas if write volume (transactions) grows, allocate more resources to the command service.
CQRS and Read Replicas
Midaz uses CQRS (Command Query Responsibility Segregation) to separate write and read operations. This allows you to optimize each side independently.
Use this to your advantage by perhaps directing heavy reporting or query loads to read replicas or services optimized for querying, while the write path remains lean and optimized for fast transaction commits.
The system is designed so that reads do not lock or slow down writes and vice versa, so by following this pattern, you can achieve high throughput.
Batching and N:N Transactions
When possible, batch multiple operations into a single transaction (if logically related) to reduce overhead. Also utilize N:N transactions for scenarios like mass payouts or aggregations.
Handling 100 debits and 100 credits in one large transaction can often be more efficient than 100 separate smaller transactions, as long as they are part of one logical operation set.
Midaz is built to handle such complex transactions in a scalable way.
Monitoring and Scaling Iteratively
Implement monitoring on key metrics: transaction latency, throughput, CPU/memory of Midaz services, database performance, and so on.
Midaz’s observability tools (OpenTelemetry + Grafana) are available as part of the open source offering or your infrastructure monitoring should be used to identify when to scale.
Scale out (or up) proactively when nearing thresholds. Because Midaz is open-source and modular, you have flexibility to deploy it in a distributed manner to handle growth.
Handling Multi-Currency and Multi-Entity Operations
Multi-Currency Strategies
Midaz inherently supports multi-currency by using separate assets for each currency. To scale this:
-
Ensure you have all needed currency assets set up, and consider any currency-specific logic (like rounding or conversion rates) in your integration layer.
-
If currency conversion transactions are common (e.g., forex trading or currency exchange for customers), treat those as distinct transaction types and possibly segregate them in a separate module or service that interfaces with Midaz - maybe using our Exchange Engine plugin. Midaz will record the debits and credits (one currency out, another in), but you might need an external FX rate service.
-
There's generally no need for separate ledgers per currency unless required by policy; Midaz can handle accounts of different currencies in one ledger. However, be mindful of reporting needs – you may need to report ledger totals per currency to avoid mixing values. Using the chart-of-accounts, you could segregate accounts by currency categories for easy aggregation.
-
Volume: If one currency (say your local currency) has the bulk of transactions, while others are minor, the ledger can still handle all; but if you find one currency's operations dominating, it’s fine to keep all in one ledger since partitioning by currency might complicate cross-currency transfers.
Multiple Entities (Consolidation and Separation)
For banks operating in multiple countries or with multiple legal entities:
- Use the organization hierarchy to separate entities. Each entity (organization) can have its own base currency, local assets, and ledgers. This ensures data (and regulations like data residency, sharding the databases) are confined as needed.
- For inter-company or inter-entity transfers, you'll likely treat them as external transactions from one org’s ledger to another’s. This might involve an external clearing account or an intermediary system. Midaz doesn’t automatically transfer between organizations, but you can withdraw from one (credit its external account) and deposit to another (debit that second org’s external account).
- Running multiple organizations on the same Midaz deployment is fine, but ensure your deployment has enough resources as you’re essentially hosting multiple ledgers. The microservices will handle requests for all orgs, so volume from all adds up.
- If needed, you could deploy separate instances of Midaz for completely isolated entities (especially if they require different customizations), but then you won’t have a unified view in one system. Most likely, you keep one Midaz cluster and isolate by org within it.
Performance Optimization Best Practices
Indexing and Queries
Use the Midaz APIs for data retrieval rather than running heavy custom queries against the database. We actually suggest that you DO NOT run queries against the database at all.
The APIs are optimized with proper indexing (e.g., you can get all transactions for an account, or all accounts in a portfolio). The Midaz schema has sensible indexes.
Testing at Scale
Before rolling out to full customer base, simulate high load with a load testing tool. Create millions of accounts in a test environment, run a high volume of transactions, and monitor performance. This will highlight any bottlenecks in your particular usage pattern.
Midaz’s architecture choices (microservices, CQRS) are meant to support high volumes, but real-world testing is essential to fine-tune it. Look for linear scalability – e.g., doubling the app servers doubles the throughput – to confirm the architecture is leveraged properly.
In summary, Midaz is built to scale – high performance and scalability as core principles. By structuring your usage wisely (appropriate use of ledgers, segmentation of load, etc.) and by taking advantage of its scalable architecture (microservices, CQRS, etc.), you can handle large-scale banking operations.
Always keep an eye on performance metrics and be ready to adjust resources and structure as your bank’s demands grow.
Updated 2 days ago