Freedom of technology choice
We practice what we call “freedom of technology choice” in FINN. This means that everyone is encouraged to choose the tools best fit for the job*. In this post, we’ll look into how we got here, what this means in practice and what trade-offs this comes with.
* As long as the decision is supported by the rest of the team
In the early days of FINN
As the business grew, the number of teams grew and the monolith code base grew. Over time, this stopped scaling, then entered microservices. Henning Spjelkavik (architect at FINN) gave an excellent talk at NDC 2019 about this journey:
An inherent property of a microservices architecture is that each service can be built in isolation. This implies that a service can be built fundamentally differently from other services in the system, as long as they agree on how to communicate. By moving onto this architecture, teams were able to experiment with new tools, programming languages, and technologies.
Where does this lead to now?
At FINN we currently have ~1000 running services of varying sizes. Most of these services run as a Docker container on Kubernetes. These services are owned by roughly 35 teams, and team sizes in FINN usually vary from 3–12 people. Each team usually owns multiple services. When each team is empowered to decide on what tools to use, we naturally ended up with a bunch of different technologies. A glance at our Github Enterprise organization shows that we have
- 234 repositories in Java
- 140 repositories in Kotlin
- 51 repositories in Python
- 48 repositories in Scala
- 39 repositories in Go
- 30 repositories in Swift
- 22 repositories in Haskell
- 4 repositories in Rust
Note: Counting repositories only gives a simplified view of technologies used in FINN. It does not factor in repository sizes, activity or impact in any way.
Java is still the dominant language used at FINN when counting repositories. This is historically bound to where we came from (a lot of libraries and support systems were traditionally written in Java). In addition to the strong domain knowledge of that programming language within established teams.
Kotlin has sailed up to be a strong contender to Java though, especially after this language was endorsed into Android. Most of the native FINN Android app is written in Kotlin. The easy migration path from Java to Kotlin has also led to some teams migrating their existing codebase to Kotlin. As has been the case with FINN Reise.
Python making this list is due to the tooling around Python for working with machine learning models, such as the ad recommendations model. In addition to some infrastructure support systems and one-off web services where a scripting language made sense.
Go has seen adoption in FINN especially with the teams working on infrastructure. One reason for this might be the good interoperability with Kubernetes and GCP. There are also quite a few small-ish product APIs built in Go, so the language is getting a decent following in FINN.
Scala & Haskell shows that some teams at FINN lean into the functional programming paradigm. The beloved heart component you see below is served by a Haskell service.
All of the backend applications built by the Personal Finance team are written in a functional-style Scala.
Swift is exclusively used for building the native FINN iOS app.
Rust for an honorable mention as there is exactly one service running in production written in Rust. Who knows, over time it might gain traction as it’s an interesting and unique language!
What’s interesting though is that we’ve run into some of the same scaling issues with frontend technologies as we did some years ago with backend services. This is one of the reasons why Podium was created.
A page in FINN is usually composed of multiple components, each component possibly owned by separate teams. Traditionally when a team was to change a component, they had to jump into an unfamiliar codebase, often with a completely different stack than they usually work with. In addition, they were limited by the technology chosen by the team owning the system that rendered those pages. When finishing up with a code change, it had to be reviewed by someone familiar with the code base. After that the whole frontend app had to be deployed.
Podium solves this by letting each component (podlet) run in isolation, and then these components are composed into a full page (layout) by requesting them over HTTP. Providing shared components as a service, rather than a library. This also makes it possible to deploy a fragment of a page instead of the full frontend powering the page. This greatly reduces the cognitive load when developing new features.
Each team selects the frontend technology of their choice for their core surface. However when they are to write a component that’s supposed to be injected into the surface of someone else they must adhere to a strict standard.
Well, are there any trade-offs?
We believe that the builders of things are best fit to decide on what tools to build with. And that this is an opportunity for the organization to learn new technologies, methodologies, and ways of working. However, this also may come with some costs.
It’s harder to build shared components that solve a common thing for multiple teams. Logging or monitoring are examples of functionality that traditionally was solved as shared components in FINN. Now each team has to evaluate this when assessing a new tool. On the flip-side, it nudges us into building on common software such as Prometheus, instead of rolling our own.
Onboard a person or team
Having a wide variety of tools and programming languages can make it harder to onboard people from other places in the organization into a project. It’s also harder to transfer ownership of a component or service since the receiving end might not be familiar with the technology. Some would argue this presents itself as a good opportunity to learn something new.
Going niche can make hiring harder
With a specialized stack, it can be harder to find talents experienced in that stack. We sometimes see this when hiring for teams that primarily work with functional programming. When we do end up finding the correct person for the job though, they often tend to be motivated not only by building cool products at FINN but also by the particular technology.
As FINN grows as a company I think we’ll see further diversification of types of technologies in use. I see this as a healthy sign of a tech organization and it means that we dare to test out new technologies. This diversification won’t come without any pains. But I think that solving those pains will also make our architecture and platform stronger since solutions emphasize clear boundaries between teams and shared responsibility within the teams.
By continue building a culture for knowledge sharing and experimentation within FINN I’m certain we’ll learn new things that will be the technology FINN runs on tomorrow.