Stack-Decision Phase

Wei Wei
Flux | Engineering
Published in
4 min readFeb 8, 2019

First few months of engineering in a startup is the “stack-decision” phase. Every week or two we introduce something new into the stack, from a language, a service, to a library, a productivity tool, etc. It’s an amazingly exciting period. You know lots of these decisions will be changed later, but more will stay. And the ones stayed will have a significant impact in the coming years. People who join in the future will inherit a stack, and curious ones will ask reasons behind the decisions. It’s better to record stack decision reasons along the way. So later on when we review decisions, we can examine reasons to find out which are still valid, which are outdated due to situation changes, which are just wrong due to our knowledge and experience limitations.

This post won’t go through every stack decision we made but will try to record on a meta level. What are the main factors to consider when a seed-stage startup choose tech stack?

Existing Experiences

First, let’s be practical. It’s great and fun to learn new things, and startup life is constant learning. But we do need to consider a team’s existing skill sets. You don’t want to spend the first month of a startup to send everyone to learn a programming language from scratch, at least when there are no enormous benefits over options that team members are already familiar with. Carefully weighing learning cost and benefits is often the first thing we consider.

We start with a mobile-friendly web app in Flux. So one of the first tasks is to choose a web language and framework. I picked up my dusted Ruby on Rails skill to write a demo app to feel out Rails 5, then wrote the same thing with Node.js. It took about the same time. I’m familiar with jQuery-era JS although I never wrote Node.js application before. It was easy to pick up Node, and other team members know JS pretty well. And I liked the unopinionated philosophy of Node and the “less-magical” aspect. So we settled on Node.js.

Examples we picked (existing experiences): Node.js, AWS, CloudFormation.

Abstraction Level

Another main factor is whether to use a high-level or low-level option. It often evolves to the classic “Build vs. Buy” dilemma because a high-level option is usually a SaaS product nowadays, and there are so many of them!

As a startup with only a few engineers, we generally prefer high-level options because it’s like outsourcing the infrastructure work to another team who is professional, but we also need to be careful about the quality of the abstraction. Unstable or messy abstraction can be more time-consuming than no abstraction.

Level of control we’re giving out by using high-level services is also a concern but usually a lesser one. A startup should have laser-focus on the “core” problem, so it’s unlikely we will have time and resource to fine tune other things.

Examples we picked (high-level abstraction): Datadog, Auth0, Elastic Beanstalk.

Maturity

Developers like to live on the edge. But when choosing tools for a product, we need to know where to be adventurous and where to be rock solid. Very new tools tend to be less verified and more problematic. It’s not fun to work with too many floating pieces. So we generally prefer tools with a certain level of maturity for the sake of stability.

Good maturity should also mean an active community, so we can find solutions to common questions and issues easily, exchange ideas and experiences with the community. Commercial products’ support can also play a big part in this front.

Recognizing maturity doesn’t mean we always choose the oldest and safest option. There are some “new kids on the block” that have gained popularities and become mature enough for us to give it a try. There are also cases that older options show signs of falling apart or lack of maintenance. It sometimes relies on some experienced engineers’ intuition.

Examples we picked (very mature or very new): Jira, Express.js, Bitbucket Pipeline, Vue.js, Cypress.io.

Scalability

The last point I want to cover in this post is scalability.

One aspect is to scale up. A programming library or an authentication service needs to handle system traffic increase seamlessly; a project management tool needs to work well when the team grows to 10x size. We’re not only picking stacks for today, but also for tomorrow. Decisions that are hard or expensive to change should be made with future needs in mind when the system and company grow.

The other aspect is to scale down. For a money/resource-constrained startup, we usually favor systems that have a moderate minimum ,cost when the usage is light, so the trial-and-error process is less costly. I would say a data loading service that charges at least 1k$/month even when your usage is near zero is not very startup-friendly. Fortunately, lots of services targeting startups offer either free or introductory/pay-as-you-go plans to lower the entry barrier. That’s a smart way to gain new customers. Then as long as the cost scales with usage linearly or sub-linearly, we’re good to go.

Examples we picked (scalability): Postgres, AWS Lambda, Stitch.

Finally, if you’re interested to see Flux’s tech stack, check out https://stackshare.io/flux-work. We’re excited to go through this phase and make choices, hopefully more right ones than wrong ones. If you have any thoughts, welcome to reach us at journeys@fluxwork.io.

--

--