SlideShare une entreprise Scribd logo
1  sur  45
Real-time Financials 

with Microservices and

Functional Programming
Vitor Guarino Olivier

vitor@nubank.com.br
@ura1a

https://nubank.com.br/
InfoQ.com: News & Community Site
• 750,000 unique visitors/month
• Published in 4 languages (English, Chinese, Japanese and Brazilian
Portuguese)
• Post content from our QCon conferences
• News 15-20 / week
• Articles 3-4 / week
• Presentations (videos) 12-15 / week
• Interviews 2-3 / week
• Books 1 / month
Watch the video with slide
synchronization on InfoQ.com!
https://www.infoq.com/presentations/
nubank-financial-systems
Presented at QCon New York
www.qconnewyork.com
Purpose of QCon
- to empower software development by facilitating the spread of
knowledge and innovation
Strategy
- practitioner-driven conference designed for YOU: influencers of
change and innovation in your teams
- speakers and topics driving the evolution and innovation
- connecting and catalyzing the influencers and innovators
Highlights
- attended by more than 12,000 delegates since 2007
- held in 9 cities worldwide
MAIN PRODUCT
Live since September 2014
A TECHNOLOGY DRIVEN APPROACH TO
FINANCIAL SERVICES
CONTINUOUS DELIVERY
MICROSERVICES
INDEPENDENTLY AND CONTINUOUSLY
DEPLOYABLE
DECOUPLED AND EASY TO REPLACE
BOUNDED BY CONTEXT AND INDEPENDENTLY
DEVELOPED
WHAT HAPPENS WHEN WE NEED TO
COMBINE DATA ACROSS SEVERAL SERVICES?
ESPECIALLY IN REAL-TIME
- Running on AWS, 2 AZs, config as code, 

immutable infra, horizontally scalable,

sharded by customers
SERVICE ARCHITECTURE
- Producer/Consumer to Kafka
- REST APIs
REST
- Written in Clojure (functional)
- Persistence with Datomic
DATOMIC
- Immutable, append-only database
- ACID on writes (atomic, consistent, isolated, durable)
Lucas Cavalcanti & Edward Wible - Exploring four hidden superpowers of Datomic
- A database that works a lot like
The Problem
WE HAVE OVER 90 SERVICES
THE PROBLEM:

A LOT OF BUSINESS LOGIC DEPENDS ON DATA
ACROSS MANY SERVICES
Should I authorize a purchase? Should I block a card? Should I charge interest?
Purchases InterestChargebacksPayments Currencies
THE PROBLEM:

WE ARE SHOWING THESE NUMBERS TO THE
CUSTOMER IN REAL TIME
THE PROBLEM:

NO CANONICAL DEFINITION OF OUR KEY
NUMBERS
- Ad-hoc definitions created by analysts and engineers
- Analysis vs. operational definition gap
- Nubank, investors, customers, and regulators 

are all worried about the same numbers.
A BALANCE SHEET IS THE CANONICAL WAY
OF REPRESENTING FINANCIAL INFO
- We can apply generally accepted accounting principles 

(verifiable, unbiased)
- Conservation of money (every credit should have a debit)
- One of the original event-sourced systems
LIABILITY
ASSET
EQUITY
THE MODEL
- Entry: represents a debit and a credit to two book-accounts
- Meta-entity: it’s a reference to the external entity that originated the event
- Movement: a collection of entries. Maps one Kafka message to one db transaction
- Book-account: A customer owned balance sheet account

ex: cash, prepaid, late, payable
-Algebraic Models For Accounting Systems 

by Salvador Cruz Rambaud and José Garcia Pérez
- Balance: cumulative sum of entries of a book account
Double-entry accounting

service
OUR GOAL FOR OUR ACCOUNTING LEDGER

