From Monolith to Microservices in FinTech and Gambling: How to Scale Your Platform Without Chaos. Part 2

From Monolith to Microservices in FinTech and Gambling: How to Scale Your Platform Without Chaos. Part 2

This article was written under the guidance of Michael,
our Senior DevOps Engineer with 10+ years of experience in this domain.

Traditionally, before we begin the next two-part article in the FinTech and iGambling series on the BeFund blog, let’s look at what came before it:

Please, if you have any gaps in knowledge on the topics listed above — review them before you start reading further material. We work sequentially, and there are no “extra steps” here — everything in the series is deliberate and systematic. So if you want to start building or improving your own FinTech and iGambling projects — take the time to go back through our body of work. It will be interesting and useful. And now let’s move on.

Credentials Service

A centralized secrets layer, or Credentials Service, is needed for securely managing access to external systems. We previously discussed in detail the requirements for secrets in projects, so splitting out a separate microservice is an important task. After all, in a monolith you can run into many undesirable situations, for example:

  • Payment API keys in .env;
  • Provider secrets in CI/CD;
  • JWT secrets in config files;
  • CRM tokens in the database without encryption;
  • One key for all brands;
  • Access that developers can see.

In FinTech and iGambling projects this is a serious risk, which we described earlier. So now let’s look at what the Credentials Service should support to increase project security:

  • Storing credentials;
  • versioning;
  • rotation;
  • access control;
  • audit logging;
  • per-brand credentials;
  • per-provider credentials;
  • short-lived secrets;
  • integration with Vault / AWS Secrets Manager / Google Secret Manager;
  • Restricting access for people;
  • Issuing credentials to services via service identity.

Advantages of the Credentials Service

Using a microservice largely resolves a number of issues that we covered separately in the article “Where Do Your Secrets Live? Security Architecture in Gambling and Fintech”. Yes, it was written with a monolith in mind, but it already touched on microservices. So using a Credentials Service provides the following advantages:

  • Developers don’t see production secrets;
  • Each service has only the access it needs;
  • Key rotation is possible;
  • Different credentials can be used for different brands;
  • There’s an audit trail of who accessed a secret and when;
  • A compromised key can be quickly revoked.

Building a microservice with the capabilities described above is especially practical for supporting multi-brand setups. If your project has several affiliated brands at once, access to each of them, unlike in a monolith, can be controlled through the microservice, for example:

Brand A → Payment Provider Key A;

Brand B → Payment Provider Key B;

Brand C → Payment Provider Key C.

So, to sum up the microservice credentials architecture: secrets shouldn’t live in code, containers, or a shared .env file. Access to secrets should be granted to services, not specific people. Microservice architecture can fully solve this problem.

Multi-brand architecture

Several brands on a single FinTech and iGambling platform is a common and highly necessary practice. A single technical core can serve multiple brands, markets, currencies, domains, and business rules. Using a monolithic architecture significantly burdens workflows. This is usually implemented as follows:

  • if brand_id == 1;
  • if country == X;
  • Separate config fields with no structure;
  • Duplicated logic;
  • Different templates in the same code;
  • Manual settings in the database;
  • Different payment keys in .env.

Even if a project has more than one brand, over time this approach causes chaos. And if there are many brands — problems are guaranteed. So a proper multi-brand architecture must account for:

  • brand_id across all key domains;
  • separate brand settings;
  • separate credentials;
  • separate payment routing rules;
  • separate risk rules;
  • separate bonus rules;
  • separate segmentation rules;
  • separate limits;
  • separate domains;
  • separate themes/frontend config;
  • separate reporting dimensions;
  • separate access permissions in the backoffice.

Example of a multi-brand flow:

 As you can see, multi-brand shouldn’t be a bunch of if/else statements, but a systemic part of the architecture. This is the correct approach used by BeFund developers for our clients’ projects. It looks like this:

Brand Context → passed between services;

Config Service → returns brand-specific rules;

Credentials Service → returns brand-specific provider credentials;

Segmentation Service → accounts for brand-specific cohorts;

ClickHouse → stores brand_id for analytics;

Kafka events → contain brand_id.

Example event:

For a better understanding, here’s a code snippet:

{

“event_id”: “evt-123”,

“event_type”: “payment.deposit.succeeded”,

“brand_id”: “brand_a”,

“user_id”: 501,

“amount”: 100,

“currency”: “EUR”,

“provider”: “provider_x”,

“created_at”: “2026-05-13T10:00:00Z”

}

Main principle:

From the above, we can draw a short conclusion: in a multi-brand system, brand_id must be part of the domain model, events, analytics, configuration, access, and reporting. Otherwise, over time the project becomes less manageable, and critical errors become commonplace.

