Ask HN: What tech stack would you choose for a serious, long-term business app

44 points by bballer ↗ HN
If you were about to start building a very vital brand new application for your company that needs to be maintained long term what tech stack would you choose? Put aside what devs at your company may already be comfortable with and lay out what you think is best.

When I ask tech stack I'm talking the whole dam thing, for example:

DB engine : ie MySQL, Postgres

API layer : ie Node w/joy, Java w/spring, PHP w/laravel, Elixer w/phoenix

Frontend SPA : ie React, Vue (do you use typescript or flow, webpack etc)

Caching : ie Redis, Mongo

PaaS : ie AWS, Google, Azure

Interested to hear your thoughts, and don't want any flame wars stating x is always better than y etc.

Feel free to just specify the stack but better to also back up why you think it is best in a few sentences.

79 comments

[ 3.7 ms ] story [ 132 ms ] thread
1. Tech stack has to be decided based on functional requirements (real-time chat, less-write but read-intensive etc) and non-functional requirements (concurrent connections to support, regulatory compliance requirements etc).

2. Any serious business system (not just one app) will have multiple tech stack.

3. In the long term tech stack has to change depending on the changing business needs.

Assuming a whole lot about above 3 points, choice could be postgres, python, react, aws. Purely because they are battle tested. Any discussions about their merits are moot without knowing requirements.

Your first mistake is that you limit yourself to what's "in", rather than what gets the job done "properly".

For serious long term business apps you want to use multiple technologies that all integrate with each other, where each are used for the tasks they suit best.

Answer for your given question: Java + Oracle. They'll both be supported by legions of enterprise devs until shortly before the heat death of the universe.

Real answer: it depends. You've told us nothing about your application's business requirements, operating environment, or staffing availability.

I'd also caution on the idea "put aside what your devs are already familiar with" - different tech can give you different velocities, but either you accept a much lower velocity for a long initial period while your team spins up OR you accept a significant recruiting cost to hire new devs & teach them enough about the business to make good decisions.

I'd like to second the important of staffing. If we were in a perfect universe we could use domain oriented languages for every project because devs would be familiar and competent with them. Obviously that is not the case.
I know it's kind of cliché and in my last project it also wasn't soo bad, but Java is not something I associate with lean and nimble. I know, OP didn't ask for that - but it sounds like the inception phase of a product, and I can't imagine working any other way than "release early, release often". Long-time support viable? Very probable.
As we're talking business and long lifetime...

First point: nothing Microsoft. Done that show for 20 years and been through all the marketoid schizophrenia promoted rewrites for no business value. Now the new "start again" is .Net core and a big chunk of stuff just isn't portable and never will be. Plus the price gouging, licensing hell etc when you have to scale up. Entire ecosystem is a wasteland of unmaintained crap and automation prospects are terrible. Forget it at this point. I'm done.

At this point, I'd pick Java + Spring + Postgres + CentOS. Does most of the stuff you need out of the box, good support available, long product lifespan, well maintained, possible to automate everything. No SPA, just old fashioned dynamic pages with light weight in house JS framework that does partial page replacement, simple validation etc via DOM. Not even jQuery which has been nothing but hell to upgrade so I'm loathed to pick anything more complicated.

PaaS: none. Either in house or old fashioned colo, with HP hardware. If you have to go PaaS, then AWS which seems the most glacial in deprecation so far.

Edit: also desperately avoid any non portable abstractions and vendor specific features. They will ruin you. For example when someone suggests a database engine, hide it behind hibernate and only use the hibernate API!

Edit 2: it is important to assign an exit cost for every decision as well. What's true now is not going to be in a decade.

Wow, that's pretty hardcore...borderline badass!

Interesting thing is this stack was doable probably 13+ years ago, so I see your emphasis on stability.

Anyway, it's similar to what I'm using and surprised to see it here. Biggest tweaks are that I'd consider Vue/Webpack if starting today and do believe PaaS to be far superior to on-prem/colo. Also, not big on Hibernate or too much abstraction at the data access layer.

It's possibly a summary of my frustration with the last 20 years or so.

I've never used vue/webpack so can't comment. I've been shot too many times by javascript framework churn over the years. I wrote a relatively small and powerful abstraction over DOM that doesn't hide it away, merely makes the hard things easy and less verbose and allows simple templates to be used.

Hibernate is essential if you ask me. One of the problems I see a lot is relying on features of the underlying storage engine. This, while it has advantages, has more disadvantages such as coupling and vendor lock in. These have been significantly costly when you have to scale something commercial up like SQL Server.

