scenic-views/scenic · error · Scenic::Adapters::Postgres::ConcurrentRefreshesNotSupportedError

Concurrent materialized view refreshes require Postgres 9.4

Error message

Concurrent materialized view refreshes require Postgres 9.4 or newer

What it means

REFRESH MATERIALIZED VIEW CONCURRENTLY shipped in Postgres 9.4, one release after materialized views themselves. Scenic's Postgres adapter raises Scenic::Adapters::Postgres::ConcurrentRefreshesNotSupportedError inside refresh_materialized_view when concurrently: true is requested and connection.supports_concurrent_refreshes? is false, meaning the connected server reports postgresql_version below 90400. A 9.3 server therefore passes the materialized-view gate and fails only when a concurrent refresh is requested; the check runs before the REFRESH statement is sent.

Source

Thrown at lib/scenic/adapters/postgres.rb:290

      # @api private
      def connection
        Connection.new(connectable.connection)
      end

      private

      attr_reader :connectable
      delegate :execute, :quote_table_name, to: :connection

      def raise_unless_materialized_views_supported
        unless connection.supports_materialized_views?
          raise MaterializedViewsNotSupportedError
        end
      end

      def raise_unless_concurrent_refresh_supported
        unless connection.supports_concurrent_refreshes?
          raise ConcurrentRefreshesNotSupportedError
        end
      end

      def refresh_dependencies_for(name, concurrently: false)
        Scenic::Adapters::Postgres::RefreshDependencies.call(
          name,
          self,
          connection,
          concurrently: concurrently
        )
      end
    end
  end
end

View on GitHub (pinned to f2162dbddb)

Solutions

  1. Drop the flag: Scenic.database.refresh_materialized_view(:posts) issues a plain REFRESH MATERIALIZED VIEW, which 9.3 supports
  2. Gate concurrency on server capability: pass concurrently: ActiveRecord::Base.connection.postgresql_version >= 90400
  3. Upgrade the server to Postgres 9.4 or newer so non-blocking concurrent refreshes work

Example fix

# before (raises on Postgres 9.3)
Scenic.database.refresh_materialized_view(:posts, concurrently: true)

# after: capability-gated
concurrently = ActiveRecord::Base.connection.postgresql_version >= 90400
Scenic.database.refresh_materialized_view(:posts, concurrently: concurrently)
Defensive patterns

Strategy: validation

Validate before calling

concurrently = ActiveRecord::Base.connection.postgresql_version >= 90400
Scenic.database.refresh_materialized_view(:posts, concurrently: concurrently)

Type guard

def concurrent_refresh_supported?
  ActiveRecord::Base.connection.postgresql_version >= 90400
end

Try / catch

begin
  Scenic.database.refresh_materialized_view(:posts, concurrently: true)
rescue Scenic::Adapters::Postgres::ConcurrentRefreshesNotSupportedError
  Scenic.database.refresh_materialized_view(:posts) # retry without CONCURRENTLY
end

Prevention

When it happens

Trigger: Scenic.database.refresh_materialized_view(:posts, concurrently: true) on a Postgres 9.3 server; the same call with cascade: true, where RefreshDependencies may refresh dependent materialized views concurrently; scheduled refresh jobs or background code hard-coding concurrently: true and deployed against an environment still on 9.3.

Common situations: Legacy production on 9.3 while development machines run 9.4+; a background refresh job written against a newer server than staging provides; mixed database fleets where only some hosts have been upgraded.

Related errors


AI-assisted analysis of scenic-views/scenic@f2162dbddb (2026-08-23). Data as JSON: /api/errors/ea68401094c6ff80. Report an issue: GitHub.