PaaS, Heroku and Java - A Perfect Combination
Heroku, with its powerful features and rich eccosystem of add-ons, is the perfect PaaS (Platform-as-a-Service) for deploying your Java applications.
Please keep in mind that the opinions expressed in this article are based on the state of affairs of early 2020 when it comes to the different tools and products we'll be discussing.
You've got a few options when it comes to running your Java applications (in production) in 2020:
- You can rent individual server instances from a provider like AWS (using EC2 instances) or DigitalOcean (using Droplet instances), manually configure a reverse-proxy like Apache or Nginx for load-balancing and/or SSL offloading, and manually set up a CD pipeline to automatically publish the latest version of your application on every code push
- You can use an application platform like Heroku (owned by Salesforce) or AWS Beanstalk, where you're still renting individual server instances, but where all of the CD pipeline, load balancing and SSL stuff is usually taken care of; in many cases, you'd only have to connect your repository, give some basic instructions on how to build your application, verify your domain (for SSL), and you'd be good to go
- You can rent CPU time via AWS Lambda or Google Cloud Functions where your application automatically gets started on every (HTTP) request, and automatically gets shut down afterwards; the big difference is that you'd be renting function execution time rather than individual server instances
Each of these three runtime environments describe a different paradigm:
- IaaS; Infrastructure-as-a-Service
- PaaS; Platform-as-a-Service
- FaaS; Functions-as-a-Service
So, should you go with a PaaS environment like Heroku for your next Java application? Or would an IaaS environment like AWS EC2, or a FaaS environment like AWS Lambda be better? The answer to this question obviously depends on the specifics of your business. But I would argue that the answer is yes. And the core of my argument is actually pretty simple:
- Your customers probably don't care about the internal infrastructure required to run your Java applications in an IaaS environment, so you'd be better off serving their direct business needs, rather than spending a ton of money on experts to build, configure, secure and maintain your own custom infrastructure (which won't actually be battle tested until your engineers and customers have gone through the pain of downtime caused by misconfigured infrastructure components)
- The Java ecosystem hasn't matured enough (in terms of frameworks) to build and support applications with lightning fast startup-times, which would be required for running your applications in a FaaS environment
- Therefore, a PaaS environment is the only way forward
Now I was probably a bit quick there. This line of thinking usually evokes some ifs, buts and whatabouts in response, so let's have a look at some of the typical counter arguments.
#1 - PaaS is so much more expensive than IaaS
I think this is only true if you're operating at scale - I agree it doesn't make economic sense for Facebook to run all of their applications on Heroku. The argument I would put against this, though, is that you shouldn't underestimate the cost of hiring and retaining expert ops engineers and sysadmins.
You can get up and running on Heroku with a fully-managed (paid) Dyno instance for just $7.50, and a fully-managed (paid) Postgres instance for an additional $9, but let's consider a more serious setup.
The beefiest Heroku Dyno will run you about $500 per month, which would come down to $1000 a month for a two-instance (automatically load-balanced) setup. Adding a managed Postgres instance (Standard 5, 61 GB RAM, 1 TB storage, 500 connections) will run you about $1400 per month. Throwing in a managed Kafka cluster (Standard 1, 3 brokers, 300 GB capacity) will be an additional *$1800\* per month.
Now this is a serious $4200 a month setup, completely managed by Heroku and capable of handling a vast amount of traffic. Depending on your region's average sysadmin salary, having just a single infrastructure expert will typically run you (a lot) more than $4200 per month - and that doesn't even include the raw costs of the actual server instances, or the total time and associated opportunity cost to actually build all of this custom infrastructure.
There's an economic tipping point in this outsource-everything VS do-it-yourself comparison, sure. But my suggestion would be to, at least, start out with a PaaS environment for new projects, and take advantage of all its benefits.
#2 - PaaS is too constraining, my application and system architecture requires IaaS flexibility
If you can design your application or (sub)system to match the following criteria, it should be a good fit for Heroku.
- Adhere to, at least, factors III, IV and VII of the Twelve Factor App
- Only rely on HTTP or WebSockets as the protocols for incoming (public) traffic
If your application doesn't meet these criteria, I'd argue that it's worth exploring to see if you can make your application fit them. There are some caveats to this, though;
- If your application is very resource hungry for CPU or RAM, Heroku's Dynos might not be powerful enough for your needs
- If your application is about machine learning or bitcoin mining, you're out of luck because Heroku doesn't offer any GPU-optimized Dynos at this point
In these cases, consider a hybrid approach where the specialized stuff gets its own IaaS (or bare metal) environment and where the other stuff can run in a fully-managed PaaS environment.
#3 - You can't do microservices with PaaS
At a fundamental level, distributed systems typically require the following types of communication between microservices:
- publish-subscribe (events)
It's true that Heroku doesn't allow inter-node communication,
meaning that cluster managers like Zookeeper are out of the window.
But that doesn't stop your account-microservice, hosted as a Heroku Dyno behind
from communicating over the public HTTP port with the authentication-microservice,
hosted as a Heroku Dyno behind
All of this is to say that if you can limit yourself to the HTTP protocol, request-response shouldn't really be a problem.
Furthermore, because all Heroku Dynos are free to connect to external components (like RabbitMQ, AWS SQS, or other message brokers), publish-subscribe shouldn't really be a problem either. This pattern is even mentioned in the official Heroku documentation, and there's an entire "Messaging and Queueing" section on the Heroku add-ons page, listing various managed queue solutions.
#4 - PaaS is too insecure; I must have full control over my infrastructure
Are you sure? Because Heroku is pretty serious about your security, and has the resources to dedicate an entire team to it. Also, because your Heroku applications will be running in a (slightly) constrained environment, the attack surface is probably going to be a lot smaller than it would be with your custom infrastructure.
Again, there are some caveats to this. If your business operates in a heavily regulated industry like finance, pharmacy or aviation, Heroku might not be the best fit.
#5 - Regarding FaaS and slow Java startup times, what about frameworks like Micronaut or Quarkus?
I agree that Micronaut and Quarkus, thanks to their focus on quick startup-times and low memory footprints, are both highly interesting frameworks to try out in a FaaS (serverless) environment.
However, since both of these projects have had their first releases around late 2018 - early 2019, I would refrain from betting your entire system on these technologies until they've had some more time to mature and gain momentum, limiting any experimentation to POCs and non-critical applications.
There's definitely a place for IaaS environments, and there probably will be a place for FaaS environments as well, once the frameworks have matured a bit. If you're doing Java in (early) 2020, however, I can only recommend trying out a PaaS environment for your next application.
Also, you've probably noticed that I've been equating PaaS with Heroku up until this point, without actually making the case for Heroku over some of the other (non-enterprise) PaaS providers with Java support, like:
The simple reason is that, apart from Elastic Beanstalk, I haven't had much personal experience with these other providers 😅. And since Heroku has worked so well for me, there's honestly been little motivation to try out anything else.
I will end this article with an overview of some of my favorite Heroku features.
- The Heroku Postgres add-on
- The Heroku Redis add-on
- The add-on marketplace in general, through which I've often discovered interesting services
- The easy-to-use Heroku dashboard
- Automated deployments from any connected GitHub branch
- Automated SSL Certificate Management (ACM) for custom domains (paid Dynos only)