HOWTO · PostgreSQL

How to List All Tables in PostgreSQL

List every table in a PostgreSQL database by querying the INFORMATION_SCHEMA views or by using psql table-listing meta-commands, and filter the results by schema.

On this page

The quickest way to see every table in a PostgreSQL database is to query the information_schema.tables view, or to run the \dt meta-command inside psql. Both approaches are covered below.

INFORMATION_SCHEMA is a schema that exists automatically in every PostgreSQL database. It exposes metadata about database objects through a set of views defined by the SQL standard, so information_schema.tables is itself a view that describes tables and views rather than a table storing user data. Querying it tells you which objects exist and which schema each one belongs to; it does not give you privileges such as DROP on those objects. Permissions still come from GRANT, and the views only report objects the current role is allowed to see.

The statements in this article are ordinary SQL and psql commands meant to be run in your own database session, so they are shown as syntax to copy rather than with captured output.

List tables with information_schema.tables

To list every table-like object the database knows about, run:

SELECT * FROM information_schema.tables;

Each returned row describes one object. The useful columns are table_catalog (the database name), table_schema (the schema the object lives in), table_name, and table_type (BASE TABLE for ordinary tables, VIEW for views). When you only need names, project fewer columns:

SELECT table_schema, table_name FROM information_schema.tables;

An abbreviated example of what the result looks like:

table_catalog table_schema table_name table_type
postgres public customers BASE TABLE
postgres information_schema tables VIEW

Notice that a single query returns rows from several schemas. The table_schema column tells you which schema contains each object, which is why public, pg_catalog, and information_schema rows appear side by side. Because INFORMATION_SCHEMA follows the SQL standard (ISO/IEC 9075), the same query works on other database systems, while pg_catalog holds PostgreSQL’s own system catalog tables.

Filter tables by schema

Add a WHERE clause on table_schema to narrow the result to a single schema. Application tables usually live in public:

SELECT table_name FROM information_schema.tables WHERE table_schema = 'public';

Substitute whichever schema you need. For example, WHERE table_schema = 'information_schema' lists the standard views themselves, and 'pg_catalog' lists the system catalog. Because information_schema.tables also reports views, add a table_type predicate when you want real tables only:

SELECT table_schema, table_name FROM information_schema.tables WHERE table_schema = 'public' AND table_type = 'BASE TABLE';

List tables with psql

Inside the psql interactive terminal, the \dt meta-command prints a compact table listing. A bare \dt shows tables in the schemas on your search_path, which is normally just public. To choose one schema explicitly, qualify the pattern:

\dt public.*

To see tables across every schema at once, use a wildcard for both parts:

\dt *.*

The result is a List of relations table with Schema, Name, Type, and Owner columns:

Schema Name Type Owner
public customers table postgres

Keep two limits in mind. \dt lists tables only, so it does not show the INFORMATION_SCHEMA contents, which are views: use \dv information_schema.* for views or \d information_schema.* to list every kind of relation in that schema. And these meta-commands work only inside psql; they are not SQL statements you can send through another client or driver.

A schema is a namespace inside a database, so different schemas can contain tables with the same name. That is why an unfiltered listing mixes rows from several schemas, and why the table_schema or Schema column matters when you read the result.

Commands that look similar do different jobs, so it is worth keeping them straight:

  • \dt lists tables, and \dv lists views.
  • \dn lists the schemas (namespaces) themselves. \dn information_schema shows that one schema’s entry, including its owner — it does not list tables.
  • \z, equivalent to \dp, prints the access privileges granted on each object. It is useful for auditing permissions, not for listing tables. Write it with a backslash; typing /z with a forward slash produces an error.

A practical workflow follows from these distinctions: use information_schema.tables or \dt to enumerate tables, add a table_schema filter or a schema pattern to narrow the scope, and reach for \dn or \z when you need schema or privilege details rather than a table list.