- Learn
- PostgreSQL
- PostgreSQL List Tables
PostgreSQL List Tables
All the ways to list tables in a PostgreSQL database.
Quick answer
To list all tables in the current database using psql:
\dt
Or with SQL:
Both give you the tables in the public schema. The rest of this guide covers every variation, from psql shortcuts to detailed queries that include sizes, row counts, and column information.
The \dt command in psql
The \dt meta-command is the fastest way to list tables when you're working in the psql terminal.
Basic table listing
\dt
Output:
List of relations
Schema | Name | Type | Owner
--------+-----------+-------+--------
public | customers | table | admin
public | orders | table | admin
public | products | table | admin
(3 rows)
This shows tables in schemas on your search path (usually public).
Show table sizes with \dt+
Adding + includes size and description columns:
\dt+
Output:
List of relations
Schema | Name | Type | Owner | Persistence | Access method | Size | Description
--------+-----------+-------+-------+-------------+---------------+---------+------------
public | customers | table | admin | permanent | heap | 128 kB |
public | orders | table | admin | permanent | heap | 1024 kB |
public | products | table | admin | permanent | heap | 64 kB |
(3 rows)
Filter by schema
To list tables in a specific schema, use the pattern schema.*:
\dt myschema.*
To list tables across all schemas (including system schemas):
\dt *.*
Filter by table name pattern
You can use wildcards to match table names:
-- Tables starting with "user"
\dt user*
-- Tables containing "log"
\dt *log*
-- Tables in the "reporting" schema starting with "daily"
\dt reporting.daily*
Other useful \d variants
| Command | Description |
|---------|-------------|
| \dt | List tables |
| \dt+ | List tables with sizes |
| \dt schema.* | List tables in a specific schema |
| \dt *.* | List tables in all schemas |
| \dv | List views |
| \dm | List materialized views |
| \di | List indexes |
| \d tablename | Describe a specific table |
Querying information_schema.tables
The information_schema.tables view follows the SQL standard. It works the same way across PostgreSQL, MySQL, SQL Server, and other databases that support the standard.
List all user tables
Output:
table_schema | table_name | table_type
--------------+--------------+------------
public | customers | BASE TABLE
public | orders | BASE TABLE
public | products | BASE TABLE
reporting | daily_stats | BASE TABLE
(4 rows)
List tables in the public schema only
List tables and views together
Output:
table_name | table_type
---------------+------------
customers | BASE TABLE
orders | BASE TABLE
products | BASE TABLE
active_orders | VIEW
(4 rows)
The table_type column distinguishes between BASE TABLE and VIEW, which is useful when you need to tell them apart.
Querying pg_catalog.pg_tables
The pg_tables view is PostgreSQL-specific and provides ownership information that information_schema does not.
List all user tables
List tables owned by a specific user
Compare pg_tables vs information_schema.tables
| Feature | pg_tables | information_schema.tables | |---------|-----------|--------------------------| | SQL standard | No (PostgreSQL-specific) | Yes | | Shows table owner | Yes | No | | Shows hasindexes, hasrules, hastriggers | Yes | No | | Portable across databases | No | Yes | | Includes views | No | Yes (with table_type filter) |
Use information_schema.tables when you want portable SQL. Use pg_tables when you need PostgreSQL-specific details like ownership.
Filtering by schema
PostgreSQL organizes tables into schemas. Understanding which schemas exist helps you filter results.
List all schemas
Common schemas:
- public: The default schema where user tables go
- pg_catalog: PostgreSQL system tables
- information_schema: SQL standard metadata views
- pg_toast: Storage for large values (internal)
List tables in a specific schema
List tables across multiple schemas
Exclude system schemas
This is the most common pattern. You want user-created tables and nothing else:
Or equivalently, exclude any schema starting with pg_:
Listing tables with sizes
Table sizes help you understand disk usage, identify growth problems, and plan maintenance.
Size of each table
Output:
schemaname | tablename | total_size
------------+-----------+-------------
public | orders | 1200 MB
public | customers | 256 MB
public | products | 12 MB
(3 rows)
The pg_total_relation_size function includes the table data, indexes, and TOAST data.
Break down table vs index size
Top 10 largest tables in the database
Listing tables with row counts
Estimated row counts (fast)
PostgreSQL tracks estimated row counts in pg_class.reltuples. This is updated by ANALYZE and is fast because it reads catalog data, not the actual table:
Output:
schema | table_name | estimated_rows
--------+------------+----------------
public | orders | 12500000
public | customers | 1500000
public | products | 45000
(3 rows)
These estimates are good enough for most purposes. Run ANALYZE tablename if you need the estimates to be current.
Exact row counts (slow)
Getting exact counts requires scanning each table. This query builds and executes a COUNT(*) for every table. Use it on smaller databases only:
On a database with millions of rows, this can take a long time. The estimated count approach is preferred for large databases.
Combine row counts with sizes
This gives you a complete overview of your database in a single query.
Listing tables with column info
Column count per table
Full column details for all tables
Tables with a specific column
Sometimes you need to find every table that has a column named created_at or user_id:
Tables and their primary keys
Listing views vs tables
PostgreSQL has regular views, materialized views, and base tables. Here is how to list each type.
List only views
Or using psql:
\dv
List only materialized views
Materialized views do not appear in information_schema. Query pg_matviews instead:
Or using psql:
\dm
List everything (tables, views, materialized views)
This query also picks up foreign tables and partitioned tables. The relkind column in pg_class is the most reliable way to distinguish object types.
Common patterns
Check if a table exists
Or using pg_tables:
List tables created recently
PostgreSQL does not track creation timestamps in the catalog. One workaround is to check the file creation time on disk using pg_stat_file:
Note: this shows the last time the file was modified, not when the table was created. It is an approximation.
List empty tables
Run ANALYZE first to make sure the row estimates are current.
List partitioned tables and their partitions
List tables with no indexes
Tables without indexes (other than a primary key constraint) might need attention:
List tables with their access statistics
This query shows which tables are being used and how:
Tables with high sequential scan counts and low index scan counts may benefit from adding indexes.
Using a GUI client
If you prefer a visual interface, DB Pro shows your tables, views, sizes, and schemas in a sidebar without needing to remember any of these commands. It connects to PostgreSQL, MySQL, and SQLite databases.
Quick reference
| Task | psql command | SQL query |
|------|-------------|-----------|
| List tables | \dt | SELECT tablename FROM pg_tables WHERE schemaname = 'public' |
| List tables with sizes | \dt+ | Use pg_total_relation_size() (see above) |
| List tables in all schemas | \dt *.* | Remove the WHERE schemaname filter |
| List views | \dv | SELECT table_name FROM information_schema.views WHERE table_schema = 'public' |
| List materialized views | \dm | SELECT matviewname FROM pg_matviews WHERE schemaname = 'public' |
| Describe a table | \d tablename | Query information_schema.columns |
| Check if table exists | N/A | SELECT EXISTS (SELECT 1 FROM pg_tables WHERE ...) |
Summary
- Use
\dtin psql for a quick table listing, and\dt+for sizes - Query
information_schema.tableswhen you need portable SQL that works across database systems - Query
pg_tableswhen you need PostgreSQL-specific details like table ownership - Filter with
WHERE schemaname = 'public'to exclude system tables - Use
pg_classwithpg_namespacefor the most flexible queries (sizes, row counts, object types) - Estimated row counts from
pg_class.reltuplesare fast and good enough for most use cases - Combine
pg_total_relation_size()withpg_size_pretty()for human-readable size output