For a certain breed of web developer, the debate over the optimal hosting choice for web applications is akin to navigating a minefield. Delve into a decade's worth of discussions on Hacker News, and you'll find a battleground of opinions, each with its own set of staunch defenders and detractors. The truth is, the diversity of web projects out there means one size does not fit all. Whether it's a matter of budget, learning curve, scalability, or control, the "best" hosting solution varies wildly from one scenario to the next.
However, amidst this convoluted terrain of options, it's crucial to recognize that the stakes of making a poor hosting choice are alarmingly high. Opting for the wrong hosting provider can be the digital equivalent of building your castle on quicksand. Slow website load times, frequent downtimes, and inadequate security measures can not only tarnish your brand's reputation but also significantly dent your revenue. Imagine the horror of your site crashing during a high-traffic event or sensitive customer data being compromised due to lax security protocols. These are not mere inconveniences; they are potential catastrophes that can derail your online presence. In an era where consumer trust is as fragile as glass, a single slip-up in hosting can lead to a domino effect of lost customers, negative reviews, and a tarnished brand image that can take years to rebuild.
We’re publishing this report to demystify the complex landscape of web hosting and deployment. Our goal is to illuminate the myriad of considerations that should guide your decision-making process, helping you navigate through the noise to find a hosting solution that aligns with your project's needs, without falling into the trap of making a catastrophic choice. By understanding the nuances of this decision, you can set your web application up for success, ensuring it is both robust and resilient in the face of the internet's ever-evolving demands.
A Virtual Machine (VM) is a “virtual” server running on top of a physical server. It’s preferred to a physical server for a few reasons, most importantly that you can overprovision VMs onto actual servers, and because the “virtual” nature makes things like migration, backup, and automation easier when compared to a physical hard drive and motherboard in a rack.
A VM is the original “hosting” product of the cloud era. Over the last 20 years, VM providers have come and gone, as have enterprise virtualization solutions such as VMware. Today you can do this somewhere like OVHcloud, Hetzner or DigitalOcean, which took over the “server” market from the early 2000’s. Amazon Web Services (AWS), Google Cloud Platform (GCP), and Microsoft's Azure also offer VMs, at a less competitive price. In their case, the VMs are either a building block for other services or the value is in the ecosystem. See the section on public cloud below for more.
To manage a VM, you can use something as simple as just manual actions over SSH, or can use tools like Ansible, Hashicorp's Packer and Terraform or other automations. For an app where there is minimal load and security/reliability concern, VMs are still a great option that provide a lot of value for the buck
These are the most flexible product, but require a lot of knowledge and work to “do them right” and while you can scale very far in terms of requests per second on one machine these days, in practice there are other parameters that matter for scale (e.g. reliability and compliance and microservices) and which drive teams to other options for their hosting needs in 2024. But you’re not a true expert until you’ve done this from scratch a few times, and everyone should play with VMs at some point…
Ideal for old school infra pro’s looking to spend as little as possible
This category dates back to the “control panel” era of tools that are still used on shared VM hosts, such as cPanel. These tools automate common functions such as managing authentication, deployment of databases, etc.
The modern iteration of these tools has taken the developer experience learnings from the Platform as a Service (PaaS) category, and will bring them to your own VM, giving you your own personal PaaS. Example of this include Dokku, Coolify, Caprover, Cloud66 and many more!
These tools are great for making the VM hosting experience easier - upgrading, deploying, maintaining all get well-supported pathways, often with documentation. In some cases, you can buy support around the software as well. Some of the commercially-supported options can scale further, but in general the biggest limitation of this category is that you remain limited to a single VM for hosting, and so for most teams they do not choose this path for anything beyond a small project.
Ideal for SaaS soloprenuers, students, or side project hackers
At some point after AWS released S3, they made it possible for you to host a website in a bucket. This was one of the first “serverless” products. You didn’t need a VM at all!
Single-page applications (SPAs) existed before S3, but given that you still had to set up, scale, and maintain servers using something like Apache or NGINX in order to serve them, the advantages for “Ops” or “DevOps” were not so different to running a “real server” with a language like PHP, python, or Java.
After S3, people got excited about the potential for a truly simpler deployment experience, where you could scale infinitely without worrying about it - it was the cloud’s problem. And, it was super cost-effective when you put a content delivery network (CDN), which is basically an internet-wide cache, in front of your site. This drove a wave of single-page app design and delivery, which had mixed results but was undoubtedly popular.
One thing that smart teams noticed with the new “serverless” paradigm for their frontend was that it was now possible to easily deploy many versions of your site, for internal testing, incremental rollout, and other reasons. The rise of “preview sites” was initiated in earnest by Netlify in 2014 and was truly catapulted by Vercel in the late 2010’s.
The term “JAMstack” has fallen out of favor, but this style of hosting and the workflow it enabled with dynamic previews is still a major trend on the internet today, and big part of how deployment and hosting work.
Purely static hosting and SPAs are still part of a lot of stacks, and if you’ve got one in yours this is still a great option for that part of the system. But if you do server-side rendering or want to use a language besides JavaScript/TypeScript for your logic, other choices will make more sense for you.
Ideal for client-side applications for the web that are content-heavy and have a lot of interactivity
The first product that popularized the term “serverless” was AWS Lambda, which is both the prototypical and archetypical function as a service provider. It also has a great name, which pings back to its envisioned place in the cloud of the future. In computer programming, a lambda, often referred to as a lambda function or lambda expression, is a concise way to represent an anonymous function, which is a function without a name. The concept originates from lambda calculus in mathematical logic and has been adopted by many programming languages, each with its own syntax and characteristics.
The definition of serverless is a bigger topic than we will cover in this post, but in general the 2 key aspects are that it scales to 0 in a request or event based timescale, and that there is no access to the underlying operating system, only to a well-defined safe runtime within it. In Lambda’s case, the original runtime was a javascript based one, which has now expanded to many languages including python and Java.
Serverless functions are now offered by many cloud providers, as well as having options like OpenFaaS, Knative, Apache's Openwhisk and more from the open source community that run in environments ranging from one server all the way up to globally replicated private clusters.
These are a great choice for a variety of uses cases. Simple API endpoints on the web, simple event-based microservices, edge functions that run close to users (often stateless), and more are the most obvious fits. But given their operational simplicity, wide availability, and simple operational mechanics - they are often seen as the “hammer” for a lot of “nails” in stacks across the startup and enterprise software world.
We see some great results from using these in conjunction with frameworks such as SST or Serverless, and also some real spaghetti from people who organically proliferate 100’s of functions over time and lose track of how they relate to each other or how to update them safely across time and service. Buyer beware!
Ideal for small bits of backend business logic integrated into a larger system, for example edge functions that need to access a 3rd party API with a secret key required
Backend as a Service (BaaS) goes back to early 2010’s with companies like Parse and Firebase. These products integrated everything a backend provides to a webapp in a single, integrated package that makes it easier to get started and enables you to offload some of the devops maintenance work to someone else.
Today, this ecosystem is going strong with new providers like Hasura, AppWrite and Supabase powering millions of projects. There are a few reasons people choose this style of hosting, especially if they are more comfortable with frontend development. BaaS lets them set up a database in a secure way, expose some business logic on top of the data, and connect via a dev-friendly SDK from their app or website code to save data easily. These modern tools build a blend of managed database with curated plugins such as authentication, great admin dashboards, and function as a service type capability - all in one package, and often offered as a integrated hosted service.
There is some overlap here into the “no-code” or “low-code” world, as sometimes the same teams will hook tools like Zapier up to the BaaS in order to integrate with third parties. For small projects this can lead to superhuman productivity! But over a certain line it can become a mess of complexity where it’s hard to track down where data lives and where it is mutated.
For solo hobby projects by frontend devs or beginners or small teams that just need to offload a bit of state to the backend but don’t have a ton of server-side requirements - BaaS is a perfect solution. It does seem that there has been a rising trend for these tools to do more - for example a lot of startups are building a large part of their backends on Supabase over the last few years. Those that end up with a high percentage of server-side business logic will often “graduate” over to a more traditional setup for their server as they grow, and migration can be painful and time-consuming if there’s too much logic spread out over different functions. We think these are not the right choice for building a SaaS software business or enterprise software product on top of.
Ideal for client-heavy applications that need to combine a function as a service with a database, or just need to synchronize state between clients but don’t need server-side logic
Platform as a Service (PaaS) is a term that captures tools built for developers to use where they don’t need devops engineers to deploy to the cloud. Heroku was the “category-defining” product here, and modern successors include Vercel, Render, Railway, Replit, platform.sh, Aptible, Northflank, and more. We have to say that there are some amazing products in this category. Developer Experience is at a premium!
There are many great reasons to use these products:
There are 3 big reasons why people outgrow a PaaS:
These three categories are unlikely to change in the near term as reasons why teams outgrow a PaaS. The bottom line is that the best engineering teams in the world are either in the public cloud or are hosting in their own datacenters and building their own tooling. They’re not paying a double premium for a black box that they cannot control.
For small teams, side projects, personal or student use, or other use cases where simplicity is paramount - a PaaS is the right hosting and deployment choice. For anyone else, these are a great place to get started but are not the final destination.
Ideal for small or new software teams, students, development agencies that serve small clients
This is a new category that sits between a Platform as a Service and a Function as a Service. Inspired by the great feedback about the developer experience for “serverless” but stuck with some of the limitations - the major cloud providers expanded the category with products that could run “real” linux containers. This means that they can run legacy apps as well as anything else that can be packaged as a container - a much larger footprint than the Function as a Service with a much smaller migration delta.
Some of these products also integrate deployment pipelines directly, making them almost as easy to use as a PaaS and blurring the lines. Generally they are still distinguished by not offering prebuilt integration with other services like databases or message queues, and by not having the same developer experience across different environments and making things like previews very easy.
Examples for products in this category are: Google Cloud Run, AWS App Runner, Azure Container Apps. Each has different scalability, cost, and integration trade-offs.
These are a great choice if you’re already running services or hosting apps/sites in a particular cloud, and need to deploy something that doesn’t fit into that existing tooling. They can be placed into a VPC and add new services, quickly and easily.
Ideal for teams who have made an existing investment into a cloud provider, and are running single-service applications that will not be updated often, or which are not production-critical
We mentioned Replit in the PaaS category - and in some ways their deployments tool is an equivalent of the rest of the PaaS category - an easy way to deploy and host without any cloud account or configuration needed.
Additionally, Replit is an example of a broader and more unique category of software as well, one that does not have a well-defined name but which is defined by having an integrated solution for both development and deployment. Usually, this involves having a Cloud Development Environment with a IDE, a dev server, and then an integrated deployment and hosting option that runs the server or serves a single-page app and other assets via a CDN.
Replit is the category leader here, but other products in this space include: Glitch, Codesphere, StackBlitz. Coherence fits here as well, with our “Workspaces” Cloud IDE. We’re also the only option where the PaaS is replaced by an Internal Developer Platform.
These tools are great for a few reasons:
So far, the only place these are a preferred choice for hosting is for education, interview process for engineers, and some edge cases internally at enterprises. We think that this is an interesting space to watch, especially as it matures. Try one of these products out if you’re not familiar with them!
Ideal for developers who are writing complex backend applications but who have no devops experience and are not able to hire a consultant to support them
The single most important development in hosting since the invention of EC2 is defined by its own 3-letter acronym: k8s. Kubernetes has won the “container orchestrator” space, becoming the default way that teams across industries are managing their compute nodes and scheduling their workloads, from data pipelines to web services.
In the beginning, there was docker. In 2013, building on linux internals, docker packaged containers for mass adoption and made it easy to share a complete runtime environment for an application across the network. Check out their first demo at PyCon 2013 (I was there!) At the time, serious workloads ran on something like Mesos, which was not “container-native” and had its own way of packaging and distributing software across a cloud or data center footprint.
Docker didn’t have a default way to run on multiple hosts, and so in the wake of docker’s explosive adoption there was a rush of different solutions offered for scheduling containers across a fleet. One of the first well-adopted solutions was actually called fleet - it was part of CoreOS, whose team went on to be very influential throughout the container revolution. This was in the systemd era, and was basically seen as a multi-host systemd. It was very cool and it worked great!
Docker itself intended to build the answer here, it was the deployment platform of the future and was going to be the heart of their business model. It was called “docker swarm” and unfortunately by the time it arrived there was a fragmented market of already-adopted solutions. Docker as a package format was a runaway winner, and Docker Hub (which became the foundation for the current Docker, Inc. business) was widely used. But the fragmented runtime market left room for a new entrant: (drumroll please…) enter Kubernetes. It was a “community-driven open source project” that was in fact funded and well-staffed by Google engineers, and rose quickly on the claim of being an open-source implementation of Google’s storied internal cluster management system called “borg.”
Docker swarm still exists, it still works, and some of these other container orchestrators are still hanging on, but for the most part, you’re using Kubernetes if you’re doing this stuff at work. Generally it's well-understood that kubernetes is hard to get right, and so most people use it via a managed provider like Elastic Kubernetes Service from AWS, Azure Kubernetes Service from MSFT, or Google Kubernetes Engine from Google Cloud. And there’s many more: Tanzu from VMWare, RedHat's OpenShift , the list goes on…
It’s also well understood that having a k8s cluster is not enough to make developers able to host their services - you need a devops team to work with them, using tools like delivery pipelines, Helm, kustomize, infra as code, service mesh, ingress, secrets management, key management - the list goes on! Developer Portals like Backstage, Port and Cortex have started to emerge to help manage some of this complexity.
In general, k8s is not a good choice for hosting, in and of itself. Even the managed variants are really helping you with the management of Kubernetes itself, not your application on top of it. Kubernetes is a tool for devops or platform engineers to then build a deployment solution for developers on top of. If you work at a company where you’ve got those resources, and they are capable of building that solution, and you’ve got time to wait, and they’ve got time to build, and you’ve got budget to buy all the pieces you’ll need to integrate and maintain to do that - congrats! Market-leading engineering teams have already done this work in many cases, and so maybe you already have this experience. If that’s you, k8s is a great solution for you. If not, stick to one of the other options outlined here.
Ideal for platform teams who are building their own internal developer platform and need a high degree of customization in order to meet their application requirements
There are a huge variety of hosting services available on the large public clouds: Amazon Web Services (AWS), Google Cloud Platform (GCP), Microsoft Azure, Oracle Cloud. These range from simple VMs that work very much like those described in the first section above, through more complex dedicated services, some of which are included in other hosting options below.
Infrastructure as Code (IaC) is an important part of any true hosting operation in the public cloud. Each of these platforms has their own IaC solution, e.g. AWS CloudFormation. But they also support popular open-source IaC tools like Pulumi or Terraform. A category of tools that also needs to be discussed is API gateways and other app-specific load balancers. There are applications for internal consumption, which can be called microservices if you have a lot of them. And often microservices use advanced networking options such as a service mesh instead of just the native private network offered by a VPC.
This topic is very complex, and is covered by entire disciplines: DevOps and Platform Engineering. Many teams take the various components above, plus a host of other tools, and build a “Developer Platform” for their company. Some of these are as simple as some bash scripts wrapping CLI tools. Others are complex apps in themselves, with a developer portal, service catalog, layers of security analyzers, IaC execution managers, compliance audit tools, workflow integrations into sprint managers like linear or Jira, engineering productivity analysis, and even more.
This category has blended with some of the Kubernetes options discussed in more detail above. The “raw” public cloud is a fit for the same types of organizations.
Ideal for backwards-compatibility with existing on-premise applications
Internal Developer Platforms are essentially a bridge between complex cloud infrastructure and developers who seek to deploy applications quickly, securely, and efficiently. By abstracting the underlying infrastructure, IDPs offer a simplified interface for developers, akin to what Platform as a Service (PaaS) provides, but with greater control and flexibility.
Some popular examples of an IDP are:
IDPs vary widely in their approach to balancing usability, customizability, and the deployment footprint. Some, like Zeet and Flightcontrol, prioritize ease of use and rapid deployment, making them ideal for small teams and projects with tight timelines. Others, like Architect and Porter, offer deeper customization options, catering to enterprises with specific compliance, security, and scalability requirements.
The choice between using high-level managed services like Google Cloud Run and Kubernetes-based services is crucial. High-level services offer simplicity, lower costs, and managed infrastructure, but with Kubernetes, you gain unparalleled flexibility and control over your environment. This decision impacts not only the developer experience but also factors like total ownership cost, compliance, and maintenance.
Here are some great IDP use cases:
Internal Developer Platforms represent a significant evolution in how organizations deploy and manage applications. They combine the best aspects of PaaS with the flexibility and control of managing your own infrastructure, tailored to the needs of modern development teams. Whether you're a startup looking to scale, an R&D team pushing the boundaries of innovation, or an enterprise migrating to the cloud, IDPs offer a compelling solution that balances ease of use with the depth of control necessary for today's complex cloud environments.
By exploring the diverse landscape of IDPs, organizations can find the right balance of features, usability, and control to suit their specific needs, ensuring a future-proof foundation for their development efforts.
Ideal for software teams writing significant backend software with business logic, looking to deploy to the public cloud without building their own platform for delivery. A VC-backend startup, a new project inside the enterprise, a large open-source project with cloud credits for hosting - these are the best use cases.
In many cases, no or low code tools are integrated with hosting themselves, and so you aren’t really choosing where to host - you’re choosing when to use these tools and when not to. There are also some open-source versions of these tools that you can self host them.
In general, these are great tools for a few use cases:
For the first category, tools like retool, Zapier, Airtable are best in class and are used in a similar way to spreadsheets with much more power (which are still well-used and important - a large % of the world economy runs on excel macros).
For the second category, tools like bubble, Unqork, Glide are awesome (there are a lot more of these). But the risk is to go too far, and build something that really needs to be built at a lower layer in one of these tools. The providers of course want to push every use case, but in our view these are not a replacement for traditional software, and AI-assisted programming is a better path for dev augmentation than a restricted platform. In some cases though, with the right escape hatches and system design, these can truly be a 10x superpower type tool!
For the third, examples here might be analytics plugins in specialized databases like Clickhouse, data-transformations in places like your ETL pipeline using Airflow or Fivetran, or special integrations in your authentication workflow with Auth0 hooks and rules.
Ideal for internal tools, technical-adjacent folks who are not developers but who want to build data-heavy integrations that require data transformation or aggregation, prototyping simple input-driven applications without complex business logic.
If you've made it this far, thank you! We hope you found this report comprehensive and helpful. As you can imagine, this is a rapidly evolving landscape. We'd love to hear your feedback, feel free to send me an email at zach@withcoherence.com.