Choosing the right tech for your startup is entirely dependent on the state of your product. As we’ve recently passed an inflection point at Simon, we’ve reflected back on the technological decisions we made to get here, and the overarching principles we used to make them.
As far as product development goes in startup land, there are two states of the world: pre product market fit and post product market fit.
If you’re in the world of pre product market fit, the only thing you should care about is finding product market fit.
From a technology point of view, choosing the right programming language, database, caching layers, queueing services, job managers, and search engines can be framed very simply. Build using only a few and familiar set of technologies that you deem absolutely necessary to get you to product market fit. Anything beyond this is building technology for the sake of building technology.
In this post we explore how we think about this problem of choosing the right technology during the early days of your startup. We’ve certainly made plenty of mistakes in the past at our previous startup, and dealt with the aftermath of even greater mistakes that were made during the early days at Etsy. While there’s certainly no single golden rule here, we’d say the following presents a context that pointed us in the right direction.
Adding new technologies
If you haven’t found product market fit, introducing any new technology to your stack should be met with skepticism. Focus on building minimally, proving out the core value proposition of the product, and understanding the singular reason why people love you.
In the stage of pre-market fit, technological improvements oftentimes either fall under the category of improvements that aren’t going to make your product, or premature optimizations that aren’t required at the scale at which you’re operating. For example:
Search. Do you really need a standalone service in Solr or Elasticsearch, or can you get away with just a database search? Maintaining a search service alongside an authoritative OLTP database is operationally hard, and further complicated whenever you migrate your database and make fundamental changes to your data models.
Etsy ran on a database search for many years before it presented as a technology bottleneck. Given the way Etsy worked in its early days and also given the scale of the marketplace over its first couple years, they didn’t need anything more than this.
Caching. Reliance on caching is like a drug addiction; it may fix or cover up your performance problems today, but it doesn’t address the root cause directly. While sometimes caching is unavoidable, it adds significant complexity to your application, since reasoning about caching is inherently hard. Consequently, iterating on your product becomes slower, since complex applications are harder to change than simples ones.
At our last startup Adtuitive, we had some very complex product matching technology, and as our algorithms matured, caching became core to the application, and misses became very expensive. We had multiple layers of caching - both Memcached as well as in-process caches; system complexity was very high, and many of our engineering as well as product performance discussions were centered around caching issues. In this context, the decision to rely on caching may have been unavoidable, but it certainly slowed our ability to iterate on the end product.
Queueing Services. Do you really need a fancy backend collector for your application logging data, or can you just get away with using syslog? We went through a half dozen queues at Adtuitive; we spent countless hours tuning parameters and trying to wrangle unfamiliar technology. At Etsy, we actually reverted away from RabbitMQ and went back to some basic database workflows that lasted several years before a rearchitecture became necessary.
Technology for technology’s sake. Etsy utilized and built a slew of technology in its early days that neither advanced the product nor provided scalability. For example, a middleware layer called “EMID” that (see stack traces here) and a reliance on Postgres stored procedures, both of which ended up being very expensive to rip out in the years that followed. Obviously, avoid this at all costs.
Planning for the long-term, building for the short-term
Of course, some technology decisions are hard to change once you get moving. Twitter built its original MVP in Ruby on Rails, and has now spent the better part of the past 5+ years rearchitecting their platform in Java. Etsy and Facebook were both originally built on PHP, probably the right choices for them at the time, and both are currently still primarily running on PHP. Adtuitive was built on JRuby, which was great in that it provided direct integration with Java; had the business not been acquired by Etsy relatively early in its cycle, we would have most likely needed to move away from JRuby for the most part and evolved to a traditional Java stack. Had we known this up front, we may have instead opted for a language like Python that would have enabled quicker development times while also offering good performance.
Switching databases is also hard, but it’s been done before. Etsy was originally built on Postgres, and we went through a transition to sharded MySQL that took well over a year to complete.
Non-transactional and non-authoritative data stores are easier to update once your product is up and running. Adding a standalone search service, migrating away from a database queue, or replacing some of your Jenkins workflows with a more scalable background job server are all technologies that if you’re able to punt on before hitting product market fit, you should.
At Simon we made a very deliberate decision early on to use Python based on its strong support for numerical programming along with its overall maturity and established web frameworks. Since the transactional requirements of our problem are fairly minimal, we were able to architect the system to use Amazon S3 as our authoritative source of record for most data and build simple components that are easily replaceable.
Our pre-product market fit system relied heavily on technologies including Jenkins, Syslog, and Hadoop streaming. Now that we’ve turned the corner and are confident about our product specs, we’re starting to explore alternatives for dedicated background processing, finer grained logging and aggregation for customer-facing analytics, and data pipes for more flexible and lower latency data processing.
Depending on the problem, market, and customer type that you’re building for, you may need to invest more heavily on longer-term technological decisions up front. Successful SaaS businesses can be built on thousands or even hundreds of customers. Yet mass market B2C products like Instagram can scale to very large sizes very quickly.
Obviously, you must plan for life after you’ve found product market fit, but finding an optimal saddle point is a careful exercise in understanding your market potential and making some guesses about your final product requirements up front.
Success is being good at one thing
At the end of the day, your customers will love your product because of one or maybe two things. Additional features, functionality, along with the underlying technology that powers all this just don’t matter.
Focus on doing one thing well, and choose technology that’s simple and will provide future scalability.
In the next post, we’ll dive into how we think about technology post-product market fit and how we’ve been scaling our efforts since then.