PostgreSQL EXPLAIN guide

Rows Removed by Filter in PostgreSQL EXPLAIN

Rows Removed by Filter tells you how many rows were read by a plan node but rejected by its filter condition. A large value can reveal expensive work that produces little useful output — but the number needs context.

Example EXPLAIN output

Seq Scan on orders
  Filter: (customer_id = 42)
  Rows Removed by Filter: 1,399,944
  Actual Rows: 56
  Actual Total Time: 486.2 ms

What PostgreSQL is telling you

The executor visited rows at this node.

The filter rejected some or all of those rows.

With EXPLAIN ANALYZE, the value reflects actual execution rather than an estimate.

What it can mean

A high rejection ratio can indicate that a scan is doing substantial work for few returned rows.

If the node is slow and examines many rows, filter selectivity becomes worth investigating.

The metric alone does not prove that an index is missing.

What to check next

Compare rows returned with rows removed.

Check the node's actual execution time and loops.

Verify whether a useful index already exists.

Check whether the predicate is selective enough for an index to help.

Compare planner estimates with actual rows.

When this is not automatically a problem

  • • Small tables may be faster to scan sequentially.
  • • Analytics queries may intentionally read a large fraction of a table.
  • • A high count with negligible execution time may not be worth optimizing.

Check your actual plan

PlanCheck analyzes TEXT or JSON locally in your browser. Your SQL and plans are not uploaded.

Analyze EXPLAIN output