Heroku is a popular platform-as-a-service (PaaS) cloud that allows you to run your applications in a serverless manner. This blog is about optimizing applications running in Heroku: making them run faster, giving them better security, and generally fine-tuning them.
What Is Heroku?
Deploying Heroku Applications
Ease of use and being developer-centric are two of the main selling points of the Heroku platform. The platform is geared toward making the developer’s life easier. Accordingly, deploying applications to Heroku is easy. Here’s what you need to do:
- Install the Heroku CLI
- Have a git repository ready
- Create an Heroku app
- Push the code
- Deploy one or more Heroku Dynos (essentially containers)
And… done. Once your app is there, it’s easy to scale it to more working Dynos (one command) and apply add-ons (backups, connecting to AWS services, sending emails, etc.).
However, this ease of use comes with a price. Since Heroku itself uses the same AWS instances you would normally use if you work with AWS services directly, the total price you’ll pay is composed of:
- The AWS infrastructure (which itself is not cheap, and costs much more than hosting on a bare-metal server)
- The Heroku platform premium on those services above
- Cost per each add-on you might use
This can get pricey fast, so optimizing your Heroku applications is even more important than optimizing your regular AWS/on-premises infrastructure.
Optimizing Apps Running in Heroku
Choosing the Right Dyno Type
When deploying an Heroku application, you have several Dyno types to choose from. Choosing the right Dyno for your application needs can save you money. For instance, there’s no point in starting with an extra-large Dyno when your app can work with the free tier. In addition, once you need a larger Dyno, you should consider whether you need to scale up (move to a larger Dyno) or scale out (run more instances). As a rule of thumb, running more containers of the same type will be cheaper than switching to a larger type of Dyno. That said, you should check for your specific use case.
Heroku Plans and Costs
The Standard plan is the minimum plan you should choose if you want to deploy commercial applications to Heroku. Switching from a 512MB RAM Dyno to a Dyno with twice that amount results in additional US$25 per month per Dyno. Switching to the Performance plan, which promises stable performance for your customers, raises your cost to at least US$250 per month per Dyno.
The high premium you pay for Heroku convenience and time saved on DevOps work suggests (or even dictates) you should thoroughly analyze performance issues and solve them using existing resources instead of scaling up/scaling out. Heroku comes with a centralized distributed logging facility called Logplex. It collects logs from your working Dynos and presents them in a unified interface.
However, Logplex is provided only as a CLI tool. And the logs aren’t very developer friendly.
In addition, the CLI tool provides only limited filtering and searching capabilities. Debugging the root cause via historic log data is difficult and requires manually parsing the log output. This makes debugging cumbersome and time-consuming. Finding the cause of performance issues without scaling infrastructure is vitally important for your (or your employer’s) financial peace of mind, so a better solution is needed.
Dedicated Cloud Logging
Dedicated cloud logging providers such as SolarWinds® Papertrail™ have a rich suite of features tailored to this and other use cases. Using Papertrail, for example, you can view and search messages from all your applications and services from a single search bar. The tail feature in Papertrail lets you search and pause live log streams features and the log velocity graph lets you visualize error volumes. It also has an alerts mechanism designed to send real-time notifications about events (and possible problems) as they unfold. This useful Heroku add-on is available here.
Another way to optimize your performance is to gzip content. Gzipping content is a well-known best practice and a “low-hanging fruit” in the world of optimizing front-end performance. By gzipping text/js/css files, you reduce the payload size to be downloaded to the client’s machine. As server configuration isn’t available in Heroku, you should use the relevant solution for your language and framework of choice.
Non-blocking is the new gold standard and the holy grail of developers worldwide. You can use the benefits of the non-blocking async paradigm in Heroku using background jobs. With non-blocking, a client doesn’t need to wait for a response from the server from which their email was sent, for instance. Likewise, if your app needs to store data on a remote service after client’s operation (like uploading a file), this can be done behind the scenes, thus improving the user’s experience. Heroku fulfills background jobs with worker Dynos. Worker Dynos are scaled independently of web Dynos.
Keep Your Packages Updated
Whatever language you use, you probably use some open-source components as a foundation or feature fulfillment instead of developing everything from scratch. That’s usually a great time-saving approach. However, it’s important to keep those packages updated. Package updates usually provide critical security fixes (you don’t want your application hacked). Moreover, software updates sometimes provide better performance, which can in itself help lower the Heroku bill. The same can apply to your language version, as security vulnerabilities are found in language source code.
Heroku is a useful PaaS tool, and your Heroku apps should be optimized. There are limits to the Heroku built-in logging facility, but SolarWinds Papertrail can help you troubleshoot fast, move quickly, and save money on your Heroku bills. Heroku is a great platform for developers, and optimizing your apps can make it even better.
This post was written by Alexander Fridman. Alexander is a veteran in the software industry with over 11 years of experience. He worked his way up the corporate ladder and has held the positions of Senior Software Developer, Team Leader, Software Architect, and CTO. Alexander is experienced in front-end development and DevOps, but he specializes in back-end development.
Prices as of October 2020