Startup Engineering & Internationalizing Wealthsimple

Here at Wealthsimple, we're growing quickly on all fronts: assets under management, clients served, services provided, company size, and — most relevant to this blog post — geography. Just earlier this year we launched in the US, and a couple months ago we announced that we would soon be launching in the UK. As an engineer on the UK team, I'd like to share some observations from inside a startup just beginning to address the challenges of internationalization.

(Please note: This will not be a very technical piece; if that's what you're looking for, check out the other pieces on our engineering blog!)

The Challenges of Internationalization

Often when we speak about the internationalization of a web-based service, we speak almost exclusively about language (or other visible content, such as images). However, because Wealthsimple provides a service that requires working with different financial institutions in every jurisdiction we move into, our challenges include more than text translation. From an engineering standpoint, that eventually boils down to three things:

  1. Identifying and implementing services in this jurisdiction's financial system that help us reach feature parity with our existing geographies (e.g. a UK JISA could be considered equal to the Canadian RESP).
  2. Identifying and implementing jurisdiction-specific services (e.g. Direct Debit is supported in the UK, but not in North America).
  3. Integrating with financial services in the given jurisdictions to help us support these services.

With every geography that we expand into, all three of the above problems need to be solved again. This means that as we begin to grow faster, our ability to achieve the above needs to grow as well. As engineers, how do we organize both our code and ourselves to do this?

We'll get to the answer to that question, but first it may be helpful to answer how we got to where we are.

Being a Startup Was a Conscious Decision

Wealthsimple is only three years old. Still, we have over a $1 billion in assets, are about to expand into our third jurisdiction, and recently got a personal shoutout from Justin Trudeau! How did we achieve this? The answer is that we made a very conscious decision to keep startup engineering culture in our DNA. This means that we move fast. We iterate. We keep things simple. We take the path of least resistance.

If it's not obvious yet, all of the above means that we've made specific design decisions not to over-engineer. We solve the problems in front of us, not ones we expect to have 5 years from now.

But We're Growing

It's the usual story: lack of resources necessitate that everybody does a little bit of everything. The startup world is a world of generalists. However, as our organization changes and grows, so do our needs: we are now reaching a point when it makes more sense for us to have functional teams, and we have organized ourselves as such.

This is mostly good, but it presents specific challenges for internationalization:

  • As we move from a company of generalists to more specialists, we lose domain knowledge as people become more integrated within their functional specific teams. This means deeper domain knowledge, but increasingly less cross-domain knowledge. For example, a developer who works on onboarding might have little knowledge about how funding or trading work and vice-versa.
  • Supporting a new jurisdiction requires changes to all domains, as well as an understanding of how all the pieces fit together.

This leaves us with basically two choices:

  • Having every functional team do work on supporting each new jurisdiction, with a project manager coordinating between all the teams.
  • Assemble a special, cross-functional team dedicated to a project that spans multiple functional domains.

There are projects at Wealthsimple that sometimes require multiple teams to co-operate, but it is uncommon that 2-4 teams would need to co-operate for 2+ months. The cross-functional teams are often software development heavy at the beginning, with a lot fewer day-to-day operational demands.

The need to constantly ask for dev resources across functional teams would be very cumbersome and create unnecessary project management overhead. Having a cross-functional team with dedicated development resources and a specific mandate allows us to quickly get a project delivered.

Enter: The New Generalist

On the UK team, we're all generalists: we've dealt with accounting, we've dealt with funding, we've built out our own UK-specific UI within Wealthsimple, we run our own brokerage integration, and so on. In the short time I've been at Wealthsimple, I've had the privilege of touching a lot of moving pieces and learning how they all come together. It's an exciting team to be on, but it can also be challenging.

Right now, we are at the cusp of launching into the UK. This presents interesting challenges being on this team. There were some challenges with internationalization when Wealthsimple launched into the US, the first market outside of Canada. But even so, it didn't make sense then to refactor everything when we were just trying to support the US. This is especially true because many things in the US are similar to Canada. For example, both US and CA use '$' as their currency symbol, so we never had to add international currency support.

These similarities didn't exist with the UK, so this expansion across the pond acted as a great catalyst to tackling some of our technical debt.

Pain Points

Most of the engineering pain points the UK team has experienced is due to the fact that Wealthsimple simply wasn't written from the beginning to be internationalized. Here are some examples:

