Wealthfront is a technology company. We believe software is the key to building products that help our clients build wealth, and our relationship with technology directly determines how good we are at building this software. When engineers onboard at Wealthfront, we give them this document, our Principles of Engineering Culture. These principles describe Wealthfront’s relationship with technology and the way we as engineers fulfill our goals during our time at Wealthfront.
We didn’t choose these principles arbitrarily: they are based on experience and reason. They do not describe the way things accidentally are but describe the way we intentionally made our culture to be. Our engineering culture directly influences the company’s relationship with technology and therefore the type of company we’re building. As a result, these principles have not changed much since our early days.
Principles of Engineering Culture
Ground-Up Quality and Infrastructure
We believe our organization is most healthy when engineers, not management, propose and drive platform improvements.
New products and problems are often brought to engineering teams to solve, but then technical leadership of these teams interweave these priorities with necessary infrastructure as part of their platforms’ continued advancement in engineering quality. While it is the team’s job to propose and defend these improvements, it is then management’s job to internally align and clear the path for the improvements to happen. The alternative would be for management to command infrastructure projects that teams then find time to execute. Such management decrees are avoided as they lead to poor trade-offs and unhappy teams.
Wealthfront gives engineers two explicit tools to advance ground-up infrastructure. However, Wealthfront is not a faceless bureaucracy, and engineers should not feel limited to these tools when a need appears.
- The first, proportional investment, is a near-term prioritization tool by which any engineer may interrupt their work to fix issues which annoy them or cause them toil. The only requirement is that investment is made roughly proportional to the toil of the annoyance.
- The second, quarterly planning, is a team’s chance to formally propose and defend larger quality and infrastructure initiatives. It is intentional that this prioritization is done alongside product project planning. We don’t believe engineering or infrastructure live in a vacuum, and our engineers should always have enough context into Wealthfront’s long term strategic vision to make prioritization trade-offs.
Build over Buy
We believe that most tech companies our size overstate the benefits and understate the costs of using third-party software. At Wealthfront, we almost always prefer to build our own software than use others’.
In-house systems tend to be much smaller and therefore less complex, are built to solve Wealthfront’s own problems more directly, are more understandable, and are more easily modifiable by our engineers. Integration with third-party software is usually much more complex than expected and introduces hard constraints on the reliability and extensibility of our solution.
We don’t want to solve some classes of extremely complex technical problems like databases. However, we have more faith in our own engineering systems and our own ability to solve technical problems than others. When tempted to adopt someone else’s code, we often, but not always, find our core problem is better solved directly through our own means.
We don’t hire engineers who know how to glue systems together with configuration. We hire engineers who write code. Writing code is what we excel at as an organization. Therefore, solving a problem by writing code is likely going to be the best solution. Having to write additional code or modify existing code to add a feature or change some behavior is not an anti-pattern, it is the ideal approach.
Individual Ownership
We believe individual engineering ownership of projects and code creates the highest quality engineering systems and the highest quality engineers.
Design docs are assigned a single author who proposes and defends a single solution and its scope. The best design docs often include ideas from wide collaboration, discussion with experts, and sometimes even public debate, but ultimately a single author proposes and defends a single solution. The alternative, design-by-committee, biases towards solutions clouded by the least knowledgeable (or even worse, the loudest) engineer in the room. At Wealthfront, the design doc author defends trade-offs of quality and scope, as designing and scoping a system are deeply intertwined.
All code and systems at Wealthfront are owned by specific groups of engineers organized into on-call rotations. These teams ensure the continued health of the systems they own. In turn, these teams are led by a single engineer, the on-call lead. The on-call lead ensures the continued health of the rotation. It is not expected that any system is owned by the same group of engineers indefinitely. Instead, it is important that every system has a group of engineers as its maintainer, and that every group of engineers has a single leader with ultimate responsibility.
Individual ownership at Wealthfront does not preclude openness, and our culture discourages gatekeeping and feeling defensive of any system. The owner of a project or system is always happy to empower others to make positive changes, and as a result any engineer has the ability to read and propose changes to any code at Wealthfront. Because all are given this power, engineers are expected to understand the limits of their expertise and to properly weigh on-call alignment trade-offs.
Engineering as Part of the Product Lifecycle
As an engineering-centric company it is crucial to our identity that engineers participate in and drive the advancement of products at Wealthfront.
- Engineers are informally involved in the early stages of a new product, as ideas and constraints flow back and forth between the product team and knowledgeable engineers.
- After the product’s value proposition has been established, individual engineers play a lead role in defining and refining the project requirements.
- Engineers are then solely responsible for writing design docs, scoping projects, and incorporating the new product into the long-term vision for their platforms.
- Engineers are responsible for successful execution of their projects, including making the correct quality-vs-speed trade-offs.
- Engineers are responsible for testing their code and rolling it out safely according to Wealthfront practices.
- After launch, engineers are responsible for stabilizing and maintaining new code in production.
This entire lifecycle from building to testing to maintaining code is driven by the same engineers and forms a powerful feedback loop forcing higher-quality code and products. For these reasons, we don’t believe in a one-way flow of information from product to engineering, we don’t believe in outsourcing QA, we don’t believe in a strong separation of ICs and project execution, and we don’t believe in any separation of project engineers and on-call engineers.
Automation
We believe in the power of automation to deliver products more safely and cheaply than otherwise possible.
The combination of our other cultural principles, including our engineering-centric mindset and our propensity to build-over-buy, uniquely allows Wealthfront to automate our products and processes to a degree that our competitors can’t. This in turn allows us to offer sophisticated financial products to more people.
In addition to allowing products to scale, we believe automation leads to higher-quality and more accurate systems than human-powered systems. Intensive automated testing allows us to verify a depth and breadth of changes not possible with human testing.
At the same time, we believe in incremental automation. New processes cannot and should not be fully automated from the day they’re launched. Instead, the most intelligent automation comes from running systems in production and observing real data and real usage patterns.
Understandability
We believe the key design principle to successful software systems at scale is understandability and its corollaries: simplicity, uniformity, and testability.
Simplicity is the design principle that systems should be only as exactly complicated as required to solve a problem but no more. Simplicity is not a principle that is solved for once at the time of design. Instead, old and new systems are continually made simpler and more understandable (refactored) as our understanding of the problem changes over time. Simplicity also reminds us not to over-engineer systems and solve for use cases that do not exist yet. It is a good thing to have an idea of where you want to evolve the system, but it does not mean you have to build everything now.
Uniformity is our goal: we aim to have our entire codebase appear as if written by a single engineer. This design principle allows engineers to quickly gain context into new parts of the codebase, multiplying the efficacy of each engineer. Without it, we would silo our organization. We codify the minutia of uniformity in our style guides, and we perpetuate our common patterns through education and communities-of-practices. Our preference for code uniformity sometimes leads us to prefer building over buying and old patterns over new, but it is ultimately only one factor of many in engineering decision making.
Testability is our design principle that all systems should be built in a way that facilitates strong automated testing. In most cases, this leads to composable code that is easy to understand.
Testing
We believe our suite of automated tests is our greatest physical asset. Our suite of automated tests is as important as the rest of our code base. If we were forced to choose between keeping our automated tests or keeping the rest of our code base, we would always choose to keep our automated tests. New production code should always be written in a way that facilitates testing, and it is perfectly ok to change existing production code to better facilitate testing.
Automated tests are where our engineers show the mastery of the programming language and tools. It is where we deploy sophisticated, creative solutions to maximize the confidence our tests give us.
Tests naturally provide our documentation. Our tests capture desired behaviors but also our institutional knowledge built over time. The purpose of automated tests is first to give us confidence in our code, but they also provide our primary source of compilable documentation that never goes stale. This means we actively discourage code comments and written documentation. In almost all cases, we believe written documentation is better expressed as a type system constraint, automated tests, cleaner APIs, or a point-in-time (design doc or commit) comment.
We believe “code coverage” is a harmful metric. In our tests we optimize for confidence and readability, constantly making dozens of trade-offs in areas like style, uniformity, and thoroughness. Tracking “code coverage” can sometimes be useful as a tool, but when used as a metric only distracts from these goals.
We do not tolerate flakey tests. The primary purpose of our tests is to provide confidence in our production code. Therefore, any test that questions this confidence is harmful.
Our strongest and most rigorous tests are our unit tests. Our unit tests, paired with clean and loosely-coupled APIs, provide the bulk of our confidence in our code base. We do use end-to-end tests to test the boundaries between large components. However, they are only our second line-of-defense, and we often view them as a crutch against messy and tightly-coupled components. We use manual testing only as a low-leverage last resort.
Development Lifecycle
We believe in rapid feedback as the key to successful projects, both in our products and our code.
When designing systems, we try to validate our core hypotheses first and quickly. Our hypotheses include our product and technical questions which are important to the success of our project, but for whatever reason cannot be answered before development.
To enable rapid feedback in our development, we work to have problems with our code fail early, always working to expose bugs earlier in the code lifecycle. Bugs that fail in production we’d rather fail on deployment. Bugs that fail during deployment we’d rather fail in tests. Bugs that fail in tests we’d rather fail during code compilation.
When designing systems, we think carefully about the problem we’re trying to solve independently of possible solutions. Then, when choosing a solution, we acknowledge that there is no absolute best solution. Solutions do not exist in a vacuum and are heavily context-dependent. Furthermore, context changes over time. So, when designing systems we discuss and debate tradeoffs.
When developing, we write small changes, then have them reviewed, committed, deployed, and exercised quickly. It should never take more than 30 minutes for your changes to be running in production, and we deploy new code sometimes hundreds of times a day. We believe large pull requests and long-lived code branches make it difficult to get the feedback necessary to course-correct our projects. Additionally, any unmerged code is a liability for our peers. Our peers cannot work with it, work around it, or improve it.
Conclusion
We do things differently at Wealthfront, and we are proud of it. As engineers we take in pride in writing quality code but at the same time wear many hats for many functions. We write our own infrastructure, care about costs, and run our own servers on-prem. We directly influence the products we build and let our products influence our platforms in return. Ultimately, this is all in service of our mission of building a financial system that favors people not institutions. If this is exciting to you, join us!
Disclosures
The information contained in this communication is provided for general informational purposes only, and should not be construed as investment or tax advice. Nothing in this communication should be construed as a solicitation or offer, or recommendation, to buy or sell any security. Any links provided to other server sites are offered as a matter of convenience and are not intended to imply that Wealthfront Advisers or its affiliates endorses, sponsors, promotes and/or is affiliated with the owners of or participants in those sites, or endorses any information contained on those sites, unless expressly stated otherwise.
All investing involves risk, including the possible loss of money you invest, and past performance does not guarantee future performance. Please see our Full Disclosure for important details.
Wealthfront offers a free software-based financial advice engine that delivers automated financial planning tools to help users achieve better outcomes. Investment management and advisory services are provided by Wealthfront Advisers LLC, an SEC registered investment adviser, and brokerage related products are provided by Wealthfront Brokerage LLC, a member of FINRA/SIPC.
Wealthfront, Wealthfront Advisers and Wealthfront Brokerage are wholly owned subsidiaries of Wealthfront Corporation.
© 2024 Wealthfront Corporation. All rights reserved.