pgconfigurator
pgconfigurator

Foreign Scan

Appears in EXPLAIN asForeign Scan

Reads rows from a foreign table via a foreign data wrapper.

What it is

A Foreign Scan retrieves rows from a foreign table through a foreign data wrapper (e.g. postgres_fdw). Capable wrappers push filters, joins, and aggregates down to the remote server.

When the planner picks it

Whenever a foreign table is queried.

Is it good or bad?

Depends almost entirely on push-down: if the WHERE/JOIN/aggregation runs remotely, it's efficient; if rows are dragged across the network and filtered locally, it's slow. Check the 'Remote SQL' in EXPLAIN (VERBOSE).

In depth

Push-down or perish

A Foreign Scan reads rows from a foreign table through a foreign data wrapper (FDW) — postgres_fdw for another PostgreSQL server, plus many third-party wrappers for other systems. Whether it's fast depends almost entirely on what runs on the remote side:

  • Push-down works: the remote server applies the filter, the join, the aggregate, and ships back only the result. Fast — often as fast as querying the remote directly.
  • Push-down fails: rows are dragged across the network and filtered locally. Slow, sometimes catastrophically.

Reading EXPLAIN

Use EXPLAIN (VERBOSE) and look for the Remote SQL line:

Foreign Scan on orders
  Output: id, customer_id, total
  Remote SQL: SELECT id, customer_id, total
              FROM public.orders
              WHERE customer_id = 42

If you see the WHERE clause embedded in Remote SQL, the filter pushed down. If not, the wrapper couldn't push it — and you'll often see a sibling Filter: line applying it locally instead.

Common reasons push-down fails

  • A predicate uses a function or operator the wrapper doesn't recognize as safe to send (volatile functions, locale-dependent comparisons, custom operators).
  • The wrapper doesn't implement aggregate or join push-down — only scans.
  • use_remote_estimate is off, so the planner uses statistics it can't trust and picks a local join plan over remote push-down.

For postgres_fdw, turning on use_remote_estimate = true on the foreign server / table gives the local planner real estimates from the remote, often enabling much better choices.

Parallel Foreign Scan

Some wrappers implement parallelism; you'll see Parallel Foreign Scan if they do. Most don't — check your wrapper's docs.

What the analyzer flags here

  • Bad row estimate — remote estimates can be unreliable

Paste a plan into the analyzer →

Settings that influence it

use_remote_estimate (FDW option)

How we tune these →

See also