Could you elaborate on the PaaS? I've been avoiding it, but partly that's perhaps because I'm a control freak and not for any particularly good reason.
Well, I should have probably distinguished between IaaS ans PaaS, but primarily intended to differentiate between either of these and the GP's advocacy of on-prem or colo.

That is, I would advocate PaaS and IaaS over on-prem/colo, and how far you go towards PaaS is a matter of comfort.

I do think that comes down to control though, and I actually can't think of a much better basis for the decision.

Ah, right. so a VPS or even a dedicated server would be considered IaaS?
Possibly. I think the line runs along how the resources are exposed. That is, if they are literally manageable as a service (e.g. via API or management console), then yeah.

No expert on the terminology here, though. Just how I understand the term.

For me at least, I'd definitely go .Net Core. And I'd not have issues using MySQL either. True, there are fads and fashions that come and go, but over the last 15 years I've not had an issue building and maintaining applications of all varieties built on MS technology. Plus, given the current owner of Java, I'd stay well clear of it. Already moved anything that was MySql over to MariaDB.
Plus .net core supports async and runs on linux.
I couldn't possibly consider .Net core on a number of reasons I didn't discuss above. Opt out telemetry, constant direction changes, who is in charge of the project and the general abusive nature of the company running the show towards its customers and end users over the last decade. The list is endless.

I have actually tried to get things fixed on MSFT open source projects as well and even when you get up to Scott Hanselman poking it on github, nothing tends to happen. On top of that many crippling bugs remain unresolved for so far 9 years. We have unreliable tooling, portability problems, all sorts.

On a larger team and product, it's a non trivial time and cost sink.

What was the bug that remained open for 9 years? Was it part of the .net framework or a Windows SDK issue?

What sort of projects did you have the most trouble with? Where were your pain points?

Sorry was 8 years ... ClickOnce refused to launch on over 2000 machines when they removed download prompting from IE9. This sits between the .net framework and the IE team, neither of which would take responsibility for fixing. Eventually we got a registry fix out of them from bottom line support which turned download prompting back on which was removed from the IE UI but still left in there. The registry fix we had to deploy to hundreds of clients and had a massive support cost. This is still broken in IE11. It was reported on an IE9 beta.

Pain points: large project performance, high concurrency projects, IDE reliability, cost, odd time sinks, bugs in the framework, lack of automation possibility for a vast number of project types (try building VSTO applications on a CI server), deprecations (WWF/WCF changes, AppFabric, Velocity etc) all sorts.

Thank you for this response. I'll not counter each point as that will get us nowhere and serve no purpose. I'm just very interested in how two people can have such polar views on the same technology.
I think it's a matter of luck and/or scale.

On tiny projects it seems fine but we're huuuuge.

I'm not familiar with the size of your code estate so I can't compare. I've certainly worked on some 'big' projects with .Net. In terms of users and application structure.
I can see not using PaaS, but strictly going in-house or colo seems odd. Not saying that there aren't reasons for this, but IaaS, rented servers, ... all are options with more flexibility and little lock-in.
Agree on IaaS. I missed that in there.
I definitely sympathize with having to endure the perpetual rewrites of Microsoft Web and Web service frameworks.

In contrast I'd like to offer our competing ServiceStack framework as an alternative (commercial) platform [1] which has been in active development since 2008 that in contrast to the ever changing MS frameworks offers a single integrated Web Services [2] and Web [3] solution that has maintained the same clean, stable high-level message-based API throughout its lifetime. It was created out of frustration in the WCF/WebForms era [4] where we were the first to offer an integrated IOC, impl-free/testable multi-provider logging, caching, virtual files and configuration providers, clean/extensible typed user sessions - all using high-performance components. The first to run on .NET Framework and Mono, the first to create high-performance JSON and text serializers and fast typed ORM, which at the time they were developed were several times faster than anything MS offered [5].

All pre-dating Web API [6] and outlasting the continually changing fragmented MVC/Web API "framework in a framework" coupling as well as the rolling churn of abandoned OWIN/katana abstractions [7]. Instead we've maintained clean impl-free IRequest/IResponse interfaces which provides a lightweight abstraction over the underlying platforms concrete HTTP Request/Response abstractions where we're still the only framework where the same ServiceStack App can run on classic ASP.NET, self-hosting HttpListener (.NET Framework or Mono OSX/Linux), ASP.NET Core on .NET Core (Win/OSX/Linux) and ASP.NET Core on .NET Framework v4.7 [8].

