The perfect tech stack
How to pick the right tech stack for your startup
Ugly but effective
You know what sucks? The LAMP stack. On almost every front, it’s a lousy web stack. There’s a real sense of shame attached to the label “PHP developer”. But you know what powered some of the most insanely successful startups in the last ten years? The LAMP stack.
As a technical founder, your job isn’t to pick the “best” web technologies, it’s to pick adequate technologies that will make you best. What is the stack that will be fastest for you to ship a product? If you can whip up a LAMP app in no time, go with that. If you live and breathe Rails go with that. If you love MERN (my personal favorite) go with that.
Originally, Droplr started off as a CodeIgniter app, much to my shame in those days. I remember a palpable sense of embarrassment when I had to admit to some developers that Droplr’s API was nothing more than a bunch of PHP scripts connected to a MySQL database. But who the hell cares? The job wasn’t to build the most elegant API on the sexiest tech stack, it was to upload a file and give a user a link. It was great at that and that was the criteria our customers judged us on. Under the hood it was ugly but it was effective.
So bottom line, you should already know what the ideal tech stack is for your startup and you can stop reading this article Pick what you’re best in.
But here’s the tech stack I would use if I were starting a new project today. This is what is right for me. If it’s not right for you, that’s ok.
Different types of application logic
At the core, every web app is going to contain pretty much the same thing:
- Synchronous logic (do this now)
- Asynchronous logic (do this and report back when you’re done)
- Scheduled logic (do this every hour/day/week).
If your project makes use of HTTP (of course it does), it’s going to contain a lot of synchronous logic. For example. REST APIs are going to be fundamentally synchronous, I.E. I want to query an endpoint and get back a list of objects. There’s no option for a HTTP request to report back later, it needs to give a result as quickly as possible. If it takes too long it fails (or throws a timeout error). Most basic web frameworks (Express, Rails, CodeIgniter) are built around synchronous logic.
But don’t be fooled, asynchronous logic can be just as important. What if you need to write a service that takes a screenshot of a url at five different screen resolutions, in different geolocations, and then shows the result to the user? Most likely there’s no way you can do that synchronously in a single HTTP request. And you don’t really need to: the user can wait until the logic is complete to get the result. It’s an ideal case for asynchronous logic. Chances are, your app is going to need to run asynchronous logic. Your tech should be ready to handle this. Don’t make it an afterthought.
Finally, scheduled logic is something that often gets forgotten but it can be actually very important. How are you going to backup your database? Track daily statistics? Send weekly email digests to your customers? These are all examples of scheduled logic. Maybe you’ll be able to get by for a few iterations without a good solution for scheduled logic but chances are you’ll need it sooner than you think.
On top of all this, whatever solution you choose needs to be fast: fast to develop, fast to deploy, and fast to debug. When you’re starting out, always choose speed over scalability.
If you already have a solution that meets these requirements that you can code crazy fast in, great! Use that one. But if you don’t, I’d recommend Node.JS + Serverless + MySQL/Postgres/Aurora or Mongo/DocumentDB as an ideal choice for your tech stack.
The case for Node.JS
I’m sure there’s reasons to hate Node for linguistic purists but for me this is the language that will most help you be best at one thing.
First the robust NPM ecosystem might have some crap in it but it means that you’ll almost never encounter a problem without a pre-built solution. For example, you won’t have to spend hours or days writing your own date parser/formatter. Just $ npm install moment and you have a better date library than you could have ever written yourself. For every challenge there is a decent to excellent solution. And if in a blue moon, there’s no acceptable solution, you can write your own module and publish it to npm. The beauty of npm is that it radically speeds up your development cycles by letting you focus on what you should actually be working on and results in a cleaner codebase, focused on its one job.
The case for going serverless
When I started at Riskalyze and Droplr, one of my first tasks was provisioning a server in our cloud, installing and compiling dependencies, configuring firewalls and security. We had a document as long as your arm in our private Wiki with all the meticulous steps to set up a new production API instance. Did I enjoy server admin? No. Was it time consuming? Yes. Is there a better way? Hell, yes.
If you haven’t heard of Serverless, I bet you can guess what it is by the name: Serverless is a Node framework that lets you write functions simply run in the cloud without a server. It cuts out the server admin part of building and shipping a web app, it removes scaling from the equation (at least for a while), and deployment is a single step. It makes shipping a fully functional app fast. And remember, speed is everything.
One of the beauties of Serverless is that it fully supports synchronous, asynchronous, and scheduled logic. It’s trivial to ship code that is triggered by a HTTP request, or a SNS notification, or a cron schedule. In one package it contains all the features you’ll need.
You might be thinking, “that’s great but I don’t have an AWS cloud on my desktop, how do I develop an app without pushing every change to the cloud?” That’s where the flexibility of Node leaps to the rescue. For HTTP functions, you can easily run those on a local port like any other http app. For functions that rely more on AWS services (say they need to be triggered by a SNS message), I recommend running localstack.
There’s a lot more that could be said about Serverless. At Droplr we’ve done a lot of work internally figuring out some best practices around this. For further reference, check out my sample project that gives examples of synchronous, asynchronous, and scheduled logic: https://github.com/levinunnink/serverless-boilerplate You can use this as a starting point for your own serverless app.
What about the database?
As I previously mentioned, when I started at Riskalyze we used MySQL, which ended up being a great choice. Riskalyze is a fintech company and financial data is highly structured and relational. It was crucial for us to be able to join and roll up data based off of different schema keys. Postgres would have also been a fine choice. At Droplr we have a much simpler data set and we ended up going with MongoDB. This also turned out to be a good choice as it allowed us to store huge sets of data without enforcing a rigid structure and needing to constantly migrate our data (very nice if your model is going to evolve with your company).
Ultimately, the best answer is to pick what is going to be fastest for you. What’s going to be the easiest for you build schemas, write queries? Go with that one.
The one thing that I’d strongly recommend is that whatever database solution you choose, make sure it’s managed. I.E. you’re not the one managing it. For every major database there’s a fine managed option available. You shouldn’t be the one worrying about backups and replication. Pay the money and use a service that will handle these things for you. You need to focus on being best at one thing, and that one thing isn’t database administration.
All of these are just my suggestions. The beauty of being a technical founder is that you get to pick the technology and as long as it allows you to be best at one thing and adequate everywhere else. Be proud of your tech stack. Let other people hate on LAMP. You go forth and ship your product!