At 9fin, we build AI-powered intelligence for debt markets. The role of our Engineering team is to create infrastructure that keeps our platform fast, reliable, and secure as our customers and data scale.
As 9fin expands its coverage across the debt markets, each new product brings its own data requirements. It also needs to connect with information already on the platform, such as companies, investors, and advisors.
Our new Asset-Backed Finance (ABF) product is one example. It brings together data on deals and the firms involved, helping customers make sense of the market, and we wanted it in their hands quickly.
But shipping quickly and building for speed are not always the same thing. Building ABF presented a choice: build on the monolith’s shared database to reach a first release sooner, or give ABF its own service and database so the team could develop it independently.
We chose the second approach. ABF has its own database and connects to the wider platform through an API, while updates to shared information, such as companies, arrive automatically as events. That gives the team control over our product’s data while staying connected to the information customers need.
When the monolith became a constraint
Our platform had grown around a shared PostgreSQL database. That design helped teams move quickly when the product and organisation were smaller, but its coordination cost increased with every new product surface.
We measured 43 query domains referencing 184 shared tables; the company table alone appeared in 37. For ABF, joining directly to those tables would have been convenient, but every future schema change, API experiment and scaling decision would still depend on the monolith.
The real constraint was the cost of changing one domain without needing global confidence. ABF gave us a rare opportunity to test a different model on a greenfield product: it was new, so no existing systems depended on its data yet.
Building a real service boundary
We gave ABF ownership of its deals, tranches, and product-specific reference data in a dedicated PostgreSQL database. The existing application accesses that data through an authenticated REST API, with no cross-database joins.
What is a REST API?
Shared facts such as companies, investors, advisors, and entity identifiers remain owned by their source domain. Instead of calling that domain during every request, ABF stores small, read-shaped local projections:
- The source commits a change and publishes a versioned event.
- A shared event bus routes it to ABF’s domain bus and durable queue.
- An ABF consumer validates the event and updates the relevant projection.
- ABF joins that local projection to the data it owns.
This separates publication from interpretation. Producers publish a stable fact once; ABF controls which facts it consumes and how they support its product.


The product reads ABF through an API while shared facts move asynchronously into local projections.
Designing the event flow for failure
Distributed delivery is not perfectly ordered or happens only once, so our correctness model does not assume either. One company may produce separate entity and company events, and they can arrive in any order or more than once.
Two database guards keep the projection correct:
- A unique 'event_id' turns redelivery into a no-op.
- An upsert applies a change only when its 'event_timestamp' is newer than the stored version.
Historical data needs a different path. A repeatable backfill seeds each projection from a read replica while live events continue flowing. Both paths use the same timestamp rule, preventing an older snapshot row from overwriting a newer event.


Entity and company events arrive independently; consumer guards make redelivery and late updates safe.
What did the experiment unlock?
ABF is now live on production. Its projections can be backfilled, updated through live events and operated using dashboards, alarms, and recovery runbooks. That makes the product ready to support our application, AI experiences, and future client integrations through the same owned interface
The work also produced a reusable engineering pattern: additive event contracts, domain routing, idempotent consumers, staleness protection, backfill, and end-to-end testing. Weekly delivery reviews helped us improve how we sequence this foundational work, leaving future teams with both a reference implementation and a clearer route through it.
Staging has validated the architecture and API surface. Production measurement is the next phase: we will baseline delivery performance, projection freshness and recovery, then compare them after cutover. That discipline matters at 9fin — we want architectural claims to be supported by operating evidence.
Engineering for the next change
Three ideas from the project now shape how we approach service boundaries:
1. Measure the coupling before proposing the architecture. Evidence turns a design preference into an engineering problem the organisation can prioritise.
2. Test the hard pattern in a bounded domain. A greenfield product limits migration risk while producing something the next team can copy.
3. Design contracts for the second consumer. Versioning, additive evolution, and recovery feel expensive for one integration; they become leverage when the pattern spreads.
Building ABF outside the monolith required us to slow down at the point where the easiest choice would have created more coupling. It shows the engineering work we value at 9fin: making deliberate bets, testing them against real constraints, and turning the result into infrastructure that helps other teams move faster. Building ABF this way serves our ambition to make 9fin the number one source of intelligence for debt markets, with deeper coverage and quicker access to the insight our clients need. ABF is one investment in that ambition.
If you enjoy making systems faster at scale, while enhancing clients' experience — we’re hiring, and want to speak with you!






