---
title: "Heroku"
description: "Heroku is a cloud platform as a service where you can deploy projects and websites. It supports several programming languages, so it’s no surprise that Heroku’s really popular."
---

# Heroku
> Heroku is a cloud platform as a service where you can deploy projects and websites. It supports several programming languages, so it’s no surprise that Heroku’s really popular.

## Articles

### [Rails 5.2 Active Storage: Previews, Poppler, and Solving Licensing Pitfalls](https://yomu.fyi/post/rails-5-2-active-storage-previews-poppler-and-solving-licensing-pitfal.md)
- Company: [Heroku](https://yomu.fyi/company/heroku.md)
- Author: Richard Schneeman
- Published: May 10, 2018
- Type: Tutorial

Rails 5.2’s Active Storage adds file uploads and attachments for Active Record models, with backing services such as AWS S3 and previews for PDFs and videos, but its beta PDF support depended on MuPDF. Security and legal review found MuPDF’s AGPL licensing could require commercial licensing, so Terence Lee updated Active Storage to support Poppler, an open-source PDF backend merged before release. Deployment guidance uses S3 through aws-sdk-s3, configures :amazon rather than the non-scalable local disk, and installs a custom buildpack containing FFmpeg and Poppler. The example Rails app attaches files to a Bulletin model, accepts uploads, and chooses PDF or video previews, image variants, or downloads according to available binaries and MiniMagick.


### [MJIT: A Method Based Just-in-time Compiler for Ruby](https://yomu.fyi/post/mjit-a-method-based-just-in-time-compiler-for-ruby.md)
- Company: [Heroku](https://yomu.fyi/company/heroku.md)
- Author: Jonan Scheffler
- Published: Apr 12, 2018
- Type: Explainer

Ruby programs are compiled into YARV instructions and executed by a stack-oriented virtual machine, while register-oriented representations can expose more opportunities for compiler optimization. The post explains how YARV represents a simple expression, contrasts stack and register architectures, and introduces Vladimir Makarov’s Ruby RTL, an intermediate representation distinct from GCC’s RTL. MJIT uses RTL generated by MRI to make speculative, operand-specific optimizations, then compiles methods to machine code rather than relying only on interpretation. The interview discusses deoptimization: when assumptions change, MJIT generates a new machine-code version and can switch between JITed execution and RTL interpretation. The participants say this overhead should be tiny and should not degrade performance overall, while acknowledging edge cases where MJIT is not faster and that benchmarking JITs is difficult.


### [Ruby CVE-2017-17405: Vulnerability in Ruby’s FTP Implementation](https://yomu.fyi/post/ruby-cve-2017-17405-vulnerability-in-ruby-s-ftp-implementation.md)
- Company: [Heroku](https://yomu.fyi/company/heroku.md)
- Author: Etienne Stalmans
- Published: Apr 6, 2018
- Type: Incident / postmortem

CVE-2017-17405 affected Ruby’s net/ftp implementation, where a filename returned by an FTP server could reach Ruby’s open function and enable command execution. The issue was found while investigating CVE-2017-8817 in libcurl and checking whether Ruby used libcurl or had a separate FTP implementation with comparable wildcard behavior. Reviewing Ruby 2.4.2 source identified the 1,496-line ftp.rb file and the gettextfile method, which called open(localfile, "w") without validating the value. A proof of concept made an FTP client request a file list containing a pipe-prefixed payload; Ruby passed it to the shell, producing remote code execution and creating a file containing id output. Ruby replaced open with File.open, released the fix in 2.4.3, and assigned CVE-2017-17405; affected versions included Ruby 2.2.8 and earlier, 2.3.5 and earlier, 2.4.2 and earlier, and 2.5.0-preview1.


### [Deconstructing Monolithic Apps with SHIFT Commerce](https://yomu.fyi/post/deconstructing-monolithic-apps-with-shift-commerce.md)
- Company: [Heroku](https://yomu.fyi/company/heroku.md)
- Author: Ryan Townsend
- Published: Mar 13, 2018
- Type: Explainer

SHIFT Commerce describes its move from a monolithic application toward microservices, while arguing that architectural change should address concrete problems rather than follow fashion. The company identifies communication overhead, governance and high-risk deployments, and language or infrastructure limitations as reasons to extract functionality, including its Order Management Suite, admin panel, and integration system. SHIFT uses managed Apache Kafka on Heroku as an asynchronous event stream, with chronologically ordered, durable messages organized into topics so services can maintain local datasets. Its eight-step migration progressively adds producers, builds a consumer-backed database, tests and replicates logic, enables feature-flagged traffic, exchanges events, and removes deprecated monolith code. SHIFT reports more regular releases, lower latency on I/O-restricted API calls, and prevention of user-facing outages, while saying the migration remains ongoing.


### [A House of Cards: An Exploration of Security When Building Docker Containers](https://yomu.fyi/post/a-house-of-cards-an-exploration-of-security-when-building-docker-conta.md)
- Company: [Heroku](https://yomu.fyi/company/heroku.md)
- Author: Etienne Stalmans
- Published: Mar 8, 2018
- Type: Incident / postmortem

The post examines how a Docker-based, multi-tenant build environment can expose untrusted code when layered isolation is misconfigured. It traces a setup using AWS CodeBuild, Docker-in-Docker, and per-step build containers, then tests directory traversal through configurable Dockerfile paths before focusing on daemon networking. The vulnerability comes from starting dockerd with tcp://0.0.0.0:2375 and placing containers on a shared default network; build code can reach the daemon, issue Docker commands, mount the host filesystem, and retrieve container-managed AWS credentials. The excerpt reports a reverse shell, access to the CodeBuild filesystem, and temporary credentials whose impact depends on IAM permissions, while noting that the build must remain alive. The stated fix is to remove the TCP listener and retain the mapped Unix socket.


### [Using HTTP Headers to Secure Your Site](https://yomu.fyi/post/using-http-headers-to-secure-your-site.md)
- Company: [Heroku](https://yomu.fyi/company/heroku.md)
- Author: Caleb Hearth
- Published: Mar 1, 2018
- Type: Tutorial

A straightforward Static Buildpack app received an F, scoring 20/100 in Mozilla Observatory because several security response headers were missing, despite redirecting visitors to HTTPS with an Automated Certificate Management certificate. The walkthrough examines failures for Content Security Policy, HTTP Strict Transport Security, X-Content-Type-Options, X-Frame-Options and X-XSS-Protection, then configures them through the static.json headers collection. The CSP restricts resource origins, blocks inline scripts by default, and uses a SHA-256 hash to permit the Google Analytics inline script without adding unsafe-inline. HSTS uses max-age=63072000, includeSubDomains and optionally preload, while other headers supply MIME sniffing, iframe and legacy XSS protections. After the changes, the reported checks pass, the configuration reaches an A and is later described as A+; the final recommendation adds Referrer-Policy and omits opt-in HSTS preload.


### [Dissecting Kubernetes Deployments](https://yomu.fyi/post/dissecting-kubernetes-deployments.md)
- Company: [Heroku](https://yomu.fyi/company/heroku.md)
- Author: Damien Mathieu
- Published: Feb 22, 2018
- Type: Explainer

Kubernetes Deployments provide declarative updates for Pods and ReplicaSets, enabling application versions to roll out gradually rather than restarting every Pod at once. The Deployment controller uses informers and triggers for Deployment, ReplicaSet, and Pod events, then synchronizes state by creating ReplicaSets and scaling old and new sets according to replica counts, max surge, and available Pods. During a rolling update, it waits for new Pods to respond before terminating old ones; progress deadlines help detect stalled rollouts, including crash loops. After completion, old ReplicaSets are cleaned up but a configured number is retained for rollback, which requires changing image tags rather than continually using :latest. The post also shows a Go informer that watches Deployment creation and update events and explains that the trigger-based design supports custom controllers.


### [Scaling ipify to 30 Billion Requests and Beyond on Heroku](https://yomu.fyi/post/scaling-ipify-to-30-billion-requests-and-beyond-on-heroku.md)
- Company: [Heroku](https://yomu.fyi/company/heroku.md)
- Author: Randall Degges
- Published: Jan 23, 2018
- Type: Problem & solution

ipify began as a free API that returns a caller’s public-facing IP address, created to help discover cloud instances’ external addresses without management APIs. Its initial implementation was a sub-50-Loc Node service deployed on one Heroku dyno for about $7/month; rising usage caused slow responses and 503s. Investigation showed roughly 10 rps, while one Node process and string manipulation around X-Forwarded-For limited throughput; clustering doubled capacity, and the implementation later used Go. Heroku supplied load balancing, automatic restarts, and horizontal dyno scaling as traffic expanded through bursty demand and malicious use; the operator chose manual capacity rather than paid autoscaling. The service surpassed 30B requests per month, routinely serving 2k–20k RPS with 1–20ms average response times at $150–$200 monthly; ownership later passed to whoisxmlapi.com, whose work includes an improved UI and more data endpoint.


### [Kafka Streams on Heroku](https://yomu.fyi/post/kafka-streams-on-heroku.md)
- Company: [Heroku](https://yomu.fyi/company/heroku.md)
- Author: Jeff Chao
- Published: Dec 19, 2017
- Type: Tutorial

Kafka Streams on Heroku shows how to organize, deploy, and scale Java stream-processing services using Kafka Streams, Apache Kafka, and the Heroku Runtime. The example contains a Text Processor that splits input from a textlines topic into words, an Aggregator that counts words in 10-second windows before writing to Postgres, and an independent Anomaly Detector that routes 10-second login-failure counts to urgent alerts or non-urgent email based on thresholds. A Gradle multi-project setup packages each service as an executable and uses a Procfile to run them as separate Heroku workers, while managed Kafka supplies the event-streaming infrastructure. Scaling is explained through Kafka partitions and Kafka Streams Stream Tasks: Stream Threads provide vertical scaling, dyno counts provide independent horizontal scaling, and Kafka Streams redistributes tasks when workers change or fail.


### [Jekyll on Heroku](https://yomu.fyi/post/jekyll-on-heroku.md)
- Company: [Heroku](https://yomu.fyi/company/heroku.md)
- Author: Caleb Hearth
- Published: Dec 13, 2017
- Type: Tutorial

Jekyll can be deployed on Heroku to use its plugin system, but relying on jekyll serve would use Ruby’s single-threaded WEBrick rather than a production-oriented web server. The setup installs Ruby with ruby-install and chruby, then installs Bundler and Jekyll, creates a site, and tracks it in Git. Heroku’s official Ruby buildpack handles dependencies and runs a Rake assets:precompile task that executes jekyll build, while the Static buildpack serves the generated \_site/ directory according to static.json. The example pins Ruby 2.4.2, adds Rake, enables clean URLs and HTTPS, and completes with a successful deployment of the generated site to a Heroku URL.


### [In the Cloud, No One Can Hear Your OutOfMemoryError](https://yomu.fyi/post/in-the-cloud-no-one-can-hear-your-outofmemoryerror.md)
- Company: [Heroku](https://yomu.fyi/company/heroku.md)
- Author: Joe Kutner
- Published: Oct 2, 2017
- Type: Announcement

Heroku introduces Heroku Exec and Language Runtime Metrics to improve production monitoring, inspection, and debugging for applications running on dynos. Heroku Exec creates secure TCP and SSH tunnels for SSH sessions, port forwarding, remote debugging, and diagnostic tools, while the Heroku Java CLI integrates jmap and VisualVM. A synthetic Java memory-leak example shows VisualVM tracking heap growth and jmap producing a downloadable HPROF heap dump that Eclipse Memory Analyzer identifies as Servlet-held FakeLeak objects. The metrics feature, enabled through the Heroku Metrics buildpack on paid Standard-or-above dynos, displays heap, non-heap, and garbage-collection activity in the dashboard through a Java agent using Prometheus; JVM-language support is generally available, while Go support is in beta.


### [Evolution of the Heroku CLI: 2008-2017](https://yomu.fyi/post/evolution-of-the-heroku-cli-2008-2017.md)
- Company: [Heroku](https://yomu.fyi/company/heroku.md)
- Author: Jeff Dickey
- Published: Aug 15, 2017
- Type: Explainer

Between 2008 and 2017, Heroku's CLI evolved from Ruby (v1–v3) through Go/Node versions v4 and v5 to a pure Node v6 implementation. The rewrite addressed slower Windows performance, separation of the CLI's runtime from users' Ruby environments, migration to API v3, and limitations in Ruby-based plugin dependencies. V4 kept existing command syntax and output while adding features such as non-TTY color suppression and --json output; its Go core used Node for plugins, and the CLI became a collection of core plugins that could also be developed and installed independently. The team migrated commands incrementally, then added Flow, Babel, and improved tests, including Jest tests that run the flag parser. The resulting foundation supports modular, tested feature development, with cli-engine and more interactive interfaces planned.


### [Hello RedBeat: A New Celery Beat Scheduler](https://yomu.fyi/post/hello-redbeat-a-new-celery-beat-scheduler.md)
- Company: [Heroku](https://yomu.fyi/company/heroku.md)
- Author: Marc Sibson
- Published: May 2, 2017
- Type: Problem & solution

Heroku Connect relied on Celery Beat to trigger frequent periodic tasks while synchronizing Salesforce and Heroku Postgres data, but the default file-based scheduler developed intermittent pauses and hangs that required manual intervention. Existing SQL-backed scheduling introduced blocked transactions and pauses from periodically saving and reloading the full schedule, while an existing Redis-backed package retained similar reload behavior. RedBeat moves the active schedule and runtime metadata into Redis, allowing updates through Redis keys that Beat reads on its next tick without pausing or reloading. It also uses a lock to prevent concurrent Beat daemons, supports schedule updates from other languages, and has run in production for more than a year without recurring scheduler-related incidents.


### [Latency Incident Report: Socket Bind Before Connect](https://yomu.fyi/post/latency-incident-report-socket-bind-before-connect.md)
- Company: [Heroku](https://yomu.fyi/company/heroku.md)
- Author: Lex Neva
- Published: Mar 30, 2017
- Type: Incident / postmortem

An August 11, 2016 incident caused increased routing latency in Heroku’s EU Common Runtime, even though CPU, packet, memory, request, and socket metrics remained normal. The routing layer received EADDRINUSE while connecting to dynos, leading engineers to investigate Linux TCP port allocation, TIME\_WAIT, and the Erlang VM’s system calls with strace. They found that the VM called bind() with 0.0.0.0:0 before connect(), forcing Linux to allocate an ephemeral source port without knowing the destination; this made the ephemeral port range an effective per-instance traffic limit and could fail before 65,536 connections. Testing reproduced the failures and showed that setting SO\_REUSEADDR before bind(), exposed in Erlang as {reuseaddr, true}, removed the bind errors; the corresponding Vegur patch was deployed a few days later.


### [How We Found and Fixed a Filesystem Corruption Bug](https://yomu.fyi/post/how-we-found-and-fixed-a-filesystem-corruption-bug.md)
- Company: [Heroku](https://yomu.fyi/company/heroku.md)
- Author: Owen Jacobson
- Published: Feb 15, 2017
- Type: Incident / postmortem

An aborted Cedar-14 stack-image upgrade led container tools to truncate and overwrite a disk image while it was mounted as the read-only / filesystem for running dynos. Because direct writes bypassed filesystem caching and consistency mechanisms, reads alternated between cached pages from the old image and missing data from the truncated file, partially corrupting newly loaded programs. Applications consequently experienced elevated segmentation faults and other hard crashes for about five hours; a virtual-machine reproduction using an ext4 loop-mounted image and sleep reliably produced the same failure. Engineers migrated affected dynos to fresh hosts, then changed host-side permissions so installed filesystem images are read-only, and retested the conditions that triggered the incident.


### [Pulling the Thread on Kafka’s Compacted Topics](https://yomu.fyi/post/pulling-the-thread-on-kafka-s-compacted-topics.md)
- Company: [Heroku](https://yomu.fyi/company/heroku.md)
- Author: Tom Crayford
- Published: Jan 11, 2017
- Type: Incident / postmortem

Apache Kafka’s log cleaner for compacted topics could crash silently when its offset map lacked enough space to hold a full log segment. Because the broker continued running without that internal thread, superseded data accumulated, threatening node and potentially cluster stability. The post explains compaction’s two phases: building an offset map for newer messages, then rewriting segments while retaining the latest offset for each key, with the latest segment excluded from the map. Kafka was changed to remove the crashing assertion and track partial segment loads so cleaning can recover without fitting an entire segment in memory. The roughly 100-line patch shipped in Kafka 0.10.1.1, which the post identifies as Heroku’s default version, and prevents the cleaner from dying silently.


### [How We Sped up SNI TLS Handshakes by 5x](https://yomu.fyi/post/how-we-sped-up-sni-tls-handshakes-by-5x.md)
- Company: [Heroku](https://yomu.fyi/company/heroku.md)
- Author: Fred Hebert
- Published: Dec 22, 2016
- Type: Incident / postmortem

Heroku’s SNI TLS termination work exposed severe handshake performance problems under benchmarks designed to avoid session resumption, caching, and keep-alive reuse. Initial tests made nodes slow and unresponsive 7–8x earlier than comparable HTTP tests, while perf top showed Erlang garbage collection and ETS hash operations consuming unexpectedly large amounts of CPU. Tracing linked repeated ets.select\_delete calls to the centralized ssl\_manager process, where ssl\_pkix\_db’s certificate cache path was still used even for DER certificates supplied directly in memory. Engineers patched the SSL library to bypass that cache wholesale. Each instance then handled three times the benchmark capacity, while SNI latencies fell from 100–120 milliseconds to 20–25 milliseconds for the reported app subset; the patch was later shipped in Erlang/OTP-19.1.


### [Handling Very Large Tables in Postgres Using Partitioning](https://yomu.fyi/post/handling-very-large-tables-in-postgres-using-partitioning.md)
- Company: [Heroku](https://yomu.fyi/company/heroku.md)
- Author: Rimas Silkaitis
- Published: Sep 13, 2016
- Type: Tutorial

Very large Postgres tables containing application events or log-like data can degrade query performance, slow index updates, and make vacuum disproportionately long. The article explains table partitioning through inheritance, using a master table, child partitions, CHECK constraints, and a trigger that routes inserts according to created\_at; for an events workload with 10 million daily inserts and short-lived data, it uses daily partitions. It then introduces pg\_partman, whose create\_parent command configures time-based partitioning and whose run\_maintenance function creates new partitions and removes old ones according to retention settings. Partitioning can improve performance and simplify deletion of expired data, but it should follow indexing and usage analysis, especially when queries cover a small time range and older data has little value.


### [Apache Kafka 0.10 Evaluating Performance in Distributed Systems](https://yomu.fyi/post/apache-kafka-0-10-evaluating-performance-in-distributed-systems.md)
- Company: [Heroku](https://yomu.fyi/company/heroku.md)
- Author: Tom Crayford
- Published: May 27, 2016
- Type: Benchmark

Testing Apache Kafka 0.10 revealed an apparent 33% throughput decline versus Kafka 0.9, prompting an investigation into whether the regression affected different plans, connection types, message sizes, and workload scales. Heroku’s benchmark system used multiple producer and consumer dynos, while the team applied Brendan Gregg’s USE method to examine resource utilization, saturation, and errors. The diagnosis was network-card saturation: Kafka 0.10 adds an 8-byte timestamp to every message, which at 1.5 million messages per second and replication factor 3 produced 288 Mbps of additional cluster traffic, causing packet drops and retransmits. Reproducing the effect by adding 8 bytes to Kafka 0.9 confirmed the explanation, and the post says most production workloads are unlikely to be affected, though clusters near network limits may be.


### [Heroku Metrics](https://yomu.fyi/post/heroku-metrics.md)
- Company: [Heroku](https://yomu.fyi/company/heroku.md)
- Author: Andrew Gwozdziewycz
- Published: May 26, 2016
- Type: Explainer

Heroku’s original Dashboard Metrics system stored 10-minute rollups in a 21-shard InfluxDB cluster, but new requirements for one-minute data, richer events, extensibility, and failure tolerance exposed infrastructure limits. To replace it, the team built a Kafka-based pipeline on Private Spaces: an ingress app parses Logplex frames into Protocol Buffers messages, Go consumers aggregate measurements into one-minute summaries, and a sink writes rolled-up data to seven sharded, partitioned Heroku Postgres databases. The custom Yahtzee framework uses accumulator maps for counts and streaming min, max, and sum calculations with deterministic partition ownership; late data and aggregation-process restarts were implementation hurdles. The design reduces reliance on expensive InfluxDB continuous queries and makes adding another datastore straightforward, although Postgres performance remains merely acceptable and measurements can still be lost before Kafka because the logging pipeline is lossy by design.


[Newer posts](https://yomu.fyi/company/heroku/page/5.md) · [Older posts](https://yomu.fyi/company/heroku/page/7.md)
