This article was written under the guidance of Michael,
our Senior DevOps Engineer with 10+ years of experience in this domain.
Before we dive into this two-part article in the BeFund FinTech and iGambling blog series, let’s take stock of what came before it:
- Where Do Your Secrets Live? Security Architecture in Gambling and Fintech;
- Data Monitoring in FinTech and Gambling: A Question of Survival, Not Comfort;
- Data Integrity in FinTech and Gambling: How Not to Lose Data, Transactions, and Money. Part 1;
- Data Integrity in FinTech and Gambling: How Not to Lose Data, Transactions, and Money. Part 2;
- Disaster Recovery in FinTech and Gambling: How to Get Your Project Back Online After a Data Center Failure;
- Backup in FinTech and Gambling: Not Just a Database Dump, but a Business Recovery Guarantee. Part 1;
- Backup in FinTech and Gambling: Not Just a Database Dump, but a Business Recovery Guarantee. Part 2.
If any of the topics above are relevant to you, we recommend reading them before going further. We build this series deliberately, one step at a time, and there are no throwaway entries — each article is carefully placed in the sequence. So if you’re planning to build your own FinTech or iGambling project, set aside some time and work through the full archive. You’ll find it both informative and practical. Now, let’s move on.
Monolith and microservices are the two primary approaches to software development, each solving different problems.
- A monolith is a single application where all the code, interfaces, and databases are bundled into one large block. It’s the natural fit for a fast start and early-stage products.
- Microservices is an architecture built from small, independent services that communicate via APIs. It offers high scalability and flexibility, but demands a considerably more complex infrastructure.
In FinTech and iGambling, starting with a monolith is often the right call. In the early stages, it lets you ship quickly, validate the business model, integrate payment providers, and build the first version of your backoffice, CRM logic, bonuses, bets, withdrawals, and basic analytics.
But over time, a monolith stops enabling growth and starts holding it back. Every change carries risk. Releases slow down. The database becomes a bottleneck. Teams become dependent on each other’s timelines. And when something goes wrong — when you need to profile the code and pinpoint the cause of an incident — only a microservices approach gives you per-service request data, resource usage breakdowns, and the granularity to actually understand what happened. In a monolith, you’re back to inventing custom workarounds every time. That’s not a serious approach for projects at this level.
In FinTech and iGambling projects, this becomes especially dangerous when a single monolith ends up mixing together:
payments; | wallet; | settlement; | withdrawals; |
bonus logic; | fraud/risk; | KYC/AML; | CRM; |
segmentation; | multi-brand logic; | reporting; | admin panel; |
provider integrations; | credentials; | feature flags; | analytics. |
The problem isn’t the monolith architecture itself — it’s when the monolith becomes the place where any change can touch money, users, balances, settlements, or compliance.
At that point, the only motivated path forward is a migration to microservices. And this doesn’t mean “slice the codebase into lots of repositories,” as it might naively appear. What microservices are really about is the correct separation of business domains, responsibilities, data, risks, and teams. In what follows, we’ll walk through exactly how to make that transition — in a way that keeps the system stable and keeps the money safe.
The Monolith Isn’t the bad
It would be a mistake to read this article as a story where the monolith plays the villain and microservices ride in to save the day. This isn’t fiction, and the monolith isn’t a poor choice — it’s an earlier stage in the natural evolution of any project. In fact, at the outset it has a number of genuine advantages over microservices:
- Faster development;
- Simpler deployment;
- A single database;
- Straightforward transactions;
- Less DevOps complexity;
- Easier debugging;
- Lower infrastructure costs;
- Faster time-to-market.
For an MVP or a first version of a FinTech/iGambling platform, a monolith is most often the rational and correct choice. It can comfortably house user registration, login, a basic wallet, deposits, withdrawals, an admin panel, payment provider integration, basic reporting, and simple bonus logic. At this stage, reaching for microservices can actually make things harder: if the team is small, the domains aren’t stable yet, and the business logic is still shifting, an early migration can create more problems than it solves.
The BeFund team’s take: don’t start with microservices just because they sound sophisticated or signal a large budget. First, understand your domain, your load, your risks, and where the boundaries of responsibility actually lie. But be ready to say goodbye to the monolith when the project outgrows what it can reasonably handle.
When the Monolith Becomes the Problem
The monolith stops being a valid choice the moment any change in one place can silently break a critical process somewhere else. In PHP-based projects, this typically shows up across four common architectural patterns:
- Legacy monolith — old code, difficult to maintain, deep inter-file dependencies, hard to test.
- Framework monolith — a well-structured Laravel/Symfony project, but the entire system deploys as one.
- CMS monolith — for example, Winter CMS, WordPress, or Drupal, where business logic lives in plugins, themes, and CMS structures.
- Modular monolith — the most evolution-ready variant: not yet microservices, but already divided into independent modules.
The warning signs to watch for:
- Releases become slow and risky;
- One team blocks another;
- Payment logic is tangled up with bonus logic;
- Settlement depends on backoffice reports;
- The wallet is updated from multiple parts of the codebase;
- Fraud/risk checks are scattered across the system;
- Multi-brand rules are implemented as if/else chains;
- Feature flags are hardcoded;
- Credentials are stored in .env or CI/CD variables;
- Heavy reports put pressure on the primary database;
- Individual modules can’t be scaled independently;
- A bug in CRM sync can affect payments;
- No clear ownership over the user balance.
Most of these are Category 1 and Category 3 problems. But lurking between them is a Category 2 variety with far more damaging consequences: incidents with low observability. Tracking them down burns precious time, and every second the system spends in an ambiguous state has a very real price tag in lost money.
Consider a simple example: a poorly written query in the Wallet service causes a memory spike. It won’t show up in slow logs — it’ll be buried under the volume of smaller, faster requests. Tracing the problem at the monolith level takes a disproportionate amount of time. At the microservice level, with proper logging, the cause of the error is immediately visible.
The time to think seriously about migration is when the lines between money, risk, analytics, configuration, integrations, brands, and administration start to blur. Any mixing between even two of these domains is a disaster waiting to happen — one you want to catch before it fully arrives. In practice, it looks like this:
- The bonus module directly modifies user.balance;
- The settlement job writes directly to the wallet table;
- CRM sync reads the production balance from the primary database;
- The admin panel can change payment settings without an audit trail;
- Each brand has its own conditions implemented through hardcoded logic.
The simplest way to put it: FinTech and iGambling cannot afford chaos. When it appears, it’s time to reconsider your relationship with the monolith and head toward microservices — before it’s too late. Under microservices, the chaos becomes distributed. And distributed chaos is controllable chaos.
Where to Begin the Migration
The transition from monolith to microservices should never be a spontaneous decision. Before moving a single line of code, conduct a thorough analysis and find answers to at least nine questions:
One critical mistake the BeFund team urges you to avoid: never try to do everything at once. Migration requires a sequence. The right approach, in order:
- Identify bounded contexts;
- Separate domain logic from legacy code;
- Add API or event boundaries;
- Extract the first service;
- Set up monitoring, logs, and tracing;
- Ensure idempotency and outbox;
- Verify data consistency.
Only after all of that is it safe to move forward. A simultaneous migration multiplies the risk to the system — and with it, the risk of data loss and financial incidents.
Wallet Service: A Single Source of Truth for the Balance
The Wallet is one of the most critical services in any FinTech or iGambling project. It owns the user balance and every financial change that touches it. Extracting it into a dedicated microservice is, from a security standpoint, one of the most important architectural decisions you can make. The future Wallet Service should be responsible for:
user balance; | holds; | transaction history; |
ledger; | reserved balance; | balance reconciliation; |
debits; | bonus balance; | wallet limits; |
credits; | rollback operations; | currency handling. |
The Wrong Approach
A short list of categorically unacceptable mistakes — avoid these under any circumstances:
- Payment Service directly modifies users.balance;
- Bonus Service directly adds bonuses to the balance;
- Settlement directly writes wins to the wallet table;
- Admin Panel manually edits balances.
The Right Approach
- Payment Service → asks the Wallet Service to credit funds;
- Settlement Service → asks the Wallet Service to process a win/loss;
- Bonus Service → asks the Wallet Service to create a bonus transaction;
- Admin Panel → creates an audited adjustment request.
In short: the Wallet must be the only service that changes the balance.
Key principles for the Wallet Service — these should be built in from day one:
- All operations are idempotent;
- Every balance change has a ledger entry;
- No other service can directly update the balance;
- All financial adjustments go through an audit;
- The balance can be reconstructed from the ledger;
- Read models can be rebuilt.
The Wallet in FinTech and iGambling projects is not just a table with a balance column, as it might naively appear. It is a financial perimeter — one that must be isolated, transactional, and tightly controlled. It’s the first candidate for migration precisely because the entire financial layer of the project depends on it, and that layer is what the business runs on.
Settlement Service: Separate from Wallet and Betting
Settlement is the process of final calculation for bets: wins, losses, refunds, and void operations. Where the Wallet directly handles the movement of money, Settlement determines who gets paid and how much. That’s why it sits second on the migration priority list.
In a monolith, Settlement is frequently entangled with betting logic, wallet logic, and provider callbacks. This is dangerous — even minor issues in adjacent components can cascade into failures and data loss. The future Settlement Service should own:
Settlement events; | Void; | Settlement retry; |
Win/loss calculation; | Rollback; | Settlement reconciliation; |
Bet result processing; | Provider result validation; | Event ordering; |
Refund; | Settlement status; |
|
Why a Dedicated Settlement Service?
A separate microservice for Settlement is warranted primarily by its financial weight in the project and the complexity of the business logic it carries. A great deal depends on it, and yet it’s frequently accessed by both other services and developers under varying conditions:
- Frequent edge cases;
- Dependency on game/odds providers;
- Idempotency is required;
- Audit is required;
- Replay capability is required;
- Independent queue processing is required;
- Reconciliation is required.
The most important design rule: Settlement Service must not directly modify the balance. It must issue a financial command to the Wallet Service. In practice:
Settlement Service:
“Bet #123 won 50 EUR”
Wallet Service:
- creates ledger transaction +50 EUR
- updates balance
- publishes wallet.transaction.created
Settlement decides the outcome. Wallet executes the financial change. This separation reduces the risk of duplicated logic and gives you much cleaner control over financial integrity.
Kafka as the Event Backbone
In a microservices architecture for FinTech and iGambling, you need a distributed platform for real-time message passing and stream processing — something that acts as a high-speed, reliable conveyor belt, letting different services exchange information instantly, accumulate it, and process it without delays. One of the strongest options for this role, in our experience, is Kafka — the message broker from Apache that becomes the central event exchange mechanism. It’s well-suited for:
Payment events; | Bonus events; | Segmentation; |
Wallet events; | KYC events; | Notifications; |
Settlement events; | CRM sync; | Audit events; |
Risk events; | Analytics; | Multi-brand activity streams. |
Examples of events Kafka handles:
payment.deposit.created | settlement.failed |
payment.deposit.succeeded | risk.user.flagged |
payment.deposit.failed | segment.user.updated |
wallet.balance.updated | bonus.granted |
wallet.transaction.created | kyc.verification.completed |
settlement.completed |
|
Kafka helps reduce synchronous coupling between services, process events asynchronously, scale consumers independently, replay events, build read models, pipe data into ClickHouse, feed fraud/risk and segmentation systems, and support event-driven architecture across the board.
Among all its strengths, the one limitation worth noting — shared by most message brokers, not just Kafka — is that it’s demanding in its operational requirements, which means problems can’t always be resolved through straightforward automation. Properly configuring Kafka adds meaningful scalability and flexibility to your project and, crucially, keeps chaos at bay and eliminates the risk of data duplication. To get there, your project will need:
Idempotent consumers; | Event ordering where it’s critical; |
Event schema versioning; | Consumer lag monitoring; |
Dead-letter topics; | Transactional outbox; |
Retry strategy; | Audit for critical events. |
Correlation_id; |
|
Fraud / Risk Service
Fraud/Risk is one of the core domains in FinTech and iGambling — directly affecting both revenue and security. It’s a complex, multi-layered system that has no business living as a pile of if/else statements inside Payment or, worse, Withdrawal logic. The future Fraud/Risk Service should evaluate risk:
- Before a deposit;
- Before a withdrawal;
- Before a bonus is granted;
- Before a large bet;
- After suspicious activity;
- After a user profile change;
- After a KYC/AML event;
- After an anomalous betting pattern.
Events processed by the Fraud/Risk Service:
user.registered; | bet.placed; |
payment.deposit.created; | settlement.completed; |
withdrawal.requested; | kyc.failed; |
wallet.balance.updated; | device.changed; |
ip.changed; | bonus.claimed. |
The decisions this microservice makes touch the most critical financial transactions in the project:
- allow;
- deny;
- manual_review;
- limit;
- hold;
- request_kyc;
- block_withdrawal;
- increase_risk_score.
In some cases, the Fraud/Risk Service must operate synchronously — for example, before a withdrawal. In others, it can work asynchronously, analyzing events from Kafka. The correct operational model:
Real-time risk decision → for critical operations
Async risk analysis → for behavioral analytics, scoring, patterns, segments
Fraud/Risk deserves its own domain because its logic changes rapidly, it directly affects money, and it requires independent oversight.
ClickHouse for Analytics and Heavy Read Queries
Another service that earns its place during migration is ClickHouse — a high-performance, column-oriented database management system designed for online analytical processing (OLAP). It handles petabytes of data in real time and executes complex analytical SQL queries with near-instant response. FinTech and iGambling projects generate an enormous volume of analytical data, including:
payments; | user activity; | risk signals; |
bets; | sessions; | CRM events; |
settlements; | provider events; | affiliate traffic; |
wallet transactions; | bonus usage; | multi-brand reports. |
Running heavy analytical reports against the primary database puts pressure on the critical flow — payments, wallet, settlement. Any slowdown or failure there is unacceptable, as we’ve covered at length in previous articles. ClickHouse is purpose-built for these workloads and fits well for:
Analytics; | Event analytics; |
Dashboards; | Segmentation; |
Reports; | Anti-fraud analytics; |
Aggregations; | Multi-brand reporting; |
Historical data; | Financial summaries. |
ClickHouse offloads the transactional database, enables fast aggregation over large event volumes, powers reports, user behavior analysis, conversion funnels, fraud/risk analytics, and multi-brand data processing.
One important caveat that must never be forgotten: ClickHouse must not be treated as a source of financial truth. It’s an analytics engine, not a system of record for critical write decisions about balances. Always keep the distinction clear:
Sources of truth: | Analytical read models: |
Wallet ledger; | ClickHouse; |
Payment DB; | Elasticsearch; |
Settlement DB; | Materialized views; |
Risk decisions audit. | Reporting database. |
Segmentation Service
Segmentation, in our view, is a distinct and important domain — not only in FinTech and iGambling, but in any project with CRM, bonus campaigns, and retention mechanics. This microservice handles the classification and grouping of users based on defined criteria, which is essential for sound strategy, opportunity identification, and risk management. The Segmentation Service can be responsible for:
user segments; | payment behavior groups; |
VIP status; | KYC-based groups; |
risk segments; | country/brand/currency segmentation; |
bonus eligibility; | retention campaigns; |
marketing cohorts; | affiliate-based segmentation; |
activity groups; |
|
Concrete examples of segments from real projects:
new users without deposit; | inactive users; |
users with failed KYC; | bonus abusers; |
VIP users; | users from a specific brand; |
high-risk users; | users with high lifetime value; |
users with high withdrawal frequency; |
|
Events processed by the Segmentation Service:
user.registered; | risk.user.flagged; |
payment.deposit.succeeded; | bonus.claimed; |
wallet.transaction.created; | kyc.completed; |
bet.placed; | settlement.completed; |
Events published by the Segmentation Service:
- user.added;
- user.removed;
- user.updated.
With this in place, other microservices can operate without duplicating logic, which improves the overall health of the project:
- Bonus Service → checks whether the user belongs to the required segment;
- CRM Service → launches a campaign targeting a segment;
- Risk Service → uses the risk segment;
- Backoffice → displays user segments.
The core value of the Segmentation Service is the extraction of complex user classification logic out of the monolith, enabling centralized management of rules across brands, bonuses, CRM, and risk.
Config / Feature Flags Service
A common problem in monolith-based projects is configuration scattered across the codebase: some settings live in .env files, others in the database, and still others are buried somewhere in the admin panel. The worst and most dangerous scenario for FinTech and iGambling — configuration hardcoded directly into the application logic.
This creates real risk. Different brands, countries, currencies, payment providers, and bonus rules can all have different settings. To avoid unwanted surprises, all configuration should be consolidated in a single place, once and for all — and never revisited as a structural problem again.
The Config / Feature Flags Service should manage:
feature flags; | risk thresholds; |
brand settings; | KYC requirements; |
country restrictions; | maintenance mode; |
payment limits; | A/B testing; |
withdrawal limits; | rollout percentage; |
bonus availability; | provider enable/disable; |
provider routing; | new feature rollout. |
A practical illustration of the advantage:
enable_new_wallet_flow = true for Brand A
enable_new_wallet_flow = false for Brand B
payment_provider_x_enabled = true for EUR
payment_provider_x_enabled = false for GBP
withdrawal_manual_review_threshold = 1000 EUR
Feature flags give you the ability to:
- Roll out a feature gradually;
- Disable a broken integration without a deploy;
- Run brand-specific rollouts;
- Test features on a subset of users;
- React quickly to incidents;
- Eliminate hardcoded logic entirely.
In FinTech and iGambling, configuration is far from a minor concern. It directly affects money, risk exposure, and feature availability. That’s precisely why it belongs in its own isolated domain.
This concludes Part 1. In Part 2, we’ll cover the Credentials Service, multi-brand architecture, database strategies, API Gateway / BFF, and more. We’ll also walk through the most common migration mistakes — so you can make sure you never repeat them in your own projects. With the right guidance, breaking a monolith into microservices doesn’t have to be painful. It can be methodical, fast, and reliable.