An event must reach a business decision
- 01EventKafka
- 02ProcessingFlink + operational data
- 03DecisionBusiness rules
- 04ChannelCustomer outcome
This article covers an early real-time product built in 2023–2024. It is not the Decision Engine / SAS RTDM project I joined in late September 2024.
In a batch model, an offer is calculated in advance and waits for the next data refresh. A real-time approach changes the point at which the decision is made: the system reacts to a customer event, enriches it with current context, and sends the result to an interaction channel.
That may sound like a technical switch from batch to stream processing. In practice, it changes the architecture, the team’s delivery process, and the conversation with the business.
The architecture of the early product
The core flow was straightforward:
- a customer event entered Kafka;
- Apache Flink processed the stream and requested enrichment data;
- Tarantool held operational profiles and reference data;
- business rules produced a decision;
- Kafka delivered the result to the target channel.
PostgreSQL served the data and scenarios that did not require an in-memory access path. Keeping those responsibilities separate was more useful than trying to make every component universal.
What changed between environments
Moving between environments exposed configuration differences. Separately, functional testing found a complex-query defect in Tarantool’s CRUD module. The organiser’s account of the talk describes these episodes; they do not establish a throughput limit.
We revised the integration and moved some logic into external services, keeping Tarantool as the resident store. The experience taught us to check environment compatibility and query correctness earlier, especially on the critical path.
Load testing is also needed. I would test operation mixes, changing data distributions, and queue accumulation alongside peak throughput. That is a recommendation for a test profile, not an explanation of the functional defect.
A timeline that keeps the projects separate
The following is my clarified account of my involvement. It separates the two projects and is not an independent acceptance report. Work on the early real-time product began in October 2023. We formed the main team in roughly two months. A technical prototype followed in late December and January, and a business scenario in February.
Requirements changed in March, and the team prepared a revised version in about a month. The solution entered production in April, and we continued extending it through June 2024.
The new Decision Engine / SAS RTDM was a different project. I joined it in late September 2024; its development ran from December 2024 to April 2025.
What mattered beyond the stack
Contracts between teams. A streaming system is sensitive to schema changes, source delays, and different interpretations of the same event. Every contract needs a clear owner.
Observability through the business journey. CPU charts are not enough. The team must be able to see whether an event completed the full path and produced the expected customer outcome.
A degradation plan. Decide in advance what happens when a source is unavailable or a queue grows: stop, retry, defer, or use a reduced scenario.
A shared decision with the business. Real-time is not valuable by default. It is justified where timing changes the customer journey or the economics of the product.
The main lesson was not a preference for Flink, Kafka, or Tarantool. Fast system response starts with clear engineering and management agreements.
Decide whether real time matters to the business
For a new product, I start with the point after which a decision loses its value. If a customer has already completed an action, timing may change the scenario materially. If an employee acts on a report the next day, stream processing may add little by itself.
I separate event occurrence, ingestion, context updates, decision computation, and channel delivery. A fast computation cannot repair a stale profile or a delayed source. “Fast” needs an end-to-end latency budget and a defined proportion of events that should meet it.
This is a method for reviewing a new problem, not a disclosure of the project’s internal targets. Those targets belong to the product owner and the teams responsible for the sources.
Questions for a release review
| Situation | Question for the system |
|---|---|
| Duplicate event | Will the business action happen twice? |
| Out-of-order events | How is current state determined? |
| Delayed profile update | Is a decision on stale context acceptable? |
| Unavailable channel | Where does the result wait, and when does it expire? |
| Changed rule | Can we identify the version that produced the outcome? |
Every answer needs an owner and a check. Otherwise a finished architecture diagram conceals rules that still live only in individual participants’ heads.
A leader owns the connection between the value of timely decisions and the operational response to a stopped flow. That is where a product goal becomes engineering responsibility.
A longer account of the project is available in the original Russian Habr article. The same case became our Saint HighLoad++ 2024 talk in St. Petersburg.
Yours, DPUPP
Related Articles
Analyst Days 14: Don't Paint the Grass — Data Risk in a BANI World
A reconstruction of my Analyst Days 14 talk on data quality and ownership: distinguishing a working control from attractive reporting.
Building Fintech Products: Seven Paths to Production
A delivery map for banking products: team capability, governance, changing needs, infrastructure, cross-team contracts, the delivery platform, and operations.
Saint HighLoad++ 2024: Moving a Banking Product to Real-Time
How Vladimir Avramov and I turned an early real-time product built with Flink, Kafka, and Tarantool into a focused technical talk.