Under the Hood: Engineering at Revolut

Revolut
Revolut Tech
Published in
7 min readMay 20, 2020

Under the Hood: Engineering at Revolut

Revolut’s success since its 2015 foundation is in no small part due to the dedicated team of engineers who have built our app from the ground up. From Backend to Mobile, Revolut’s engineers are dedicated to delivering a seamless experience to all our customers around the world. Through our strong interpersonal relationships, we encourage organic personal and professional development within the engineering function, and it all starts with how we approach engineering at Revolut. In this article, you’ll learn about

  • How the team works,
  • Revolut’s development culture,
  • Revolut’s 8 engineering principles, and
  • What we look for in potential Revoluters.

How the Engineering Team at Revolut Works

From Revolut’s inception, our engineering team has been encouraged to function as a startup within a startup: they’re a self-led team with the freedom to innovate as they develop Revolut. They’re inspired to ‘act like a founder’ and think big; we believe that great ideas can come from anyone. Revolut is committed to delivering the best possible product that we can create, so any time someone comes forward with an improvement or suggestion, it’s taken seriously. We’ve made it easy for these ideas to become reality by streamlining approval processes.

Teams are encouraged to share their experiences during weekly full stack team catch-ups where they discuss releases, proposals, improvements, and troubleshoot questions. This is supported by strong inter-team communications channels that pool requests outside of weekly meetings. We’ve created an environment that creates opportunities to get involved, contribute, and learn from teams outside your own — our engineering teams aren’t isolated from each other.

Engineering at Revolut is the foundation and lifeblood of all that we do. Our teams work cross-functionally with every other team at Revolut directly and indirectly, creating our products and supporting our people.

Development Culture

Our development culture is built on two pillars: sound technical solutions for our business problems, and efficient communication.

Building sound technical solutions

Through the main stages of our engineering and production process, we build in methods that ensure that we’re doing things in the most logical, business-sensitive way:

  • Roadmap planning and prioritisation based on the team’s objectives, user feedback, and how they affect risk and business debt.
  • Solution design (UX) is represented by visual screen flows or diagrams that show data flows and process logic. Our systems and applications are modelled on DDD (Domain Driven Development). Services communicate through events, and we have found following Command Query Responsibility Segregation (CQRS) to enable simplicity, scalability, and team performance.
  • Solution approval by the Enterprise Risk Committee to mitigate potential financial or reputational, or other risks. We operate in a regulated industry, which means that the decisions we make need to go through a certain level of mandatory regulatory scrutiny, but we try to make it a no-nonsense process.
  • Software implementation — individual teams organise their work differently. Some may be more into Kanban, some use iterative Agile, while some pair more than others. Every single pull request needs to pass the review stage, will be built by CI server (we use TeamCity), and will trigger a huge battery of tests (tens of thousands). Only then can it see production. In practice, if this is all good, you could see your code in production within the hour.
  • Continuous integration and delivery (CI/CD) which helps us build something that can be released to production at any time, encouraging our engineers to implement incremental changes frequently. This reduces uncertainty to a minimum.
  • Production release through blue-green deployment, allowing us to take software from the final stage of testing to live production with no downtime. This approach also gives us a rapid way to roll back an unstable version. Hotfixes will take longer than rollbacks.
  • Application and database configuration review — the configuration is environment-specific and is maintained together with the infrastructure code. Platform DevOps Engineers must review and approve all configuration changes prior to integration into the main branch.
  • Learning through post-mortem culture — sometimes an incident may occur that causes downtime, service unavailability, or data loss. It is very important to learn from failures and prevent the same mistakes from repeating. Therefore, we perform post-mortem analysis — finding the root of the issue, recording actions taken to eliminate the issue, and sharing the acquired knowledge in order to respond efficiently to similar issues in the future.

Communication

Primarily, we advocate for direct, face-to-face communication. However, with a global workforce, that may not always be feasible, and there will be situations where we must record information for future use. That’s why we use Slack, Atlassian Confluence, and JIRA to support our internal communication.

Roadmaps of some product teams may overlap, and different teams may share codebases or work on the same parts of the app. To make sure everybody has the full picture, we hold a weekly sync meeting where Product Owners share news on their developments and their teams’ goals.

Good communication between front-end, back-end, test engineers, and designers is crucial throughout the implementation phase when changes are applied to agreed designs/contracts/interfaces. Design and solution review may require that a back-end engineer and a front-end engineer work closely and sync daily until the interface contract is fully agreed.

