Developers at startups are almost always faced with the question of the most cost-effective way of getting the benefits of the cloud without having to manage the underlying systems. Years ago, when we were still building monoliths and using EC2 instances, Elastic Beanstalk (or Google App Engine and Azure App Service) was a tempting choice for young start-ups that were looking to deploy fast.
Even then, Elastic Beanstalk (EB) was a fit only for non-mission-critical applications that required standard configuration and deployments. (Here are some accounts of real developers getting their hands burnt with EB). Besides, Elastic Beanstalk has not seen a major upgrade for some time, so should you use it even for non-mission-critical applications anymore? What are the modern alternatives to Elastic Beanstalk in 2022?
Much of the existing information about EB’s alternatives either lists equally legacy PaaS from other cloud providers or compares with the stagnant Heroku. And rarely do they weigh the alternatives from the perspective of startups with a lean or no ops team at all. This post attempts to list and compare the options to Elastic Beanstalk in 2022. It will be helpful for you if:
- You’re a growing start-up that needs to build and scale critical applications - aspects like time to deploy, latency, and troubleshooting are vital for you.
- You currently have manually pieced together your infrastructure and processes. And you’re evaluating which PaaS is the most suited for you.
- You’re already using EB but want to migrate out of it because now, as you’re scaling, EB’s limitations are hurting you—unstable & slow deployments and lack of transparency around failures & updates, to name a few.
- You want to get your apps running without hiring an ops team or with only a lean ops team.
Now, we realize that reading this post alone won’t help you narrow down on the PaaS for your startup—because one can decide only after considering the nuances of one’s use-case, the skillset of the team, and the associated costs. However, our hope is for this blog to help you navigate through the various technologies that can help you solve for your growing scale.
Alternatives that don’t make the cut
Hence, this article doesn’t recognize the following as practical EB alternatives:
- Heroku: Despite its unmatched developer experience, we do not recommend starting on Heroku anymore because it’s often much more expensive at scale than any other alternatives, and it hasn’t released any notable upgrades for many years. For example, it still doesn’t support HTTP/2.
- IaaS: IaaS requires you to configure your servers, specify networking rules, manage autoscaling, security updates, etc., all on your own. While this method gives you more control and flexibility than a PaaS like Elastic Beanstalk, it comes at a considerable cost of hiring a large specialized ops team.
- FaaS: Faas is suitable for running asynchronous jobs and event-driven applications like RESTful. And in many of these use-cases, FaaS is a spin-off of your core application, not the core one. For FaaS-friendly use-cases, it might also be your core application when you’re just starting off and get inconsistent traffic peaks. But this post addresses startups with a much broader range of use-cases than those suitable for FaaS.
Moving on to Alternatives.
Legacy Fully-managed PaaS on Public Clouds
There are 2 PaaS solutions, one each by the other top two cloud providers: Google and Microsoft, that are near equivalents to Elastic Beanstalk:
The primary benefit of using any cloud provider’s PaaS offering, be it Elastic Beanstalk, App Engine, or App Service, is faster time to market by eliminating the overhead of handling details of deployment, capacity provisioning, load-balancing, security, scaling, and application health monitoring.
So, how do you evaluate them against each other?
Google App Engine
While it’s as feature-rich and battle-tested, now Google itself considers App Engine a legacy product. We’ve included it as an alternative in this post because some of you might have asked us why if we didn't. Today, Google itself recommends that App Engine developers move to the more modern Cloud Run—the sister service to App Engine. (More on it later)
Azure App Service
If your application uses Microsoft technologies such as .NET, it’s just easier to run your application on App Service than on EB or App Engine. But again, similar to Elastic Beanstalk and App Engine, it’s a legacy PaaS. You’re better off evaluating Microsoft’s more modern PaaS offerings.
Elastic Beanstalk, App Engine, and App Service are all best suited to run simple web applications or mobile app backends in a serverless platform. These are also legacy offerings. While they receive regular updates, few notable features have been added to them in the last few years. Whether you’re looking to choose your first PaaS or an alternative to an existing Elastic Beanstalk setup, we strongly recommend that you continue reading to learn more about the more modern alternatives that along with being fully managed and serverless, are also future-proof.
However, if you still believe that one of these PaaS is just enough for your use case, and want to choose one of them, here’s what we have to say. Features or underlying implementation will rarely decide which one of these you pick because you can accomplish any use-case with any one of them (with or without workarounds). So, there would be two ways of thinking about your decision:
- If you’re already using AWS’s Elastic Beanstalk, migrating to another cloud (though not unheard of) just for their PaaS (App Engine or App Service) would rarely be an ideal choice unless your team’s expertise is now with another cloud provider, or there’s a significant cost difference in using features that are of interest to you.
- If you’re choosing your first PaaS, do a cost-benefit analysis of the services you want to run, how they will interact with each other, and your team’s experience with that specific cloud provider.
Note: Other smaller cloud providers like DigitalOcean offer similar services with likely much better customer support and at a lower cost but the breadth of use-cases that you can handle with them is limited as compared to other cloud providers’ PaaS.
Moving on to the modern alternatives.
PaaS on Private Clouds
Fly vs Render vs Railway
While Render, Fly and Railway are often pitted against each other when searching for a Heroku-like experience, they are not near-equivalents. So first, let’s compare them with each other:
- Render is much more Heroku-like aka polished in its developer experience and capabilities such as documentation, dashboards, CLI, etc than Fly or Railway.
- Render supports much fewer regions than Fly. There's no information about the regions supported by Railway.
- Fly and Render's pricing is complex. Pleasantly, Railway's pricing is usage-based with a generous free tier.
- (As of now) Both Fly and Render provide fully-managed Postgres. Railway supports no-config integration with Postgres and few other databases but none of these integrations are fully-managed.
- None of Fly, Render or Railway support queues. So, for use-cases that require these capabilities, they’re not a fit.
- Both Render and Railway support Monorepos; Fly doesn't.
If you’re already using Elastic Beanstalk and are considering migrating for flexibility or to manage more scale, none of Fly, Render or Railway is a fit. In fact, they might be more limiting.
But if you’re looking for your first PaaS, you should know the following:
- Fly is optimized for edge apps like no other PaaS and is a top contender if you’re building such an app.
- (As of now) Fly, Render or Railyway are a great fit for use-cases like running a static website or building a simple CRUD application or an application that doesn’t require a database at all (assuming your runtime is supported).
- Since they all support docker images, your lock-in is fairly limited to their proprietary features. So, lock-in should not be a concern while evaluating them.
- Unless you’re looking to make use of Fly-only features, Render and Railway are more developer-friendly and might be more future-proof.
- Railway's simple pricing makes a case for trying it before anyone else.
Container-native PaaS on Public Clouds
Container-native PaaS is a serverless, fully-managed service to deploy containerized applications and APIs.
Like legacy PaaS, you can either provide the source code or a container image, and they take care of deployment, upgrades, load-balancing, scaling, security, etc. so you can focus on delivering business value.
But unlike legacy PaaS, they’re optimized to build and host not just web and mobile applications but also APIs, microservices, long-running processes, background tasks, and event-driven applications.
There are 3 noteworthy container-native fully-managed PaaS on public clouds: Google Cloud Run (generally available from November 2019), AWS App Runner (launched in May 2021), and Azure Container Apps (generally available - May 2022).
Cloud Run vs App Runner vs Container Apps
- While they all can deploy from both container images and source code, they each have different constraints on what type of images, source code repositories, and language runtimes are supported.
- Cloud Run supports more languages than Container Apps and App Runner as of today.
- Cloud Run and Container Apps support HTTP/2, WebSockets, and gRPC but App Runner doesn't.
- Cloud Run and Container Apps both support scaling down to 0 while App Runner doesn’t yet.
- The support for background jobs is not ideal in App Runner and Cloud Run but Container Apps claims to support them.
- Cloud run supports blue/green, canary, and rolling deployments. Container apps support only blue/green and canary deployments. But App runner doesn’t support any of these.
- Container Apps support multiple containers in a single service but Cloud Run and App Runner don’t.
- Almost no lock-in Cloud Run: It is based on KNative which is open source. Cloud Run is only a layer on top of KNative which is open source. So, you can deploy your container in any K8S cluster using KNative definitions.
- Container App: Your only investment is in creating the container image, and then running a few commands to deploy it. Also, it is powered by Kubernetes which is open source. So if you choose to migrate, you’ll be able to do it with relative ease.
- App Runner: It runs on ECS Fargate which is a proprietary AWS offering but your investment is limited to providing the container image while it takes care of the rest (being a PaaS). So there is little lost effort if you choose to migrate.
- Autoscaling in Cloud Run works out of the box—without you having to specify any rule—based on its default behavior of creating a replica for every 100 concurrent requests. But, both App Runner and Container Apps require you to specify auto-scaling rules.
- Each of App Runner, Container Apps, Cloud Run, Fly, and Render are relatively new PaaS and hence haven’t been battle tested.
- While they’re all relatively new, Fly and Render will inevitably be more limiting than their container-native public cloud counterparts because the public clouds have an extensive set of offerings that you can use to solve just about any use case. It might not be a neat way to solve it but it won’t block you. On the contrary, with Fly or Render, once you hit a wall with their capabilities, you have to migrate out of them.
- If you’re looking for your first PaaS they all should be evaluated against your use-case and team skills.
- However, if you’re looking to migrate away from Elastic Beanstalk for more flexibility at scale, do evaluate App Runner and also AWS’s CaaS (more on it later).
Containers as a Service (CaaS) on Public Clouds
All the above PaaS options allow you to develop and deploy applications without the burden of building, managing, and maintaining infrastructure. Container-native PaaS is almost the same as CaaS except that in some cases, as we’ll see, CaaS offers more control.
This abstraction of container-native PaaS works beautifully at the beginning for most startups but if at some point you require more control, you’ll need to evaluate the only other notable CaaS offering: ECS. Let’s take a look at some of its notable pros and cons:
AWS ECS (with or without Fargate)
- Requires tens of pieces to be assembled before you can deploy anything on it. So, the user experience is unpleasant.
- Setting up auto-scaling on ECS is complicated (like the rest of the experience of using it).
- Is fully proprietary, and enforces you to completely rely on AWS, the number of resources you need to create, and the format for writing application definitions ensures that we’re locked into AWS. If you choose it, you’ll find it extremely hard to move out. But again, lock-in needs to be evaluated against what it makes easy for you.
- Its proprietary nature has also led to the lack of community support on it.
Note: We’ve not included Azure Container Instances (ACI) as an alternative because it doesn’t support horizontal auto-scaling. Vertical scaling is also purely manual. All you can do is run single instances that are isolated from each other. Hence, ACI cannot be used in production for any application unless a single instance of the app is sufficient in your use case.
- Regardless of your use case, skip ACI altogether.
- If you’re already on AWS, and if your use-case is not a fit for Kubernetes, evaluate ECS against App Runner for running managed containers.
- ECS provides more flexibility against App Runner at the cost of more administrative work from you. For example, it can run multiple containers in a single service while App Runner cannot.
- ECS’s sub-par developer experience requires significant setup time. You should be mentally prepared for that.
- If your goal is to hire zero ops, ECS is not recommended.
- If AWS is not a constraint, then Cloud Run is the most developer-friendly for deploying containerized applications. It comes with the least lock-in and is the most hands-off way to run serverless and managed containers. We highly recommend that you evaluate it.
Kubernetes as a Service (KaaS) or Managed Kubernetes
Logically CaaS would be the next step if one wanted to migrate out of a PaaS for flexibility and scalability. But some use-cases warrant considering Kubernetes as well. KaaS or Managed Kubernetes Services, such as GKE, EKS, and AKS, abstract away the management of the control plane, and hence are easier to work with than using Kubernetes directly.
But what should you know about it so you can take a more informed decision?
- Kubernetes is an open-source container orchestration system. CaaS like ECS has a proprietary container orchestration system - which is their main drawback against Kubernetes. (Though, Cloud Run and Azure Container Apps don’t suffer from this as they’re powered by Kubernetes)
- The great thing about KaaS is that it is Kubernetes - which is open source, has large community support, and a growing ecosystem of tools to solve common use-cases - so there’s minimal lock-in and infinite scalability.
- While KaaS simplified management of the control plane, it still leaves the administration of the worker nodes - such as upgrades and networking to you. That’s a huge overhead that requires a dedicated team with specialized Kubernetes knowledge.
- Evaluate whether Kubernetes is required for your use case, or will containers work just fine for you (via container-native PaaS or CaaS).
- Should you decide to go ahead with Kubernetes, assess whether you have the team to operate KaaS like GKE, EKS, and AKS.
- In general, GKE is the most mature KaaS as of today, and also what we’d recommend.
If you don’t have the time and resources to put behind KaaS today, but decide to go the Kubernetes way, there might be a middle ground between KaaS, CaaS, and PaaS.
Middle Ground between PaaS, CaaS, and KaaS
A middle ground between PaaS, CaaS, and Kaas would take the best characteristics of each of them, and will not have their respective limitations.
- Unlike KaaS or CaaS, and exactly like PaaS - it will be fully managed and serverless
- Unlike proprietary CaaS or PaaS, it’s based on an open-source tool such as Kubernetes.
- That does not bind you to a specific cloud provider, or its tools.
- That gives you the room to integrate with and take advantage of the huge ecosystem of third-party tools for logging, monitoring, storage, etc.
At Argonaut, we’re trying to build such a platform. Argonaut is an orchestration layer (abstraction) above your cloud account. In other words, it operates your cloud account.
- It’s fully managed
- It’s container-native
- It has native support for working with KaaS or managed Kubernetes like EKS (GKE support coming in a few weeks) as well as FaaS like AWS Lambda (Cloud Functions support coming soon).
- You can run any helm chart on applications deployed with Argonaut.
- It has an expanding ecosystem of third-party add-ons be it for monitoring, logging, search, etc. Examples include Datadog, Prometheus, ELK, etc.
When moving to any new way of operating infrastructure, be it using a PaaS or CaaS, a good rule of thumb is to use the highest level abstraction that will solve your problem without putting any unnecessary limitations on the workload. We recommend the following for beginners:
- Start with a container-native PaaS and then slowly transition into an opinionated CaaS or KaaS. This helps you get started quickly, bootstraps your knowledge, reduces the barrier to adopting optimal technologies, and helps you learn good practices through embedded defaults.
- Over time, as your depth of knowledge increases, you can start fiddling with the defaults or even use the native technology directly.
- Heroku’s pricing is per dyno, i.e. the containers that Heroku uses to run on top of EC2 at the backend. Since Heroku doesn’t operate the underlying infrastructure stack (on AWS), you end up paying a total of Heroku for the dynos and AWS for the infrastructure. As against Cloud Run, Container Apps, or App Runner where you pay only for the workload that your job executes and not for the traffic as well. And hence they come out much cheaper than Heroku.