(aka DOUBLE-ENTRY SERVICE)
- High availability to other services, clients, and analysts in real-time
- Resilient to distributed systems craziness
- Traceability of when and why we were inconsistent (strong audit trail)
- Event-driven, via kafka. (we could subscribe to existing topics)
THE IDEAL FLOW
f(payload)
MOVEMENT[ ]
EVENT
ACID transaction
- Event ordering doesn’t matter
- No mutable state
- Needs to guarantee all events are
consumed
- Thread safe
{:purchase

{:id (uuid)

:amount 100.0M

:interchange 1M

:post-date "2016-12-01"}}
Initial Balances: 

Current Limit R$ 1000, Current Limit Offset R$ 1000
Final Balances: 

Current Limit: R$ 900, Current Limit: Offset R$ 900

Settled Purchase: R$ 100, Payable: R$ 99, Interchange Revenue: R$ 1
[{:entry/id (uuid)

:entry/amount 100.0M

:entry/debit-account :asset/settled-purchase

:entry/credit-account :liability/payable

:entry/post-date "2016-12-01"

:entry/movement new-purchase}
recognize

receivable/payable
{:entry/id (uuid)

:entry/amount 100M

:entry/debit-account :liability/current-limit

:entry/credit-account :asset/current-limit

:entry/post-date "2016-12-01"

:entry/movement new-purchase}
reduce limit
{:entry/id (uuid)

:entry/amount 1M

:entry/debit-account :liability/payable

:entry/credit-account :pnl/interchange-revenue

:entry/post-date "2016-12-01"

:entry/movement new-purchase}

]
recognize

revenue
WE CAN'T GUARANTEE CONSISTENCY,

BUT WE CAN MEASURE IT
f(payload)
MOVEMENT[ ]
ACID transaction
- Kafka Lag
- Service downtime
- Processing time
produced-at vs. consumed-at
post-date vs. produced-at
consumed-at vs. db/txInstant
PURE FUNCTIONS OF THE PAYLOAD
WON'T ALWAYS WORK
The Stateful Flow
{:payment

{:id (uuid)

:amount 150.00M

:post-date "2016-12-01"}}
[{:entry/id (uuid)

:entry/amount 100.0M

:entry/debit-account :asset/cash

:entry/credit-account :asset/late

:entry/post-date "2016-12-01"

:entry/movement new-payment}
amortize debt
{:entry/id (uuid)

:entry/amount 100M

:entry/debit-account :asset/current-limit

:entry/credit-account :liability/current-limit

:entry/post-date "2016-12-01"

:entry/movement new-payment}
increase limit
{:entry/id (uuid)

:entry/amount 50M

:entry/debit-account :asset/cash

:entry/credit-account :liability/prepaid

:entry/post-date "2016-12-01"

:entry/movement new-payment}

]
recognize

prepaid amount
Initial Balances: 

Current Limit: R$ 900, Current Limit Offset: R$ 900

Late: R$ 100, Payable: R$ 99, Interchange Revenue: R$ 1
Final Balances: 

Current Limit: R$ 1000, Current Limit Offset: R$ 1000

Cash: R$ 150, Prepaid R$ 50, Payable: R$ 99, Interchange Revenue: R$ 1
{:payment

{:id (uuid)

:amount 150.00M

:post-date "2016-12-01"}}
[{:entry/id (uuid)

:entry/amount 100.0M

:entry/debit-account :asset/cash

:entry/credit-account :asset/late

:entry/post-date "2016-12-01"

:entry/movement new-payment}
amortize debt
{:entry/id (uuid)

:entry/amount 100M

:entry/debit-account :asset/current-limit

:entry/credit-account :liability/current-limit

:entry/post-date "2016-12-01"

:entry/movement new-payment}
increase limit
{:entry/id (uuid)

:entry/amount 50M

:entry/debit-account :asset/cash

:entry/credit-account :liability/prepaid

:entry/post-date "2016-12-01"

:entry/movement new-payment}

]
recognize

prepaid amount
Initial Balances: 

Late: R$ 100
Final Balances: 

