Working with Clojure at Nubank

Lucas Cavalcanti
Nov 22, 2019 · 4 min read

A quick view on why we chose this technology and how we use it to fight complexity and empower people

Nubank has helped change the landscape of financial services in Brazil. We launched our first product in 2014, a no-fee credit card, and since then we grew to be the most innovative company in Latin America and the biggest independent digital bank in the world, with more than 15 million customers.

Our portfolio of products includes, other than the credit card, NuConta, a digital savings account; Nubank Rewards, a loyalty rewards program; Lending for personal loans, and Conta PJ, a digital account for small and medium business. Both Lending and Conta PJ are the most recent additions to our portfolio, introduced in 2019, the same year we’ve announced the launch of our operations on 2 new Latin American countries: Mexico and Argentina.

A big part of our success comes from the fact that we are not a financial company per se: we are a technology company, focused on developing financial solutions.

In other words: technology is at the heart of everything we do — which is why software engineering is a core competence for Nubank.

We strive for state-of-the-art software development practices, and Nubank has enjoyed significant benefits from embracing practical functional programming concepts to build our business. These concepts play an important role in the clarity and consistency of our codebase, and we put a lot of effort to make sure engineers understand them when they join the company.

These are a few examples of practices and techniques we employ:

  • Horizontally scalable microservices written mostly in Clojure, using Finagle and leveraging functional programming techniques and hexagonal architecture (more on that in this video);
  • High throughput jobs and inter-service communication using Kafka;
  • Continuous Integration and Deployment into AWS;
  • Storing data in Datomic and DynamoDB;
  • Monitoring and observability with Prometheus;
  • Running as much as possible in Kubernetes.

It’s interesting to note that most of our engineers had never worked with this particular set of technologies (which are either abstracted in a tool so they don’t have to know much about it or are easy enough to onboard on) nor had been in contact with financial services, which is a little bit harder to onboard, but we’d have to do it anyway, no matter what technology we choose.

Why Clojure and Functional Programming?

The world we live in has machines on the cloud, with multiple cores that allow us to run several things in parallel. Besides that, Nubank solves for the finance domain, which is very close to mathematical functions — and functional programming is a great fit for both scenarios.

The previous systems we’ve built before joining Nubank used languages and frameworks that force you to add too much boilerplate to solve a problem, which makes evolving the system harder and harder over time. Clojure, on the other hand, has simple constructs that allow us to focus on the problem we are solving, making evolving the system a small incremental challenge, which doesn’t get that much harder over time.

Most of our codebase can be understood locally, looking at any given pure function, understanding its outputs for any given set of inputs. There’s rarely any need to reason about or recreate the internal state of objects. Data moves through the system in a composable, inspectable, consistent, and immutable way (without hiding it inside of objects).

We’ve built a number of enablers in Clojure over the past 6 years — useful tools that help us be faster and scale at an accelerated pace. With Clojure, we can create new products in a very easy way. When it comes to infrastructure, for example, we have a continuous delivery pipeline that enables any given change to master on GitHub to be running in production within 30 minutes, with the aid of declarative EDN configuration files that define how the deployment and the pipeline look like. Functional code is much easier to test, and that gives us the confidence to deploy an average of over 50 changes per day in a mission-critical domain.

Speed is crucial at Nubank as we’re growing our customer base and expanding to new segments and geographies. We are constantly evolving our product and structure — which is why we are constantly looking for people to join our team.

Engineering at Nubank

We currently have over 400 engineers working from our HQ in São Paulo, our engineering hub in Berlin and our offices in Mexico City and Buenos Aires. And we also nurture a global environment regardless of the office in which you’re located since we host more than 30 nationalities and English is our first language.

We’re looking for individuals who are really passionate about what they do and are eager to solve complex problems at scale, all while working in a safe, welcoming surrounding who want to see their work having a positive impact on the lives of millions of people who, otherwise, would be stuck in a bureaucratic and inefficient relationship with their money.

So, if you see yourself working here, do not hesitate to hit us up on

By Lucas Cavalcanti and Wilker Lúcio

Building Nubank

Nubank's Tech Blog

Lucas Cavalcanti

Written by

Principal Engineer @ Nubank

Building Nubank

Nubank's Tech Blog

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade