Skip Navigation
Show nav
Heroku Dev Center Dev Center
  • Get Started
  • Documentation
  • Changelog
  • Search
Heroku Dev Center Dev Center
  • Get Started
    • Node.js
    • Ruby on Rails
    • Ruby
    • Python
    • Java
    • PHP
    • Go
    • Scala
    • Clojure
    • .NET
  • Documentation
  • Changelog
  • More
    Additional Resources
    • Home
    • Elements
    • Products
    • Pricing
    • Careers
    • Help
    • Status
    • Events
    • Podcasts
    • Compliance Center
    Heroku Blog

    Heroku Blog

    Find out what's new with Heroku on our blog.

    Visit Blog
  • Log in or Sign up
View categories

Categories

  • Heroku Architecture
    • Compute (Dynos)
      • Dyno Management
      • Dyno Concepts
      • Dyno Behavior
      • Dyno Reference
      • Dyno Troubleshooting
    • Stacks (operating system images)
    • Networking & DNS
    • Platform Policies
    • Platform Principles
    • Buildpacks
  • Developer Tools
    • AI Tools
    • Command Line
    • Heroku VS Code Extension
  • Deployment
    • Deploying with Git
    • Deploying with Docker
    • Deployment Integrations
  • Continuous Delivery & Integration (Heroku Flow)
    • Continuous Integration
  • Language Support
    • Node.js
      • Troubleshooting Node.js Apps
      • Working with Node.js
      • Node.js Behavior in Heroku
    • Ruby
      • Rails Support
        • Working with Rails
      • Working with Bundler
      • Working with Ruby
      • Ruby Behavior in Heroku
      • Troubleshooting Ruby Apps
    • Python
      • Working with Python
      • Background Jobs in Python
      • Python Behavior in Heroku
      • Working with Django
    • Java
      • Java Behavior in Heroku
      • Working with Java
      • Working with Maven
      • Working with Spring Boot
      • Troubleshooting Java Apps
    • PHP
      • PHP Behavior in Heroku
      • Working with PHP
    • Go
      • Go Dependency Management
    • Scala
    • Clojure
    • .NET
      • Working with .NET
  • Databases & Data Management
    • Heroku Postgres
      • Postgres Basics
      • Postgres Getting Started
      • Postgres Performance
      • Postgres Data Transfer & Preservation
      • Postgres Availability
      • Postgres Special Topics
      • Heroku Postgres Advanced (Limited GA)
      • Migrating to Heroku Postgres
    • Heroku Key-Value Store
    • Apache Kafka on Heroku
    • Other Data Stores
  • AI
    • Inference Essentials
    • Inference API
    • Inference Quick Start Guides
    • AI Models
    • Tool Use
    • AI Integrations
    • Vector Database
  • Monitoring & Metrics
    • Logging
  • App Performance
  • Add-ons
    • All Add-ons
  • Collaboration
  • Security
    • App Security
    • Identities & Authentication
      • Single Sign-on (SSO)
    • Private Spaces
      • Infrastructure Networking
    • Compliance
  • Heroku Enterprise
    • Enterprise Accounts
    • Enterprise Teams
  • Patterns & Best Practices
  • Extending Heroku
    • Platform API
    • App Webhooks
    • Heroku Labs
    • Building Add-ons
      • Add-on Development Tasks
      • Add-on APIs
      • Add-on Guidelines & Requirements
    • Building CLI Plugins
    • Developing Buildpacks
    • Dev Center
  • Accounts & Billing
  • Troubleshooting & Support
  • Integrating with Salesforce
    • Heroku AppLink
      • Heroku AppLink Reference
      • Getting Started with Heroku AppLink
      • Working with Heroku AppLink
    • Heroku Connect (Salesforce sync)
      • Heroku Connect Administration
      • Heroku Connect Reference
      • Heroku Connect Troubleshooting
    • Other Salesforce Integrations
  • Troubleshooting & Support
  • Understanding Heroku Postgres Log Statements and Common Errors

Understanding Heroku Postgres Log Statements and Common Errors

English — 日本語に切り替える

Table of Contents [expand]

  • LOG: duration: 3.565 s …
  • LOG: checkpoint starting…
  • LOG: could not receive data from client: Connection reset by peer
  • LOG: unexpected EOF on client connection
  • LOG: [Errno 104] Connection reset by peer
  • FATAL: too many connections for role
  • FATAL: could not receive data …
  • FATAL: role “role-name” is not permitted to log in
  • FATAL: terminating connection due to administrator command
  • FATAL: remaining connection slots are reserved for non-replication superuser connections
  • FATAL: no pg_hba.conf entry for host “…”, user “u…”, database “d…”, SSL off
  • LOG: temporary file: path “file path”, size “file size”
  • ERROR: permission denied for relation
  • ERROR: operator does not exist
  • ERROR: relation “table-name” does not exist
  • ERROR: column “column-name” cannot…
  • ERROR: SSL SYSCALL error: EOF detected
  • ERROR: prepared statement “a30” already exists
  • ERROR: could not write block … of temporary file: No space left of device
  • Out of Memory Errors

Last updated July 06, 2026

Heroku Postgres publishes database logs in your app’s log stream. You can isolate Heroku Postgres events with the heroku logs command by filtering for the postgres process.

Logs are available on Standard-tier and higher databases. Essential-tier databases don’t include logs.

$ heroku logs -p postgres -t -a example-app
2026-06-29T13:34:12.000000+00:00 app[postgres]: [15521-1]  [CHARCOAL] LOG:  checkpoint starting: time
2026-06-29T13:34:12.000000+00:00 app[postgres]: [15522-1]  [CHARCOAL] LOG:  checkpoint complete: wrote 6 buffers (0.0%); 0 transaction log file(s) added, 0 rem...

Besides seeing system-level Postgres activity, these logs are also useful for understanding your app’s use of Postgres and for diagnosing common errors. This article lists common log statements, their purpose, and actions to take.

Find the Heroku Postgres Metrics Logs for your database by filtering for the heroku-postgres process. These metrics logs are independent of standard logs emitted by Postgres, which uses the postgres process.

LOG: duration: 3.565 s …

[12-1] u8akd9ajka [BRONZE] LOG:  duration: 3.847 s  statement: SELECT  "articles".* FROM "articles"...

By default, Heroku Postgres logs any query execution that takes more than 2 seconds to run, defined by the log-min-duration-statement setting.

Heroku logs queries taking longer than log-min-duration-statement so you can identify and optimize them.

See Solutions to Expensive Queries for recommendations on analyzing and fixing expensive queries.

LOG: checkpoint starting…

2026-06-29T13:35:16.000000+00:00 app[postgres]: [15521-1]  [CHARCOAL] LOG:  checkpoint starting: time
2026-06-29T13:35:16.000000+00:00 app[postgres]: [15522-1]  [CHARCOAL] LOG:  checkpoint complete: wrote 6 buffers (0.0%); 0 transaction log file(s) added, 0 rem...

LOG: checkpoint starting and the corresponding LOG: checkpoint complete statements are part of Postgres’ checkpointing activity. A checkpoint flushes dirty pages from Postgres’ shared memory buffers to disk to allow recycling older WAL segments. Postgres triggers checkpoints automatically based on time or WAL volume.

These statements are part of normal database operation and no action is required.

LOG: could not receive data from client: Connection reset by peer

See unexpected EOF on client connection for more information.

LOG: unexpected EOF on client connection

app[postgres]: LOG:  could not receive data from client: Connection reset by peer
app[postgres]: LOG:  unexpected EOF on client connection

Although Postgres emits this log, the cause for the error is unrelated to the database. Your app happened to crash while connected to Postgres, and didn’t clean up its connection to the database. Postgres noticed that the client, your app, disappeared without ending the connection properly, and logged a message saying so.

If you aren’t seeing your app’s backtrace, make sure you’re logging to stdout instead of a file and that you have stdout synced.

LOG: [Errno 104] Connection reset by peer

This error indicates a transient network interruption between your app or Postgres client and Postgres. If the error appears frequently or in sustained bursts, investigate the connectivity between your dynos and the database, checking for connection leaks in your app, or reviewing recent infrastructure changes.

FATAL: too many connections for role

FATAL:  too many connections for role "[role name]"

This error occurs on Essential-tier databases plans, which have a max connection limit of 20 per user. To resolve this error, close some connections to your database by stopping background workers, reducing the number of dynos, or restarting your app in case it has created connection leaks over time. See Concurrency and Database Connections for Rails-specific guidance.

FATAL: could not receive data …

FATAL: could not receive data from WAL stream: SSL error: sslv3 alert unexpected message

A transient network error or a TLS handshake failure interrupts replication from a primary database to a follower. This error is a transient problem and Postgres automatically re-establishes the replication stream.

Find replication lag for a follower with heroku pg:info. The “Behind By” field shows the replication lag in commits.

$ heroku pg:info --app example-app
=== HEROKU_POSTGRESQL_WHITE
...
Following    DATABASE_URL
Behind By    125 commits

You can also monitor follower lag via the database metrics of the Heroku Postgres Metrics Logs.

FATAL: role “role-name” is not permitted to log in

FATAL: role "u8akd9ajka" is not permitted to log in (PG::Error)

This error occurs when you’re trying to connect to a database with credentials that no longer exist, which can happen for several reasons, including:

  • The database credentials rotated but you’re still using the old ones to connect to it. In the specific case of Essential-tier databases, credentials rotate as part of regular maintenance tasks.
  • You deprovisioned an Essential-tier database but you’re still trying to connect to it.

FATAL: terminating connection due to administrator command

FATAL: terminating connection due to administrator command

This message indicates Postgres terminated a backend connection. This error can happen when you run the heroku pg:killall or heroku pg:kill --force CLI commands, or when you run SELECT pg_terminate_backend(pid); to terminate a database connection.

FATAL: remaining connection slots are reserved for non-replication superuser connections

FATAL: remaining connection slots are reserved for non-replication superuser connections

Each database plan has a maximum allowed number of connections available, which varies by plan. This message indicates your database has reached its connection limit and has reserved the remaining connections for superuser access (restricted to Heroku Postgres automation). See Heroku Postgres Production Tier Technical Characterization for details on connection limits for a given plan.

If the high number of connections to your database is unexpected:

  • Consider restarting your dynos to clear potentially leaked connections that accumulated over time, or terminate them with heroku pg:kill.
  • Inspect your database locks to identify connections blocked due to lock contention and investigate or terminate the connections holding locks.

If your database hits its connection limit often, use a connection pooler such as PgBouncer to reduce the number of connections to your database, or upgrade to a higher-tier plan if your workload requires more concurrent connections.

FATAL: no pg_hba.conf entry for host “…”, user “u…”, database “d…”, SSL off

This “SSL off” error indicates that you’re attempting to establish a database connection without SSL. Heroku Postgres requires SSL connections. Check the documentation for your Postgres driver on how to establish encrypted connections.

LOG: temporary file: path “file path”, size “file size”

temporary file: path "base/pgsql_tmp/pgsql_tmp23058.672", size 1073741824

Heroku Postgres logs temporary files larger than 10,240 kilobytes. Postgres creates temporary files for large sort and hash operations that exceed work_mem.

This log entry is informational. Frequent temporary files indicate queries exceeding work_mem and can impact performance. Consider optimizing the query or increasing the work_mem setting.

ERROR: permission denied for relation

PGError: ERROR:  permission denied for relation table-name

On Heroku Postgres Essential-tier databases, Heroku enforces row limits by revoking write privileges when it exceeds the limit. If you hit this error on an Essential database, check where you’re over your row limit. Upgrade to a Standard-tier or higher database to remove this constraint or reduce the number of total rows on your database.

On other Heroku Postgres tiers, check the role’s permissions on the affected table.

ERROR: operator does not exist

PGError: ERROR:  operator does not exist: character varying = integer

Postgres raises an error when an operator doesn’t support the operand types. For example, comparing a character varying column to an integer requires casting one side to a compatible type.

Make sure the operator is adequate for the data type or use an explicit cast to resolve the mismatch.

ERROR: relation “table-name” does not exist

PGError: ERROR: relation "documents" does not exist

This error is the standard message shown by Postgres when a relation, such as a table or a view, doesn’t exist. This error means the query references an object that doesn’t exist in the current database or search path.

Check that your migrations ran successfully and that the relation name and search path are correct.

ERROR: column “column-name” cannot…

PGError: ERROR: column "verified_at" cannot be cast to type "date"

This error occurs when you change the type of a column and Postgres can’t automatically convert the existing row values to the new type.

Inspect the data in the affected column to identify values that Postgres can’t convert. Then either clean the data or provide an explicit USING expression in your ALTER TABLE statement to indicate Postgres how to perform the conversion.

ERROR: SSL SYSCALL error: EOF detected

Errors with similar root causes include:

  • no connection to the server
  • SSL error: decryption failed or bad record mac
  • could not receive data from server: Connection timed out

These errors indicate the connection between your app or client and Postgres was interrupted or corrupted. The two most common causes are:

  • Shared Postgres connections across processes or threads: if forked processes or threads share a Postgres connection without re-establishing the connection, concurrent use corrupts the connection state. This behavior happens typically with Resque workers or Unicorn. Re-establish the connection after forking or initializing a thread to resolve this issue.
  • Abrupt client or app disconnections: if your app crashes or a transient network interruption drops the connection, the next query attempt fails because the connection no longer exists. Heroku restarts the crashed dyno, which re-establishes the connection on the next request.

ERROR: prepared statement “a30” already exists

Postgres scopes prepared statements to a single connection. When a connection is shared across processes or threads, one process can attempt to create a prepared statement with a name that another already registered on the same connection.

The root cause is typically a Postgres connection shared improperly between forked processes or threads. Re-establishing the connection after forking resolves this problem.

ERROR: could not write block … of temporary file: No space left of device

This error indicates that Postgres ran out of disk space while writing a temporary file. Postgres cleans up temporary files automatically when the query ends, and temporary tables at the end of the database session.

If this error is recurrent, review queries that generate large temporary files and consider optimizing them to reduce their disk usage.

Out of Memory Errors

Out of memory (OOM) errors occur when the server running your database can’t allocate enough memory for connections, query execution, or its buffer. Several factors can contribute to memory exhaustion, such as expensive queries or a high number of concurrent connections. Review your database usage and upgrade your plan if your database workload requires more memory resources.

See Understanding Heroku Postgres Out of Memory Errors for more details.

Extremely Complex Querying

Sort and hash operations each allocate up towork_mem. A single complex query can allocate multiples of work_mem if it contains several sorts of hash nodes. Sort operations arise from ORDER BY, DISTINCT, and merge joins. Hash operations arise from hash joins, hash aggregations, and IN subqueries. A single complex query can trigger several of these operations simultaneously. This memory pressure multiplies with concurrent connections that run memory-intensive operations.

Ruby, ActiveRecord, and Prepared Statements

Prepared statements allow Postgres to parse a query once and reuse it efficiently. However, many ORMs don’t construct prepared statements effectively and create a separate prepared statement for each distinct parameter in a query. For example, let’s say our app allows its users to select products from a product table by ID. If customer A selects two products, ActiveRecord defines a query and creates a prepared statement:

SELECT * FROM products WHERE id IN ($1, $2);

If customer B, in the same app, for the same query, selects four products instead of two, ActiveRecord creates a new prepared statement:

SELECT * FROM products WHERE id IN ($1, $2, $3, $4);

Because these are distinct queries, the prepared statement cache grows depending on the variability in the IN clause, consuming significant memory over time. Consider disabling prepared statements or adjusting the number of prepared statements that your app caches.

Disabling Prepared Statements in Rails

To disable prepared statements, update your config/database.yml file to include the prepared_statements parameter:

production:
  adapter: postgresql
  prepared_statements: false

To adjust the size of the prepared statement cache, update your config/database.yml file to include the statement_limit parameter (defaults to 1000).

production:
  adapter: postgresql
  statement_limit: 200

Too Many Connections

Each Postgres connection allocates memory for its backend process regardless of whether it’s actively executing a query. Many idle connections can exhaust the available RAM before hitting the connection limit. Use a connection pooler such as PgBouncer to reuse and reduce the number of Postgres connections to the database.

Database Plan is Too Small

If query and connection optimizations don’t resolve the OOM errors, it’s possible your database plan doesn’t have enough memory for your workload. Consider upgrading to a higher plan.

Feedback

Log in to submit feedback.

Information & Support

  • Getting Started
  • Documentation
  • Changelog
  • Compliance Center
  • Training & Education
  • Blog
  • Support Channels
  • Status

Language Reference

  • Node.js
  • Ruby
  • Java
  • PHP
  • Python
  • Go
  • Scala
  • Clojure
  • .NET

Other Resources

  • Careers
  • Elements
  • Products
  • Pricing
  • RSS
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku Blog
    • Heroku News Blog
    • Heroku Engineering Blog
  • Twitter
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku
    • Heroku Status
  • Github
  • LinkedIn
  • © 2026 Salesforce, Inc. All rights reserved. Various trademarks held by their respective owners. Salesforce Tower, 415 Mission Street, 3rd Floor, San Francisco, CA 94105, United States
  • heroku.com
  • Legal
  • Terms of Service
  • Privacy Information
  • Responsible Disclosure
  • Trust
  • Contact
  • Cookie Preferences
  • Your Privacy Choices