Serverless Containers is first of all a tradeoff between running costs and maintenance costs. Everything that can run in a Serverless Container (Fargate) can run on a non-serverless compute (ECS, K8S/EKS, or without an orchestrator at all). The other way around is entirely possible. Due to the technology limitations, some applications can not run on Serverless Containers.
Besides the technical limitations, the financial aspect should be considered as well. A fully managed / Serverless Compute transforms the varied future costs of unknown maintenance, to a known fixed cost of zero maintenance paid for for now. Money invested into a system’s resilience.
To better understand this, let’s have a look at an example comparing the Elastic Container Service (ECS), which is a Manager Orchestrator. It is free, but you’d be paying for the underlying servers and will be maintaining them on your own. For example, if the Orchestrator Agent has been updated, you’d need to upgrade and replace your entire server fleet.
To compare the pricing of the two (Fargate and ECS) the two let’s calculate the cost of running a single container for 30 days straight. It would require 2 vCPU and 1GB of memory.
It would cost you a total of $19.2 to run it on Fargate:
$0.01264407 per vCPU per hour * 2 vCPUs * 24 * 30 = $18.2
$0.00138841 per 1GB memory per hour * 24 * 30 = $1
The smallest EC2 instance (t3a.micro) that has enough resources to run this Container will cost a total of $6.768 ($0.0094 per hour * 24 * 30).
The price difference per Container is $12.4, or 283%. If there’s a need for a high availability design that would be a difference of $37.2. This is the costs of peace and quiet of not maintaining an EC2 instance at all. I call this a premium.
This premium grows linearly with the required processing power so it may not scale for your use case, or the premium itself would not be worth the cost of zero maintenance.
At Wiser (2016), for example, we had a web scraping service that required running 5,000 concurrently running containers for 24/7, each required one vCPU. Let’s say that even if it were possible on Fargate, that would incur a monthly premium of $31,000. The error handling was a simple one, as web scraping is an “endless stream” of “offline jobs” into a queue, it was only a matter of retrying. It was not worth paying $31k in this case, the costs of hiring two DevOops.
Strict Resource Allocation
With Fargate you’re paying for server resources, both vCPU and RAM, which are allocated in advance to a Container. If they are not 100% utilized, that would be paying for unused processing power is what we are trying to avoid.
Containers on ECS can share server resources so no need to allocate them in advance.
If we’ll consider Wiser’s web scraping user case, a Container’s operation required a lot of I/O, thus each container’s vCPU was not 100% utilized during its entire run. For certain use cases, you can bin back even more Containers on a single EC2 server thus reducing the costs even more.
It is not necessary to decide in advance that all Containers must be either Serverless or not. You can run some of your applications on ECS and others on Fargate.
At Silo we had some “mission critical” containers that were part of the messaging system. If one of them would crash, all hell will break loose. As one time at one of our development environments the ECS servers went down for no apparent reason, we’ve moved them to Fargate for higher resilience.
Other Containers, such as those of Event Storage and Event Analyze, which could sustain a good time down, could have been kept on ECS. The only reason they were moved to Fargate as well were because now it was not worth the price of sustaining an under utilized EC2 server. There was nothing blocking us from using ECS for any other future applications.
Distributing Container instances between both ECS and Fargate, as far as I know, is currently not possible OOTB. As it is currently an either/or situation, the created Load Balancer can not be shared between two Services one running on ECS and the other on Fargate. I theroize it can be programmatically taken care of as the LB has API to register and deregister instances, or maybe with two load balancers. I have heard that AWS are working on a solution for that, one that also may allow a mixture between Functions and Containers as well.