Most of the code defaults to Canada, with other jurisdiction logic added on through sprinkled-on if-statements or I18n translation files. This means that every time a change is made to the “default” code, there may be an unknown consequences to all the other jurisdictions. At times things break for seemingly no reason — but in fact, they were just working “by coincidence” before.

Example:
Team X team decides to do an overhaul of some of the X flow. In order to do this, a lot of the copy in the default en-CA translation file needs to change. When the UK team initially wrote their version of the X flow, much of the copy just happened to work perfectly: hence, no copy was written for UK and it was just using the default en-CA copy. When Team X pushes their changes to the en-CA translation file, much of the independent X flow for UK now has incorrect or broken copy.

Parts of our system simply take for granted: things that are a given in North America that are simply not true in other jurisdictions. This sometimes makes adding “trivial” features for other jurisdictions a bit difficult, since we have already made a bunch of assumptions that no longer apply.

Example:
It's usually safe enough to assume that somebody in the US will have a US phone number and the same in Canada. Hence, our phone number validation was written to reflect that: we didn't take into account country codes when validating, and representing things in national phone format. However, this assumption is not one we can make easily outside of North America and especially in the UK. Because our entire phone number validation and storage system was already built around the assumption that country codes didn't matter, we would have to do a complete overhaul of CA/US numbers just to support this properly for UK (lest we start adding a bunch of switch statements into our phone number validation!).

We don't have an abstract interface to interact with when adding a new brokerage for a jurisdiction. Since each time we move into a new jurisdiction we need to integrate with a third party, it takes a lot of domain knowledge about each Wealthsimple microservice to integrate things properly. This requires much more domain-specific knowledge from a cross-functional team than should be required, since all third-party brokerages regardless of jurisdiction essentially do the same thing.

Our Values and Doing What's Right

We'll keep moving fast, but given the pain points that have arisen, it's time for us to step back and make some bigger and better changes to our code. There is a bit of love and commitment that we'll be putting into overhauling our code so that it is more international and receptive to adding jurisdictional logic. This will make life easier for us, but more importantly, it will make it easier for us to achieve one of our company values: do what's right for each client.

In fact, what we have done in the past, what we're doing now, and what we'll do in the future all ties into our company values:

Simple is better (Simple is harder than complex)

Keeping things simple has been good enough to do what’s right for our CA and US clients, but it becomes increasingly more difficult as we add the UK and will add more jurisdictions in the future. We want to be able to adapt and be flexible to serve each jurisdiction separately, so we need now to pivot. It may make the overall architecture of our code more complex, but dealing with each jurisdiction will be much simpler.

Do what's right for each client

When we were a Canadian-only company, we cared most about doing what was right for Canadians: hence, we had all-Canadian defaults in our code. Given that we're growing quickly into other jurisdictions though, we can no longer give preference to CA this way. Wealthsimple is an international company and our codebase needs to reflect this.

Take care of each other

As a company grows and teams become more specialized, we need to stay cognizant of each others’ priorities and work so as not to step on each other’s toes. This is especially obvious when it comes to internationalizing a codebase that was built on one locale, and in order to take care of each other, we need to build in organizational — but more importantly, engineering — processes and architectures to help us consider all locales equally.

Dress to Impress

We try to go above and beyond what our clients expect of of us. This is a large reason as to why we didn't try tackling internationalization before now: it was important for us to make sure were giving our existing clients a stellar experience before tackling new markets.

We now want to deliver an amazing experience to the UK and more international countries. However, giving them the experience they deserve requires us to to tackle internationalization like never before.

Ship it

We need to enable all our teams to move quickly without worrying about accidentally breaking a jurisdiction or having to manually test each individual jurisdiction for every change. Given our growth trajectory, these requirements are simply unsustainable. For example, what would happen with 6, 10, or 22 brokerages? Sometimes we need to write some more tests and reduce our technical debt in order to ship things faster in the future.

Keeping it Simple

We're extremely excited to be growing the way we are, because each day, it brings us closer to our mandate. For all the writing in this blog post, better supporting internationalization is just a means to the ends we all want: making financial services for everybody accessible and simpler to use. All of us at Wealthsimple are passionate about this, and we'll do whatever it takes to do right and make sure our platform eventually does reach everybody: regardless of age, economic status, and jurisdiction.

Keep it simple!