What the target architecture might look like

It’s better to see something once than hear about it a hundred times. Instead of a long text, we suggest looking at clear diagrams of the high-level architecture implementation for a  FinTech and iGambling project:

Example of a high-level architecture:

Financial flow:

Settlement flow:

Config flow:

Credentials flow:

Database per service or shared database?

In the context of this topic, the question of the database can’t be avoided. One of the biggest mistakes is creating many microservices but leaving one shared database that all of them access directly. This inevitably creates a distributed monolith — an antipattern where the system is designed as a set of microservices, but logically and functionally remains as tightly coupled as a monolith. It has the drawbacks of both approaches but none of the benefits of microservice architecture. For example:

The main problems that arise from such a scheme:

  • Strong coupling;
  • Impossible to change the schema independently;
  • Hard to scale;
  • Risk of breaking another service;
  • No real ownership;
  • Transactions are smeared across services;
  • Complex deployment.

To avoid this situation, a better approach must be used:

Payment Service → payment_db;

Wallet Service → wallet_db;

Settlement Service → settlement_db;

Risk Service → risk_db;

Config Service → config_db;

Segmentation Service → segmentation_db.

Under these conditions, the project’s complexity grows, since a number of questions need to be resolved:

  • How to ensure consistency?;
  • How to build read models?;
  • How to do reporting?;
  • How to exchange events?;
  • How to avoid duplication?;
  • How to do reconciliation?

However, microservices without data separation often remain a monolith, just a more expensive and complex one. That’s exactly why it’s worth thinking everything through in detail, so as not to create bigger problems purely out of a desire to avoid them. BeFund will help you handle this task in the best possible way.

API Gateway / BFF

When a FinTech or iGambling project migrates away from a monolith and the number of microservices keeps growing, a new problem appears that less experienced development teams often forget about. It’s related to the frontend or mobile application, which shouldn’t need to know directly about all the internal services, since that only burdens their work. In that case, an API Gateway is needed — a single entry point for all client requests in the system It acts as a “middleman” or “concierge” intercepting calls and routing them to the appropriate microservices, while also handling security and traffic optimization functions. Such a gateway should be responsible for:

  • routing;
  • authentication;
  • rate limiting;
  • request validation;
  • brand resolution;
  • tenant context;
  • aggregation;
  • API versioning;
  • basic security checks;
  • observability headers;
  • correlation_id;
  • public API layer.

API Gateway / BFF is especially important for multi-brand setups, since here it determines:

  • brand by domain;
  • brand by header;
  • brand by token;
  • brand by API key;
  • country/currency context.

Observability as a mandatory requirement for microservices

For comparison, let’s say that microservices without observability are a black box into which the following are simply dumped:

  • centralized logs;
  • metrics;
  • distributed tracing;
  • correlation_id;
  • request_id;
  • business metrics;
  • Kafka consumer lag;
  • service health;
  • error rate;
  • latency;
  • dead-letter topics;
  • outbox lag;
  • ClickHouse ingestion lag;
  • feature flag audit;
  • credentials access audit.

It’s impossible to say what’s happening inside the box. In a monolith, the problem could still be found through a log file, though investigating it takes time and resources. But in microservices, a single user flow can pass through:

  • API Gateway;
  • Payment Service;
  • Risk Service;
  • Wallet Service;
  • Kafka;
  • Notification Service;
  • CRM Sync;
  • ClickHouse.

In that case, it’s simply impossible to track down a specific problem. Without tracing, no one will understand where, when, or under what conditions it happened. That’s why observability must be in place before moving to microservices. Otherwise every incident becomes an investigation without a map.

Common migration mistakes

Let’s move on to more practical matters. So, the decision to migrate has been made, work is starting… Wait, review this checklist, and don’t put everything on hold if at least one of these points applies to your project:

🔲 Cutting up code without understanding the domains;

🔲 Creating many services with a single shared database;

🔲 Extracting services without monitoring and tracing;

🔲 Not having idempotency;

🔲 Not having Kafka retry / DLQ;

🔲 Making everything synchronous HTTP calls;

🔲 Not having an outbox pattern;

🔲 Not having schema versioning for events;

🔲 Not separating Wallet and Settlement;

🔲 Giving every service the right to change the balance;

🔲 Leaving credentials in .env;

🔲 Not accounting for multi-brand;

🔲 Implementing feature flags via hardcoded if statements;

🔲 Using ClickHouse as the source of truth;

🔲 Launching microservices without DevOps maturity.

