Check the health of the application
When an instance crashes or exits with an error, a red banner appears at the top of every tab of the application, for exampleThe app exited with code 137 (OOMKilled, SIGKILL). Click it (See app health) to open App health.


What the exit code means
The Get process exit codes API operation returns the same exit codes with their times.
The process runs out of memory
Symptom. Instances restart with exit code137, and the Memory usage chart on the Analytics tab reaches the limit line (turn on Show limit).
Cause. The process used more memory than its instance size allows, so it was killed. An instance that writes more than 20 GB to its ephemeral filesystem is also stopped.
Fix.
- On the Processes tab, click ⋯ on the process, then Update process, and pick a size with more memory, such as one in the Memory optimized group.
- Deploy the application.
- If memory keeps growing until the kill, look for a leak. Tell your runtime how much memory it has, for example
node --max-old-space-size=768 server.json a 1 GB size.
The process crashes without any logs
Symptom. Instances keep restarting, and the runtime logs stay empty. Cause. The start command fails before your code prints anything: the binary doesn’t exist, the path is wrong, or the command exits at once. Fix. Check the Custom start command on the process. When you chain commands, the last one must start the long-running server, for examplenpm run migrate && npm start. Leave the field empty to use the image’s default command. To investigate inside the container, debug the process in the web terminal.
Health checks restart the process
Symptom. The web process restarts every few minutes, or a deployment fails, although the logs show no error. Cause. A liveness or readiness probe fails: its path doesn’t exist or returns an error, it uses the wrong port, or the application answers more slowly than the probe’s Timeout (1 second by default), especially while it starts. Fix. Open the web process with Update process and check the probe’s Path and Port. Raise Initial delay above your application’s startup time and Timeout above its normal response time. Point probes at a lightweight endpoint that doesn’t call your database.The application cannot connect to a database
Symptom. The logs show connection errors such asECONNREFUSED, ETIMEDOUT, getaddrinfo ENOTFOUND, could not translate host name, password authentication failed or Access denied for user.
Cause.
- There’s no internal connection between the application and the database, so the private network between them is closed.
- The application and the database are in different locations. Internal connections only work within one location.
- The application uses a wrong host:
localhost, the database’s external hostname, or an old value. - The variable names don’t match what the application reads, or the credentials changed.
- The database is suspended or still being created.
- On the application’s Networking tab, check that the database is listed in Connected services. If not, add an internal connection and turn on Add environment variables to the application.
- Check that the application reads the variables the connection added (
DB_HOST,DB_PORT,DB_DATABASE,DB_USERNAME,DB_PASSWORDorDB_URL;REDIS_URLfor Redis and Valkey), or rename them to what your framework expects. - Compare the values with the database’s details; see Connect to a database.
- Deploy the application, then check the connection with
printenvand a client in the web terminal.
Connections to external services fail
Symptom. Calls to an external database, API or mail server time out or are refused. Cause. The service only accepts known IP addresses, or the connection uses a blocked port. Outbound SMTP on ports 25, 465 and 587 is blocked (and 2525 in Oracle Cloud locations). Fix. Allowlist the application’s egress IP addresses on the service. Send email through your provider’s HTTP API instead of SMTP on a blocked port.PHP errors
These settings apply to PHP applications built with Buildpacks (heroku/php). Put .user.ini and other configuration files in the application’s root folder, push, and deploy.
Allowed memory size exhausted
Symptom. The logs showPHP Fatal error: Allowed memory size of 134217728 bytes exhausted.
Cause. PHP’s memory_limit is 128 MB by default.
Fix. Raise it in a .user.ini file. Keep it below the process’s memory size, or the process is killed with exit code 137.
.user.ini
Scripts stop before they finish
Symptom. Long PHP requests stop withMaximum execution time of 30 seconds exceeded, or are cut off without an error.
Cause. PHP’s max_execution_time or PHP-FPM’s request_terminate_timeout ends the script.
Fix. Raise max_execution_time in .user.ini. Set request_terminate_timeout at least as high in an fpm_custom.conf file, and load it in the web process’s start command. Neither can usefully exceed Cloudflare’s 185-second limit; see 504 Gateway Timeout and Cloudflare error 524.
.user.ini
fpm_custom.conf
Start command
Debug a process in the web terminal
When a process crashes too fast to inspect, keep its container running and start your application by hand:1
Replace the start command
On the Processes tab, click ⋯ on the process, then Update process, and set Custom start command to
sleep infinity. Note the old command first.2
Deploy
Deploy the application. The process now starts and waits without running your code.
3
Investigate in the terminal
Open the web terminal on the process. Run
printenv to check the environment variables, then run your start command by hand, with debug output on, to see the error.4
Restore the start command
Put the original start command back and deploy again.