Dynos

What is a Dyno?

A dyno is roughly equivalent to an individual Mongrel, Thin, or FastCGI backend in traditional Ruby deployment environments. In fact, Heroku uses Thin at the core of its dyno architecture, so you can think of dynos as having the same constraints as individual Thin processes.

What makes a dyno unique is not the individual Thin process but the features enabled by the rest of the Heroku platform.

  • Elasticity: The number of dynos allocated for your app can be increased or decreased at any time – without server provisioning of any kind.

  • Intelligent routing: The routing mesh tracks the availability of each dyno and balances load accordingly. Requests are routed to a dyno only once it becomes available. If a dyno is tied up due to a long-running request, the request is routed to another dyno instead of piling up on the unavailable dyno’s backlog.

  • Process management: Each dyno process is monitored for responsiveness. Misbehaving dynos are taken down and new dynos are launched in their place.

  • Distribution and redundancy: Dynos are distributed across a large cluster of machines called the “dyno grid”. An app configured with two dynos is running two processes, as you'd expect, but each process is running on a separate machine. If a machine goes down, your site stays up – even with only two dynos.

See How it Works, an illustrated tour of Heroku’s infrastructure, for more on how dyno’s fit into Heroku’s architecture. The Dyno Grid and Inside a Dyno sections are especially relevant.

Dyno Runtime Environment

Dyno processes run in a partitioned Unix environment within a standard Ruby VM (Ruby version details). There are no Heroku specific APIs. Dynos are free to use any frameworks, gems, libraries, or network services (outbound network connections are allowed) available. In most cases, standard Ruby web apps just work.

Filesystem

The ./tmp and ./log directories are writeable but their contents are not shared between multiple dyno processes. The rest of the filesystem is read-only and contains the app’s source files.

It’s not possible to use the filesystem to store data between requests, since dynos can’t see each others writeable data. The Application Constraints topic has more on the read-only filesystem, including techniques for accomplishing tasks that traditionally required shared disk access.

Environment variables

Heroku uses standard Unix environment variables to provide dyno processes with information about the system and configured Heroku network services. For instance, the DATABASE_URL environment variable specifies the network location of the app’s PostgreSQL database; similarly, MEMCACHED_SERVERS contains the IP list of all servers in the app’s memcached cluster (for app’s that have enabled the memcached add-on). You can also manage a custom environment variables with Config vars.

Dyno Concurrency and Scaling

The number of dynos allocated to an app directly affects the app’s maximum concurrency and request throughput. A single dyno can process a single request at a time and is bound to a single CPU core.

For a “typical” app, a single dyno should be able to process between 10 and 100 dynamic requests per second. The request throughput for a single dyno is dictated by the app’s overall performance. An unoptimized app might take an average of 100ms to process requests, while a well tuned app might take 10ms. It’s possible to achieve request times of 2ms or less with profiled/optimized code and judicious use of memcached.

Increasing the number of dynos increases an app’s maximum request throughput because more dynos are able to process requests is parallel. Adding dynos can also decrease response latency, since a dyno is more likely to be immediately available to process requests.

The number of dynos allocated to an app may be changed at any time by visiting the app’s Resources page in My Apps. The first dyno is always free; subsequent dynos cost $0.05 per hour. For example, an app with four dynos is charged $0.15 per hour for each hour that the four dynos are running. See the pricing page for an estimate monthly cost under various configurations.