Heroku Dyno
Required Heroku Dyno Attributes
The following cost calculation tags are required for traces originating from Heroku dynos.
Always Required Fields
These fields are always required for Heroku dyno cost calculation:
| Attribute Name | Example Value | Allowed Values |
|---|---|---|
cloud.platform | heroku_dyno | heroku_dyno |
service.name | my-heroku-app | Your Heroku app name |
host.id | web.1 | Heroku dyno instance name (from DYNO env var) |
host.type | Standard-1X | See supported dyno types |
cloud.region | us | us, eu |
Heroku dyno names like web.1 and worker.1 are not globally unique — every Heroku app has its own web.1. If you run multiple Heroku apps, service.name is what distinguishes them. Without it, Beakpoint cannot tell whether two web.1 spans came from the same app or different apps, which leads to incorrect cost splitting.
Set service.name to your Heroku app name (e.g., my-api, my-worker). This is standard OpenTelemetry practice and most SDKs set it by default.
Optional Fields
These fields provide additional context but are not required for cost calculation to work:
| Attribute Name | Example Value | Allowed Values | Purpose |
|---|---|---|---|
cloud.provider | heroku | heroku | Identifies the cloud provider; helps organize costs by platform |
Supported Dyno Types
| Dyno Type | Memory | CPU | Monthly Cost |
|---|---|---|---|
| Basic | 512 MB | Shared | $7 |
| Standard-1X | 512 MB | Shared | $25 |
| Standard-2X | 1 GB | Shared | $50 |
| Performance-M | 2.5 GB | Dedicated | $250 |
| Performance-L | 14 GB | Dedicated | $500 |
| Performance-L-RAM | 30 GB | Dedicated | $500 |
| Performance-XL | 62 GB | Dedicated | $750 |
| Performance-2XL | 126 GB | Dedicated | $1,500 |
| Private-S | 1 GB | Dedicated | $125 |
| Private-M | 2.5 GB | Dedicated | $250 |
| Private-L | 14 GB | Dedicated | $500 |
| Private-L-RAM | 30 GB | Dedicated | $500 |
| Private-XL | 62 GB | Dedicated | $750 |
| Private-2XL | 126 GB | Dedicated | $1,500 |
| Shield-S | 1 GB | Dedicated | $150 |
| Shield-M | 2.5 GB | Dedicated | $300 |
| Shield-L | 14 GB | Dedicated | $600 |
| Shield-L-RAM | 30 GB | Dedicated | $600 |
| Shield-XL | 62 GB | Dedicated | $900 |
| Shield-2XL | 126 GB | Dedicated | $1,800 |
Eco dynos are not supported. Eco dynos use a shared-pool pricing model ($5/month for 1000 hours across all Eco dynos) that cannot be accurately attributed to individual spans. Consider upgrading to a Standard dyno if you need span-level cost tracking.
Fir generation dynos are not yet supported. This includes dyno types like dyno-2c-8gb. Currently, only Cedar-generation dynos (listed above) are supported for cost calculation. Check your dyno type with heroku dyno:type --app <app-name>.
Cost Calculation
Heroku dynos are priced at a fixed monthly rate. Beakpoint converts this to an hourly rate using 730 hours/month and calculates cost per span based on span duration:
cost = (span_duration_seconds / 3600) × (monthly_price / 730)
When multiple spans execute concurrently on the same dyno instance (identified by service.name + host.id), costs are proportionally shared using a time-sharing algorithm. Spans running on different dyno instances are priced independently.
Example Configuration
Set these as OpenTelemetry resource attributes in your application. The DYNO and other values are automatically set by Heroku at runtime:
export OTEL_RESOURCE_ATTRIBUTES="service.name=my-heroku-app,cloud.platform=heroku_dyno,host.id=${DYNO},host.type=Standard-1X,cloud.region=us,cloud.provider=heroku"
For Python (using OpenTelemetry SDK):
from opentelemetry.sdk.resources import Resource
resource = Resource.create({
"service.name": "my-heroku-app",
"cloud.platform": "heroku_dyno",
"host.id": os.environ.get("DYNO"),
"host.type": "Standard-1X",
"cloud.region": "us",
"cloud.provider": "heroku",
})
Heroku automatically sets the DYNO environment variable on every dyno (e.g., web.1, worker.2). Use this as host.id to uniquely identify each dyno instance and ensure correct cost attribution. This guarantees that concurrent spans on the same dyno share costs proportionally, while spans on different dynos are priced independently.
Attribute Mapping
| Beakpoint Insights Attribute | Source | Notes |
|---|---|---|
service.name | Application configuration | Your Heroku app name — distinguishes apps that share dyno names |
cloud.platform | Static configuration | Always heroku_dyno |
host.id | DYNO environment variable | Set automatically by Heroku (e.g., web.1, worker.2) |
host.type | Heroku dyno configuration | Must match a supported dyno type exactly (case-sensitive) |
cloud.region | Heroku app settings | us for United States, eu for Europe |
cloud.provider | Static configuration | Optional, always heroku |
Troubleshooting Common Issues
Missing or Incorrect Attributes
Missing service.name: Without this attribute, Beakpoint cannot distinguish between the same dyno type running in different apps. This causes cost data to be merged incorrectly. Always verify that your telemetry instrumentation sets service.name to your Heroku app name.
Mismatched host.type: The dyno type must match exactly (case-sensitive). Use Standard-1X, not standard-1x or Standard 1X. If the dyno type is not recognized, it won't be priced.
Wrong cloud.region: Ensure cloud.region matches where your Heroku app actually runs. Check your app's region with heroku info --app <app-name> and set cloud.region to us or eu accordingly.
Cost Calculation Issues
Zero or unexpected costs: Verify that:
- All required attributes are present and correctly formatted
- The span duration is non-zero
- The dyno type exists in the supported list
- The application is receiving and exporting spans correctly
Eco dynos showing no cost: Eco dynos use a shared-pool pricing model and are intentionally not supported. Upgrade to a Standard-tier dyno for accurate span-based cost tracking.