As a result of our stable surface area we still have older v3 (BSD) Customers upgrading to our latest commercial version just so they can leverage their existing investments to run on ASP.NET Core which is relatively easy to port [9] where most of our .NET Live Demos [10] have been ported to run on .NET Core [11].

Unlike any of MS offerings, ServiceStack:

- Has never abandoned any .NET library, our libraries are continually enhanced and maintained, not rewritten or discarded

- The same Services implementation supports multiple formats out-of-the-box, can be called from multiple HTTP / MQ / SOAP endpoints, on multiple hosting options [12]

- Provides native, end-to-end typed development experience for C#, TypeScript/JS, Java, Kotlin, Swift, F# and VB.NET [13]

- Has no prejudice towards MS products, our libraries work equally well on all platforms/back-end providers, e.g. OrmLite [14] provides a high-level typed DB agnostic API across all major RDBMS's. Whilst SQL Server is our most popular dialect (courtesy of marketing in .NET), we personally prefer/use PostgreSQL and its a popular configuration to configure Unit tests to use SQLite for faster Integration tests.

- Provides clean abstractions of multiple providers for AWS [15] and Azure [16]

- Has its own flexible Auth Provider model [17] which hasn't had a schema change and never needed a "migration" whilst being continually updated to support new providers

- Has an aversion to complexity, instead of blindly adopting over-engineered solutions we develop our own cleaner alternatives. Some examples of this include AutoQuery vs OData [18] Add ServiceStack Reference vs WCF Service Reference [19], Templates [20] vs Razor [21]

- Offers a Simple and "pure Cloud App" solution for developing .NET Core Apps with built-in hot-reloading and without any compilation or builds [22]

From 2013 we've adopted a sustainable dual licensing model (commercial for closed-source or OSS/Free for OSS projects) which has allowed ServiceStack to be actively supported and maintained and continually updated with new releases [23].

Anyway I'd like to offer ServiceStack a stable competing framework for .NET and .NET Core that's being developed from a different mindset/values which has evolved gracefully over the years and stand...

Thanks for the write up. We evaluated ServiceStack and the license conditions, lock in risk and cost for a supported product across our estate was prohibitive.

The only desirable feature was Redis sentinel but we can live without that.

Honestly we can just switch parts of the system to another platform for the same cost and get an ROI over a couple of years.

Understood, although I still think you should consider evaluating .NET Core (even w/o ServiceStack), the latest .NET Standard 2.0 offers a broad and compatible API Surface shared by .NET Framework v4.6.2 and .NET Core. The new msbuild project format is much more human-friendly that together with tools like `dotnet watch run` you can for the first time productively develop C# Apps with command-line tooling and a text editor like VS Code in any OS (that also sports IDE features like intelli-sense/debugging/etc - tho Rider is my personal pref / with VS Code for the SPA front-end). Being able to deploy to Linux opens up a new world of automation possibilities where you have first-class Docker support or can incrementally deploy just changed files in seconds with a single rsync + ssh supervisord bash command run with WSL - everything feels cleaner, faster and more automatable and runs flawlessly cross-platform, e.g. all our .NET Core Apps are developed on Windows and deployed to Linux.

It's a different world with a much improved development model that I find vastly superior compared to traditional classic ASP.NET Framework Web Apps - which I don't see myself ever creating greenfield Apps for again.

The stack should be chosen based on the requirements, not just "needs to be a long term application".

Honestly I echo the Java suggestion plus a rdbms. You have a big talent pool, it's well supported and "enterprise stable", and it's multiplatform.

Tech or nontech business? Engineering driven org or not? Size of org? Structure of existing team? Relationship of this team to other teams? Overall structure of org? Hiring strategy? Where in culture spectrum does your business require you to be?
DB: Postgres

API: Ruby on Rails

Frontend: React, the react_on_rails gem to set up webpack, Flow, Redux, Immutable.js

Background Jobs: Sidekiq and Redis

Caching: Memcached

PaaS: convox (on AWS). See: https://convox.com and https://github.com/convox/rack (But you should start with Heroku.)

I recommend the Rails stack. It's not the "hot new thing", but it's very stable, secure, and productive.

Definitely agree with memcached. This has been entirely bullet proof for us for years. We have had lots of nodes with billions of hits each running non stop for 3 years without a reboot on CentOS 5. Zero maintenance required. Amazing bit of software.
While memcached is great. I feel like its hard to argue for both redis AND memcached. It seems like redundant infrastructure unless you have very specific needs.
Yes I agree there. I would err towards redis these days myself as well, not necessarily using it for anything persistent unless you need to.
It's not a good idea to use a single Redis instance for both caching and persisted/transactional data (background jobs). For background jobs, you need real-time persistence with AOF. For caching, you want everything in memory, and you need an LRU cache that evicts any old data. This means you should run two Redis instances with different configurations. But in that case, it can be a good idea to use Memcached, which is recommended by Mike Perham [1].