Revolut’s 8 Engineering Principles

Inspired by eXtreme Programming (XP), Revolut applies a number of modern agile practices to the way we approach engineering at Revolut. Our aim has always been to deliver high quality software, fast. This approach requires structure, and so Revolut created a set of eight engineering principles to apply to every engineer, no matter which team they were in.

1. Simplicity

It seems obvious, but it’s a cliché for a reason. Simpler software architecture is proven to be more stable, secure, flexible, and scalable. This can be seen on many different levels: from application code and test code, to module structure and overall system design. At the core of our designs, we put low coupling and high cohesiveness, and decrease the number of abstraction layers to what’s absolutely necessary.

2. Feedback

Every voice counts. Whether that’s from users, testers, or other engineers at Revolut, we listen to what they have to say to create a better experience overall. Our products and features all go through a number of release stages, starting with the team, working up through others at Revolut, handing over to our beta users, and then with a full release to our retail and business users. It’s important to seek feedback proactively at every stage of product development, and we’ve built in approaches to do that: solution design reviews, pair programming, test-driven development (TDD), code review, continuous integration, user feedback, and monitoring and alert systems.

3. Expectation Driven Development

This is important to us because of the high security needs that we have as a financial service provider. Our software should not be permitted to work when unexpected scenarios are attempted — the system should reject those cases. This exclusivity principle allows us to build a very robust design and implementation, prompting us to learn, and adjust our expectations.

This principle is strongly aligned to Revolut’s appreciation for TDD, where engineers should formulate all expectations explicitly in test code before implementing them. This protects the application code from accidental bugs and changes.

4. Automation

We reduce human error and free up time for creative work by automating as many processes as possible — from coding and testing, to deployment and maintenance. A notable example of this is our Continuous Integration/Continuous Delivery (CI/CD) process. In this process, all code changes should be covered by automated tests. When the changes are submitted to the Version Control Software (VCS), they are automatically picked up and built. Any successful server build is automatically deployed to the staging environment without downtime, and is by default considered ready for production deployment. Feedback loops and server API documentation generation should also be automated to ensure efficiency and consistency of information.

5. Continuous Improvement

At Revolut, we have a Minimum Viable Product (MVP) approach. This enables us to introduce new products and features at optimal cost and time, all while maintaining a high quality of execution and flexibility to make corrections based on all kinds of feedback.

We don’t consider the current state to be final. All systems and solutions should be continuously and periodically reviewed and improved through refactoring. As systems and code tend to become complex, continuous refactoring is necessary to retain simplicity, maintainability, and clarity. It also aids us in discovering corner case issues and vulnerabilities that were not captured in our automated and manual feedback loops.

6. Code Quality

As a tech company, every business decision is reflected in our systems in the form of code. Therefore, our application code and coded infrastructure should represent the real state of our customer-facing and internal business applications. That’s why it’s vital for our code to remain comprehensible and maintainable, and ensure it adheres to established standards and undergoes quality control and continuous improvement.

7. Data Integrity and Security

As a data-driven company, the integrity and security of our data is of paramount importance to our users and us as a business. To ensure seamless user experience, data should be highly available whenever a user makes a payment or chats to a customer support agent. We cannot lose data. We cannot leak data. Therefore we must undertake all available measures to protect it at all levels: code, system, database, infrastructure, and process.

8. Readiness to Scale

In just five years, we had reached over twelve million customers. As we reach more daily active users, our systems need to be prepared to service them with the same dedication that we give at every stage. That’s why we monitor and measure performance, and always consider short-and-long-term potential scaling.

What We’re Looking for in Potential Engineers

First and foremost, we’re looking for people who are aligned on our engineering principles and our drive to deliver products fast, and at high quality. You should have a strong love for programming, and demonstrate a breadth of knowledge of the newest technologies.

If you want to join our team, show us that you can create an app that is simple, useful, and properly tested. (TDD, remember?) We expect you to understand Java or JS-related technologies and concepts, as well as having knowledge of other areas like relational databases, data structures, and algorithms. You should be ready to communicate in order to participate in solution reviews, daily or weekly sync-ups, or post-mortems, and to work closely with your peers until successful version delivery. If you think you’re our next Revoluter, check out our Careers page to explore opportunities around the world.

--

--