Cash: R$ 150, Prepaid R$ 50
THE STATEFUL FLOW
- Movements in the past will modify all future balances
- Adapters are a function of the event payload AND current balances
- Balances can’t change during calculations
- Can’t allow for data to be corrupted depending on the order of the events
INVARIANTS
INVARIANTS
- Some balances can’t coexist (no late alongside prepaid)
- We can establish invariants that must hold true at all times
- Some balances can’t be negative (cash)
- Some can’t be positive (credit-loss)
THE STATEFUL FLOW
EVENT
f(payload, )
ACID transaction
f( )
VALID STATE?
FIX VIOLATION
INVARIANT VIOLATIONS?
NO
MOVEMENT[ ]
Cr: Late

Dr: Cash

R$ 150
Cr: Late

Dr: Cash

R$ 150
MOVEMENT WITH CORRECTION[ ]
Cr: Prepaid

Dr: Late

R$ 50
Initial Balances: 

Late: R$ 100
Final Balances: 

Cash: R$ 150, Prepaid R$ 50
[ ]
VIOLATIONS YES
Negative 

Late 

Balance
CHALLENGES
CHALLENGES
- Fixing invariants logic is extremely complex.
- Datomic indexing is tested until 10 billion facts.
- Datomic isn’t the best option for analytical workload, especially with sharded dbs
- Other services bugs may generate incorrect entries that will need to be fixed
GENERATIVE TESTING
- We generate random events from our schemas (bill, purchases, payments, etc)
- Write a function that describes a property that should always hold true 

instead of describing input and expected output,