[1] http://www.mikeperham.com/2015/09/24/storing-data-with-redis...

My favorite stack as well, minus Convox (haven't heard of it before though). A no-brainer for me personally, unless there are realtime requirements.
You should pick your technical stack depending on what the requirements are. Picking the stack first means you're forever going to be trying to shoehorn the requirements around it, which is a pretty terrible way to design a long term solution.

And then you need to look around yourself at the resources you have now and what they may be 5 years from now. There's no use writing something up in a little used language hoping you'll be able to hire for it later and adding risk by writing something in a language or technology only you know in your company is creating an unnecessary bus factor of 1.

Is your business just starting, or already have some customers? How much funding you have, and what are the skillsets of your staff have?

A safe place to start would be Linux + Postgres + Java Spring or PHP Laravel.

My experience is the market has more Java or PHP engineers (compared to say, Elixir).

> the market has more Java or PHP engineers

That's a quantity over quality argument. Assuming there isn't an extreme shortage, I'd opt for a language and/or framework that tends to attract higher quality candidates. Personally, Ruby/Rails feels like it hits the sweet spot there.

My ideal business app layout (I assume we are talking enterprise, here) would be:

DB: A hybrid of Postgres & MongoDB

API: Hand rolled w/ SparkJava

Front End: intercooler.js (SPAs blow out your complexity budget, which should be spent on business logic)

Caching: Redis

PaaS: the system should be designed to deploy on anything, including internal servers

For a SaaS app, I would look at rails due to the ecosystem and stability, but otherwise it would remain the same.

Postgres, PHP w/ Slim Framework, Python w/ Django, React, Redis, AWS.

This is a combination of things I'm most familiar with and things I'd build shit in if not for the fact that other devs at my company aren't familiar with it. i.e. We use MySQL everywhere, so I can't just spin up a new project using Postgres for the sake of consistency.

First off. As someone else pointed out it depends on the application.

Heavily data dependent / ETL applications have different requirements than CRUD applications. There is not a one size fits all stack, you need to consider the user cases.

For example:

- We use DynamoDb and ElasticSearch on the back-end because our case is very key-value oriented but also needs faceted search in some use cases.

- We use Node.js for our user-facing REST API because it was fast to develop and quick to iterate on but we use GoLang for our internal gRPC APIs and front-end because in our case those are the hot paths and where the performance differences between node and Go make a difference.

For an activity feed API (hundreds of thousands of activities a day) I've used Redis with huge success.

The point being is if your app is truly enterprise you'll probably have more than one microservice, and you should pick the right stack for each microservice.

In absence of a hard business requirement that is significantly different between languages choose the framework your team can develop the fastest in and get to market fastest (like our hot path example).

My personal go to is...

Backend: Postgres, Redis, Elasticsearch, DynamoDb

Front-end server and APIs: Node.js with express (no framework), focusing on as few lines of code per microservice as possible

OS: Definitely Linux

Cloud Provider: AWS

Cache: Cache close to the app when possible, if you don't need cache to be synchronized across machines there is no need for a central cache. With that said, I personally love Redis

On the cloud platform note, I'm an AWS guy but they all have their benefits. I try to use as many AWS services as possible to decrease dev time / costs but write the code in such a way where it is abstracted so getting away from vendor lock-in would be possible (painful but at least possible).

All the cloud providers have a service catalog that can shorten your development time if you take the time to learn them use them right. I happen to like AWS value added services best.

With all that said:

- The most important things you should worry about is getting to market and solving the customer's use case. The stack is not important in 90%+ of cases. If you structure as microservices you can always replace individual services cheaply on a case by case basis once you have customers.

- Second, "When I ask tech stack I'm talking the whole dam thing" is very unprofessional and I almost didn't answer because of that. I suggest perhaps an attitude adjustment when asking the community for free consulting advice.

Answering this before reading so I'm not impacted by others. SQL Server, ASP.NET Core, As little JavaScript as possible, No caching initially, Dedicated servers, IIS.
(comment deleted)
Node is fine for the frontend -- I'd go with React and React Native personally -- but between NPM issues and a general cowboyishness, I wouldn't go near it on the server-side.

Backend/API layer would be one or more of Ruby, Python, or Java, depending on what my team felt comfortable with. Large, mature communities, healthy ecosystems, overall decent tooling, good support for testing and deployment automation.

Nothing Microsoft. Not going down that road again if I can help it.

AWS hands-down. Google tends to have this pathological distaste towards providing support for their customers, and I don't trust them to not just shutter any of their non-core products randomly one day.

I am very sold on GraphQL or Protobufs as the interchange format over REST.

Databases, hard to go wrong with PostgreSQL. Redis and Memcache for caching.

> very vital brand new application for your company that needs to be maintained long term

Long term maintenance is easier if the tools are relatively stable. I think that argues against most (all?) Javascript frontends. Eg, if you started this 3 years ago, your current JS devs would want to throw away your entire JS framework and tooling stack. Odds are if you do it today, they'll want to do the same in < 3 years.

For minimum maintenance issues, I'd pick PostgreSQL for db (data integrity FTW), Redis for caching, and do a server-rendered app.

Of the server-side frameworks I know, Elixir Phoenix is my favorite, but Rails is older and arguably changing less. Probably some Java framework is even more crufty / stable?

Of course, there are other concerns besides stability that might argue for different choices - eg, using Elixir Phoenix means that a lot of your caching would be unnecessary, because the dynamic parts of view rendering are "cached" in compiled functions and the responses are very quick without further caching. And you'd get richer experiences with an SPA, in exchange for a lot more work. But you highlighted maintenance.

Postgres + Go + Vue.js + Redis + AWS

Go with or without any framework (like Buffalo)

Vuejs with Vuex

Your technical stack should not be frozen. During years, it will probably evolve, either to use some promising features of new technologies, or to still be able to hire. For instance, hiring some Cobol developers is really hard (and then expensive) these days.

More important than technologies is testing. If your whole app is well tested (with both unit and E2E tests), you won't be reluctant to upgrade some part of your system because it doesn't answer your needs. Moreover, it would bring a lot of reliability and would be self-documented. That's the biggest point IMO.

For nowadays mood, we are really glad using React, Node, GraphQL and PostGreSQL for all our apps.

Note: we wrote a blog post about one of our long running customer story, which may interest you: https://marmelab.com/blog/2018/03/28/1859.html

Ruby with rails or php with laravel, the js stacks are too new and too hip for a long term application, go with a mature stack that doesn't change with the wind
I'm not sure about the stack (depends on what you are comfortable with, your requirements...) but:

1. use something that has been around a long time and is well supported/known

2. you probably don't need stuff like cassandra or other "big data" data stores (just yet). PostgreSQL/MySQL is plenty fine to start with (and easier to manage/think about).

3. please use only a single cloud provider.

For our SAAS we're running:

- DB Engine: MariaDB on RDS (multiple instances) + Redis for specific use cases. - API layer: Symfony (PHP) - Frontend : React - Caching: Redis - Ops: Rancher Orchestration on EC2, and a bunch of AWS features like S3, ALB, ...

We had some hiccups here and there, but I'd say we are happy with the stability of it.

A No hassle, No worries plan is to use AWS. It's going to scale, and not on you for everything (deploying, packaging). Zero provisioning, and pay as you use. You'll get up and running very fast with low costs, high reliability.

DB: dynamodb

API: API Gateway and AWS Lambda

Frontend: angular 2+, or React

Cache: AWS Elasticache

Blob Storage: S3

> Put aside what devs at your company may already be comfortable with

At your peril. Sorry, but it's true.

Any time there is something even slightly amiss it's going to be "Uh oh - looks like Mongo is giving us trouble again."

No matter what the real problem is a slam-dunk scapegoat. And your name is going to be forever attached to it.

Also consider how you're going to deploy & maintain the stack itself. Do you have an ops team that's familiar with deploying war files into a servlet container? Well now on the critical path to this thing going live is them learning how to maintain a new app server, language and deployment process?

That said, at the end of the day - all the tools, frameworks, and languages you mentioned are just fine, with some slight nuance:

DB: MySQL is fine, Postgres has some nice additional features if you need them: GIS, great scripting support, etc

API/App: Stick with the big ones (Elixir? C'mon...). Slight edge to Node because JSON de/serialization is automagic. Slight ding to PHP because... PHP.

Frontend: Who cares? It's going to be outdated in 6 weeks anyway.

Caching: Which ever one you don't have to maintain or think about. Did you choose AWS? Great. Elasticache supports Redis and Memcached.

PaaS: Whichever one supports all the features that you need.