---
title: "Puma 4: Hammering Out H13s—A Debugging Story"
description: "Heroku investigated mysterious H13s—“Connection closed” without response—affecting Ruby applications during dyno deployments or scaling, especially at high traffic levels. The failure involved a race between SIGTERM shutting down Puma and the router’s separate system continuing to deliver a few requests, but comparison with other webservers indicated Puma needed to handle the condition. A reproduction used Rack applications that sent SIGTERM to Puma and themselves, plus parallel curl requests, reproducing curl exit code 52 and Heroku H13s. Debugging showed Puma relied on process termination to close accepted sockets; Puma 4 instead closes binder listeners before shutdown, allowing the router to retry connections while preserving responses for in-flight requests."
---

# Puma 4: Hammering Out H13s—A Debugging Story

[Heroku](https://yomu.fyi/company/heroku) · Richard Schneeman · Jul 12, 2019

**Type:** Incident / postmortem

## Summary

Heroku investigated mysterious H13s—“Connection closed” without response—affecting Ruby applications during dyno deployments or scaling, especially at high traffic levels. The failure involved a race between SIGTERM shutting down Puma and the router’s separate system continuing to deliver a few requests, but comparison with other webservers indicated Puma needed to handle the condition. A reproduction used Rack applications that sent SIGTERM to Puma and themselves, plus parallel curl requests, reproducing curl exit code 52 and Heroku H13s. Debugging showed Puma relied on process termination to close accepted sockets; Puma 4 instead closes binder listeners before shutdown, allowing the router to retry connections while preserving responses for in-flight requests.

## Context

Customers reported H13 errors when Ruby applications deployed, scaled, or shut down. The issue appeared mainly at relatively high scale and was traced to requests arriving during the coordination gap between dyno shutdown and the router stopping traffic.

## Approach / What changed

The investigation reproduced the race with Rack applications that sent SIGTERM to Puma and themselves while parallel curl requests continued. Debugging Puma internals led to a fix that closes binder listeners before shutdown, and the change was tested with a reproduction, customer deployments, and Puma tests.

## Takeaways

- A dyno shutdown coordinates SIGTERM to its processes with a separate router operation, so a few requests can still reach Puma after shutdown begins.
- Puma’s reproduction used parallel requests and recorded curl exit code 52, “Empty reply from server,” while deployment on Heroku produced H13 errors.
- Puma 4 closes binder listeners before shutdown; this rejects incoming connections for router retry while allowing existing requests to finish.

**Tags:** [Debugging](https://yomu.fyi/topic/debugging), [Distributed Systems](https://yomu.fyi/topic/distributed-systems), [Ruby](https://yomu.fyi/topic/ruby)

- Source: [Heroku](https://www.heroku.com/blog/puma-4-hammering-out-h13s-a-debugging-story)
- Source URL: https://www.heroku.com/blog/puma-4-hammering-out-h13s-a-debugging-story
- Ingested by Yomu: 2026-09-09T14:27:38.821Z

[Read original post](https://www.heroku.com/blog/puma-4-hammering-out-h13s-a-debugging-story)