- Properties that should hold true are the same invariants that are guaranteed in prod
- Embed the least amount of domain logic assumptions
GENERATIVE TESTING
(def balances-property
(prop/for-all [account (g/generator Account)

events (gen/vector (gen/one-of [(g/generator Purchase)

(g/generator Payment)

...]))]

(->> datomic

(consume-all! account events)

:db-after

(balances-are-positive!)))
(fact (tc/quick-check 500 balances-property) => (th/embeds {:result true}))
(ns double-entry.controllers.rulebook-test

(:require [midje.sweet :refer :all]
[clojure.test.check.properties :as prop]

[clojure.test.check :as tc]

[schema-generators.generators :as g]

[clojure.test.check.generators :as gen]))
MONITORING / REPLAY HISTORY TOOLING
- Other services have republish endpoints 

(same payload and meta data as original thanks to datomic)
- We set sanity checks to make sure events aren’t missing
- We have an endpoint that can retract all entries for a customer

(resets business timeline, but not DB)
SHARDING BY CUSTOMER / TIME
- No cross customer entries allows for per customer sharding
- We shard the database by time fairly often.
- simple representation of the end state of the customer at a time shard: 

final balance of each of the book accounts
- As time passes, any single customer’s db will approach infinite datoms
ETL
extract logs
facts to table

(one per
entity type)
tables stored
applies functions to generate balances
balances
on redshift*
* also accessible through metabase
The Result
Text placeholder
2015-01 2015-04 2015-07 2015-10 2015-01 2016-03
REAL TIME BALANCE SHEET
2 TIMELINES
ACTUAL (DB) TIME
audit trail / Datomic log
“when did we know”day 0 day 30 day 90
BUSINESS TIME
official version of events
uses business-relevant “post dates”
can correct after the fact
day 0 day 30
WHAT WE LIKE
- Canonical definition of our most important numbers
- Financial analysis applied at a the customer level in real-time
- Business-specific invariants provide safety
- Generative testing finds real bugs
- Ability to replay history for a customer without losing data
- Shardable by time and by customer
- Extensible to other products (some don’t require stateful approach)
- Inconsistency traceability allows us to react to it
42
nubank.com.br/jobs
vitor@nubank.com.br
@ura1a
https://gist.github.com/ura1a to get snippets of our domain!
THANK YOU!
Watch the video with slide synchronization on
InfoQ.com!
https://www.infoq.com/presentations/nubank-
financial-systems

Contenu connexe

Plus de C4Media

Shifting Left with Cloud Native CI/CD
Shifting Left with Cloud Native CI/CDShifting Left with Cloud Native CI/CD
Shifting Left with Cloud Native CI/CDC4Media
 
CI/CD for Machine Learning
CI/CD for Machine LearningCI/CD for Machine Learning
CI/CD for Machine LearningC4Media
 
Fault Tolerance at Speed
Fault Tolerance at SpeedFault Tolerance at Speed
Fault Tolerance at SpeedC4Media
 
Architectures That Scale Deep - Regaining Control in Deep Systems
Architectures That Scale Deep - Regaining Control in Deep SystemsArchitectures That Scale Deep - Regaining Control in Deep Systems
Architectures That Scale Deep - Regaining Control in Deep SystemsC4Media
 
ML in the Browser: Interactive Experiences with Tensorflow.js
ML in the Browser: Interactive Experiences with Tensorflow.jsML in the Browser: Interactive Experiences with Tensorflow.js
ML in the Browser: Interactive Experiences with Tensorflow.jsC4Media
 
Build Your Own WebAssembly Compiler
Build Your Own WebAssembly CompilerBuild Your Own WebAssembly Compiler
Build Your Own WebAssembly CompilerC4Media
 
User & Device Identity for Microservices @ Netflix Scale
User & Device Identity for Microservices @ Netflix ScaleUser & Device Identity for Microservices @ Netflix Scale
User & Device Identity for Microservices @ Netflix ScaleC4Media
 
Scaling Patterns for Netflix's Edge
Scaling Patterns for Netflix's EdgeScaling Patterns for Netflix's Edge
Scaling Patterns for Netflix's EdgeC4Media
 
Make Your Electron App Feel at Home Everywhere
Make Your Electron App Feel at Home EverywhereMake Your Electron App Feel at Home Everywhere
Make Your Electron App Feel at Home EverywhereC4Media
 
The Talk You've Been Await-ing For
The Talk You've Been Await-ing ForThe Talk You've Been Await-ing For
The Talk You've Been Await-ing ForC4Media
 
Future of Data Engineering
Future of Data EngineeringFuture of Data Engineering
Future of Data EngineeringC4Media
 
Automated Testing for Terraform, Docker, Packer, Kubernetes, and More
Automated Testing for Terraform, Docker, Packer, Kubernetes, and MoreAutomated Testing for Terraform, Docker, Packer, Kubernetes, and More
Automated Testing for Terraform, Docker, Packer, Kubernetes, and MoreC4Media
 
Navigating Complexity: High-performance Delivery and Discovery Teams
Navigating Complexity: High-performance Delivery and Discovery TeamsNavigating Complexity: High-performance Delivery and Discovery Teams
Navigating Complexity: High-performance Delivery and Discovery TeamsC4Media
 
High Performance Cooperative Distributed Systems in Adtech
High Performance Cooperative Distributed Systems in AdtechHigh Performance Cooperative Distributed Systems in Adtech
High Performance Cooperative Distributed Systems in AdtechC4Media
 
Rust's Journey to Async/await
Rust's Journey to Async/awaitRust's Journey to Async/await
Rust's Journey to Async/awaitC4Media
 
Opportunities and Pitfalls of Event-Driven Utopia
Opportunities and Pitfalls of Event-Driven UtopiaOpportunities and Pitfalls of Event-Driven Utopia
Opportunities and Pitfalls of Event-Driven UtopiaC4Media
 
Datadog: a Real-Time Metrics Database for One Quadrillion Points/Day
Datadog: a Real-Time Metrics Database for One Quadrillion Points/DayDatadog: a Real-Time Metrics Database for One Quadrillion Points/Day
Datadog: a Real-Time Metrics Database for One Quadrillion Points/DayC4Media
 
Are We Really Cloud-Native?
Are We Really Cloud-Native?Are We Really Cloud-Native?
Are We Really Cloud-Native?C4Media
 
CockroachDB: Architecture of a Geo-Distributed SQL Database
CockroachDB: Architecture of a Geo-Distributed SQL DatabaseCockroachDB: Architecture of a Geo-Distributed SQL Database
CockroachDB: Architecture of a Geo-Distributed SQL DatabaseC4Media
 
A Dive into Streams @LinkedIn with Brooklin
A Dive into Streams @LinkedIn with BrooklinA Dive into Streams @LinkedIn with Brooklin
A Dive into Streams @LinkedIn with BrooklinC4Media
 

Plus de C4Media (20)

Shifting Left with Cloud Native CI/CD
Shifting Left with Cloud Native CI/CDShifting Left with Cloud Native CI/CD
Shifting Left with Cloud Native CI/CD
 
CI/CD for Machine Learning
CI/CD for Machine LearningCI/CD for Machine Learning
CI/CD for Machine Learning
 
Fault Tolerance at Speed
Fault Tolerance at SpeedFault Tolerance at Speed
Fault Tolerance at Speed
 
Architectures That Scale Deep - Regaining Control in Deep Systems
Architectures That Scale Deep - Regaining Control in Deep SystemsArchitectures That Scale Deep - Regaining Control in Deep Systems
Architectures That Scale Deep - Regaining Control in Deep Systems
 
ML in the Browser: Interactive Experiences with Tensorflow.js
ML in the Browser: Interactive Experiences with Tensorflow.jsML in the Browser: Interactive Experiences with Tensorflow.js
ML in the Browser: Interactive Experiences with Tensorflow.js
 
Build Your Own WebAssembly Compiler
Build Your Own WebAssembly CompilerBuild Your Own WebAssembly Compiler
Build Your Own WebAssembly Compiler
 
User & Device Identity for Microservices @ Netflix Scale
User & Device Identity for Microservices @ Netflix ScaleUser & Device Identity for Microservices @ Netflix Scale
User & Device Identity for Microservices @ Netflix Scale
 
Scaling Patterns for Netflix's Edge
Scaling Patterns for Netflix's EdgeScaling Patterns for Netflix's Edge
Scaling Patterns for Netflix's Edge
 
Make Your Electron App Feel at Home Everywhere
Make Your Electron App Feel at Home EverywhereMake Your Electron App Feel at Home Everywhere
Make Your Electron App Feel at Home Everywhere
 
The Talk You've Been Await-ing For
The Talk You've Been Await-ing ForThe Talk You've Been Await-ing For
The Talk You've Been Await-ing For
 
Future of Data Engineering
Future of Data EngineeringFuture of Data Engineering
Future of Data Engineering
 
Automated Testing for Terraform, Docker, Packer, Kubernetes, and More
Automated Testing for Terraform, Docker, Packer, Kubernetes, and MoreAutomated Testing for Terraform, Docker, Packer, Kubernetes, and More
Automated Testing for Terraform, Docker, Packer, Kubernetes, and More
 
Navigating Complexity: High-performance Delivery and Discovery Teams
Navigating Complexity: High-performance Delivery and Discovery TeamsNavigating Complexity: High-performance Delivery and Discovery Teams
Navigating Complexity: High-performance Delivery and Discovery Teams
 
High Performance Cooperative Distributed Systems in Adtech
High Performance Cooperative Distributed Systems in AdtechHigh Performance Cooperative Distributed Systems in Adtech
High Performance Cooperative Distributed Systems in Adtech
 
Rust's Journey to Async/await
Rust's Journey to Async/awaitRust's Journey to Async/await
Rust's Journey to Async/await
 
Opportunities and Pitfalls of Event-Driven Utopia
Opportunities and Pitfalls of Event-Driven UtopiaOpportunities and Pitfalls of Event-Driven Utopia
Opportunities and Pitfalls of Event-Driven Utopia
 
Datadog: a Real-Time Metrics Database for One Quadrillion Points/Day
Datadog: a Real-Time Metrics Database for One Quadrillion Points/DayDatadog: a Real-Time Metrics Database for One Quadrillion Points/Day
Datadog: a Real-Time Metrics Database for One Quadrillion Points/Day
 
Are We Really Cloud-Native?
Are We Really Cloud-Native?Are We Really Cloud-Native?
Are We Really Cloud-Native?
 
CockroachDB: Architecture of a Geo-Distributed SQL Database
CockroachDB: Architecture of a Geo-Distributed SQL DatabaseCockroachDB: Architecture of a Geo-Distributed SQL Database
CockroachDB: Architecture of a Geo-Distributed SQL Database
 
A Dive into Streams @LinkedIn with Brooklin
A Dive into Streams @LinkedIn with BrooklinA Dive into Streams @LinkedIn with Brooklin
A Dive into Streams @LinkedIn with Brooklin
 

Dernier

Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 

Dernier (20)

Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 

Functional / Microservices in Real-Time Financials

  • 1. Real-time Financials 
 with Microservices and
 Functional Programming Vitor Guarino Olivier
 vitor@nubank.com.br @ura1a
 https://nubank.com.br/
  • 2. InfoQ.com: News & Community Site • 750,000 unique visitors/month • Published in 4 languages (English, Chinese, Japanese and Brazilian Portuguese) • Post content from our QCon conferences • News 15-20 / week • Articles 3-4 / week • Presentations (videos) 12-15 / week • Interviews 2-3 / week • Books 1 / month Watch the video with slide synchronization on InfoQ.com! https://www.infoq.com/presentations/ nubank-financial-systems
  • 3. Presented at QCon New York www.qconnewyork.com Purpose of QCon - to empower software development by facilitating the spread of knowledge and innovation Strategy - practitioner-driven conference designed for YOU: influencers of change and innovation in your teams - speakers and topics driving the evolution and innovation - connecting and catalyzing the influencers and innovators Highlights - attended by more than 12,000 delegates since 2007 - held in 9 cities worldwide
  • 4. MAIN PRODUCT Live since September 2014
  • 5. A TECHNOLOGY DRIVEN APPROACH TO FINANCIAL SERVICES
  • 9. DECOUPLED AND EASY TO REPLACE
  • 10. BOUNDED BY CONTEXT AND INDEPENDENTLY DEVELOPED
  • 11. WHAT HAPPENS WHEN WE NEED TO COMBINE DATA ACROSS SEVERAL SERVICES? ESPECIALLY IN REAL-TIME
  • 12. - Running on AWS, 2 AZs, config as code, 
 immutable infra, horizontally scalable,
 sharded by customers SERVICE ARCHITECTURE - Producer/Consumer to Kafka - REST APIs REST - Written in Clojure (functional) - Persistence with Datomic
  • 13. DATOMIC - Immutable, append-only database - ACID on writes (atomic, consistent, isolated, durable) Lucas Cavalcanti & Edward Wible - Exploring four hidden superpowers of Datomic - A database that works a lot like
  • 15. WE HAVE OVER 90 SERVICES
  • 16. THE PROBLEM:
 A LOT OF BUSINESS LOGIC DEPENDS ON DATA ACROSS MANY SERVICES Should I authorize a purchase? Should I block a card? Should I charge interest? Purchases InterestChargebacksPayments Currencies
  • 17. THE PROBLEM:
 WE ARE SHOWING THESE NUMBERS TO THE CUSTOMER IN REAL TIME
  • 18. THE PROBLEM:
 NO CANONICAL DEFINITION OF OUR KEY NUMBERS - Ad-hoc definitions created by analysts and engineers - Analysis vs. operational definition gap - Nubank, investors, customers, and regulators 
 are all worried about the same numbers.
  • 19. A BALANCE SHEET IS THE CANONICAL WAY OF REPRESENTING FINANCIAL INFO - We can apply generally accepted accounting principles 
 (verifiable, unbiased) - Conservation of money (every credit should have a debit) - One of the original event-sourced systems LIABILITY ASSET EQUITY
  • 20. THE MODEL - Entry: represents a debit and a credit to two book-accounts - Meta-entity: it’s a reference to the external entity that originated the event - Movement: a collection of entries. Maps one Kafka message to one db transaction - Book-account: A customer owned balance sheet account
 ex: cash, prepaid, late, payable -Algebraic Models For Accounting Systems 
 by Salvador Cruz Rambaud and José Garcia Pérez - Balance: cumulative sum of entries of a book account
  • 22. OUR GOAL FOR OUR ACCOUNTING LEDGER
 (aka DOUBLE-ENTRY SERVICE) - High availability to other services, clients, and analysts in real-time - Resilient to distributed systems craziness - Traceability of when and why we were inconsistent (strong audit trail) - Event-driven, via kafka. (we could subscribe to existing topics)
  • 23. THE IDEAL FLOW f(payload) MOVEMENT[ ] EVENT ACID transaction - Event ordering doesn’t matter - No mutable state - Needs to guarantee all events are consumed - Thread safe
  • 24. {:purchase
 {:id (uuid)
 :amount 100.0M
 :interchange 1M
 :post-date "2016-12-01"}} Initial Balances: 
 Current Limit R$ 1000, Current Limit Offset R$ 1000 Final Balances: 
 Current Limit: R$ 900, Current Limit: Offset R$ 900
 Settled Purchase: R$ 100, Payable: R$ 99, Interchange Revenue: R$ 1 [{:entry/id (uuid)
 :entry/amount 100.0M
 :entry/debit-account :asset/settled-purchase
 :entry/credit-account :liability/payable
 :entry/post-date "2016-12-01"
 :entry/movement new-purchase} recognize
 receivable/payable {:entry/id (uuid)
 :entry/amount 100M
 :entry/debit-account :liability/current-limit
 :entry/credit-account :asset/current-limit
 :entry/post-date "2016-12-01"
 :entry/movement new-purchase} reduce limit {:entry/id (uuid)
 :entry/amount 1M
 :entry/debit-account :liability/payable
 :entry/credit-account :pnl/interchange-revenue
 :entry/post-date "2016-12-01"
 :entry/movement new-purchase}
 ] recognize
 revenue
  • 25. WE CAN'T GUARANTEE CONSISTENCY,
 BUT WE CAN MEASURE IT f(payload) MOVEMENT[ ] ACID transaction - Kafka Lag - Service downtime - Processing time produced-at vs. consumed-at post-date vs. produced-at consumed-at vs. db/txInstant
  • 26. PURE FUNCTIONS OF THE PAYLOAD WON'T ALWAYS WORK
  • 28. {:payment
 {:id (uuid)
 :amount 150.00M
 :post-date "2016-12-01"}} [{:entry/id (uuid)
 :entry/amount 100.0M
 :entry/debit-account :asset/cash
 :entry/credit-account :asset/late
 :entry/post-date "2016-12-01"
 :entry/movement new-payment} amortize debt {:entry/id (uuid)
 :entry/amount 100M
 :entry/debit-account :asset/current-limit
 :entry/credit-account :liability/current-limit
 :entry/post-date "2016-12-01"
 :entry/movement new-payment} increase limit {:entry/id (uuid)
 :entry/amount 50M
 :entry/debit-account :asset/cash
 :entry/credit-account :liability/prepaid
 :entry/post-date "2016-12-01"
 :entry/movement new-payment}
 ] recognize
 prepaid amount Initial Balances: 
 Current Limit: R$ 900, Current Limit Offset: R$ 900
 Late: R$ 100, Payable: R$ 99, Interchange Revenue: R$ 1 Final Balances: 
 Current Limit: R$ 1000, Current Limit Offset: R$ 1000
 Cash: R$ 150, Prepaid R$ 50, Payable: R$ 99, Interchange Revenue: R$ 1
  • 29. {:payment
 {:id (uuid)
 :amount 150.00M
 :post-date "2016-12-01"}} [{:entry/id (uuid)
 :entry/amount 100.0M
 :entry/debit-account :asset/cash
 :entry/credit-account :asset/late
 :entry/post-date "2016-12-01"
 :entry/movement new-payment} amortize debt {:entry/id (uuid)
 :entry/amount 100M
 :entry/debit-account :asset/current-limit
 :entry/credit-account :liability/current-limit
 :entry/post-date "2016-12-01"
 :entry/movement new-payment} increase limit {:entry/id (uuid)
 :entry/amount 50M
 :entry/debit-account :asset/cash
 :entry/credit-account :liability/prepaid
 :entry/post-date "2016-12-01"
 :entry/movement new-payment}
 ] recognize
 prepaid amount Initial Balances: 
 Late: R$ 100 Final Balances: 
 Cash: R$ 150, Prepaid R$ 50
  • 30. THE STATEFUL FLOW - Movements in the past will modify all future balances - Adapters are a function of the event payload AND current balances - Balances can’t change during calculations - Can’t allow for data to be corrupted depending on the order of the events INVARIANTS
  • 31. INVARIANTS - Some balances can’t coexist (no late alongside prepaid) - We can establish invariants that must hold true at all times - Some balances can’t be negative (cash) - Some can’t be positive (credit-loss)
  • 32. THE STATEFUL FLOW EVENT f(payload, ) ACID transaction f( ) VALID STATE? FIX VIOLATION INVARIANT VIOLATIONS? NO MOVEMENT[ ] Cr: Late
 Dr: Cash
 R$ 150 Cr: Late
 Dr: Cash
 R$ 150 MOVEMENT WITH CORRECTION[ ] Cr: Prepaid
 Dr: Late
 R$ 50 Initial Balances: 
 Late: R$ 100 Final Balances: 
 Cash: R$ 150, Prepaid R$ 50 [ ] VIOLATIONS YES Negative 
 Late 
 Balance
  • 34. CHALLENGES - Fixing invariants logic is extremely complex. - Datomic indexing is tested until 10 billion facts. - Datomic isn’t the best option for analytical workload, especially with sharded dbs - Other services bugs may generate incorrect entries that will need to be fixed
  • 35. GENERATIVE TESTING - We generate random events from our schemas (bill, purchases, payments, etc) - Write a function that describes a property that should always hold true 
 instead of describing input and expected output,
 - Properties that should hold true are the same invariants that are guaranteed in prod - Embed the least amount of domain logic assumptions
  • 36. GENERATIVE TESTING (def balances-property (prop/for-all [account (g/generator Account)
 events (gen/vector (gen/one-of [(g/generator Purchase)
 (g/generator Payment)
 ...]))]
 (->> datomic
 (consume-all! account events)
 :db-after
 (balances-are-positive!))) (fact (tc/quick-check 500 balances-property) => (th/embeds {:result true})) (ns double-entry.controllers.rulebook-test
 (:require [midje.sweet :refer :all] [clojure.test.check.properties :as prop]
 [clojure.test.check :as tc]
 [schema-generators.generators :as g]
 [clojure.test.check.generators :as gen]))
  • 37. MONITORING / REPLAY HISTORY TOOLING - Other services have republish endpoints 
 (same payload and meta data as original thanks to datomic) - We set sanity checks to make sure events aren’t missing - We have an endpoint that can retract all entries for a customer
 (resets business timeline, but not DB)
  • 38. SHARDING BY CUSTOMER / TIME - No cross customer entries allows for per customer sharding - We shard the database by time fairly often. - simple representation of the end state of the customer at a time shard: 
 final balance of each of the book accounts - As time passes, any single customer’s db will approach infinite datoms
  • 39. ETL extract logs facts to table
 (one per entity type) tables stored applies functions to generate balances balances on redshift* * also accessible through metabase
  • 41. Text placeholder 2015-01 2015-04 2015-07 2015-10 2015-01 2016-03 REAL TIME BALANCE SHEET
  • 42. 2 TIMELINES ACTUAL (DB) TIME audit trail / Datomic log “when did we know”day 0 day 30 day 90 BUSINESS TIME official version of events uses business-relevant “post dates” can correct after the fact day 0 day 30
  • 43. WHAT WE LIKE - Canonical definition of our most important numbers - Financial analysis applied at a the customer level in real-time - Business-specific invariants provide safety - Generative testing finds real bugs - Ability to replay history for a customer without losing data - Shardable by time and by customer - Extensible to other products (some don’t require stateful approach) - Inconsistency traceability allows us to react to it
  • 45. Watch the video with slide synchronization on InfoQ.com! https://www.infoq.com/presentations/nubank- financial-systems