The worst outcome that can happen, even if just one of these conditions is met, is a distributed monolith: many services, many network calls, complex deployment, but the same tight coupling as in a monolith. Don’t let this happen — the next section will help you avoid it.

A practical migration plan

We’ve broken the entire migration process down into logical stages

 Stage 1. Preparing the monolith

  • Add logging;
  • Add correlation_id;
  • Isolate domain modules;
  • Clean up direct balance changes;
  • Add audit;
  • Add feature flags;
  • Add an outbox table;
  • Add idempotency for payments/webhooks;
  • Prepare API boundaries.

Stage 2. Extract the read load

  • Kafka / outbox;
  • ClickHouse for analytics;
  • Separate read models;
  • Reporting outside the primary DB;
  • Dashboards without load on the transactional database.

Stage 3. Extract Config / Feature Flags

  • brand settings;
  • provider settings;
  • limits;
  • feature toggles;
  • rollout rules;
  • maintenance flags.

This is often a safe first service, since it doesn’t touch money directly, but it reduces hardcoded chaos.

Stage 4. Extract the Credentials Service

  • secrets;
  • provider keys;
  • brand credentials;
  • rotation;
  • audit;
  • service access.

This strengthens security and prepares the platform for independent services.

Stage 5. Extract the Wallet

The Wallet is complex but critical. It needs to be extracted carefully:

  • Ledger;
  • Idempotency;
  • API for debit/credit/hold;
  • Audit;
  • Reconciliation;
  • Strict transactions;
  • Prohibiting direct balance updates.

Stage 6. Extract Settlement

  • settlement events;
  • result validation;
  • win/loss/refund;
  • integration with Wallet;
  • retry;
  • reconciliation;
  • Kafka consumers.

Stage 7. Extract Fraud/Risk

  • Risk scoring;
  • Rules;
  • Manual review;
  • Real-time checks;
  • Async event analysis;
  • Risk segments.

Stage 8. Extract Segmentation

  • User cohorts;
  • Bonus eligibility;
  • CRM segments;
  • Risk segments;
  • Multi-brand segmentation;
  • ClickHouse-based analysis.

Stage 9. Scale the remaining services

  • Bonus;
  • CRM Sync;
  • Notifications;
  • Affiliate;
  • Reporting;
  • KYC/AML.

Benefits of the right approach

A well-thought-out implementation of microservice architecture gives the project the following benefits:

  • Independent scaling of services;
  • Isolation of critical domains;
  • Faster releases;
  • Less risk for wallet and payments;
  • Separate teams per domain;
  • Better observability;
  • Better multi-brand management;
  • Flexible feature flags;
  • Safer credentials management;
  • Faster analytics via ClickHouse;
  • Better fraud/risk models;
  • Less load on the primary DB;
  • Better preparation for high load.

At the same time, we have to emphasize: microservices also add complexity:

  • Network latency;
  • Eventual consistency;
  • More complex deployment;
  • More complex debugging;
  • More DevOps work;
  • Need for Kafka;
  • Need for tracing;
  • Need for contract testing;
  • Need for schema governance;
  • Need for incident response.

That’s why the main question every owner of a FinTech or iGambling project should ask before starting the migration process is not “Do we need microservices?”, but rather: “Are we ready for microservices organizationally, technically, and domain-wise?”

Conclusions

In summarizing these two articles, our specialists want you to understand: the transition from a monolith to microservices in FinTech or iGambling should not be a fashionable architectural exercise, but a controlled transformation of business domains.

You should start not by cutting up the repository, but by understanding:

  • Where is the financial truth?;
  • Who is responsible for the balance?;
  • Where does settlement happen?;
  • How does fraud/risk work?;
  • How are credentials managed?;
  • How is multi-brand supported?;
  • Where is segmentation needed?;
  • Where is ClickHouse needed?;
  • Which events should go through Kafka?;
  • Which services should be independent?;
  • Where is eventual consistency acceptable?;
  • Where is strict consistency needed?

The right approach to this whole large-scale migration process looks like this:

  • Wallet separate;
  • Settlement separate;
  • Fraud/Risk separate;
  • Config / Feature Flags separate;
  • Credentials separate;
  • Segmentation separate;
  • Analytics in ClickHouse;
  • Events through Kafka;
  • Multi-brand as part of the architecture, not a set of if/else statements.

That’s it. In reality, microservices don’t solve chaos. They scale what’s already there. If a monolith lacks clear domains, audit, monitoring, data integrity, idempotency, and ownership — after the transition the system won’t become better, but on the contrary, more complex. That’s why BeFund specialists are always ready to help you get everything right, on time, and in a way that doesn’t lose data or money and doesn’t need redoing later.