PostgreSQL configuration limit exceeded error (54000) occurs when a predefined system limit is surpassed, such as maximum table columns, function arguments, or query complexity. Fix by refactoring your schema or query design rather than adjusting compiled limits.
PostgreSQL enforces hard-coded limits on various configuration parameters to maintain system stability and prevent resource exhaustion. When you exceed these limits—such as table width, recursion depth, or index size—the database returns error 54000 (program_limit_exceeded). Unlike soft limits like max_connections that can be adjusted in postgresql.conf, configuration limits are compiled into PostgreSQL and cannot be changed through configuration alone.
The error will include details about which limit was exceeded. Common formats:
ERROR: index row size 4496 exceeds maximum 2712
ERROR: row is too big: size 8192, maximum size 8160
ERROR: stack depth limit exceededNote the specific limit mentioned to determine which solution applies.
If you have a table with many columns, split it into multiple related tables:
-- Move rarely-accessed columns to a separate table
CREATE TABLE users_extended (
user_id INTEGER REFERENCES users(id),
profile_data TEXT,
preferences JSONB
);
-- Query across tables when needed
SELECT u.*, ue.profile_data FROM users u
LEFT JOIN users_extended ue ON u.id = ue.user_id;PostgreSQL efficiently handles 1600 columns per table; split wider tables.
Instead of indexing the entire large column directly, create a functional index or use full-text search:
-- Problem: Indexing large text column
CREATE INDEX idx_large_text ON documents(body); -- May fail
-- Solution 1: Hash the value
CREATE INDEX idx_body_hash ON documents(md5(body));
-- Solution 2: Use full-text search index (more efficient)
CREATE INDEX idx_body_fts ON documents USING GIN(to_tsvector('english', body));
-- Query with full-text search
SELECT * FROM documents
WHERE to_tsvector('english', body) @@ to_tsquery('english', 'your:query');Rewrite recursive logic to use iterative approaches or WITH RECURSIVE CTEs:
-- Problem: Deep recursion
CREATE OR REPLACE FUNCTION find_children(id INT) RETURNS TABLE(child_id INT) AS $$
BEGIN
RETURN QUERY SELECT child_id FROM items WHERE parent_id = id;
RETURN QUERY SELECT * FROM find_children(child_id);
END;
$$ LANGUAGE plpgsql;
-- Solution: Use WITH RECURSIVE CTE
WITH RECURSIVE hierarchy AS (
SELECT id, parent_id FROM items WHERE parent_id = $1
UNION ALL
SELECT i.id, i.parent_id FROM items i
INNER JOIN hierarchy h ON i.parent_id = h.id
)
SELECT id FROM hierarchy;Recursive CTEs are more efficient and avoid stack depth issues.
Break down complex aggregations into separate queries or use UNION ALL:
-- Problem: Too many grouping sets
SELECT col1, col2, col3, col4, COUNT(*)
FROM table1
GROUP BY GROUPING SETS (
(col1, col2, col3, col4),
(col1, col2, col3),
(col1, col2),
(col1),
()
);
-- Solution: Separate simpler queries
SELECT col1, col2, col3, col4, COUNT(*) FROM table1
GROUP BY col1, col2, col3, col4
UNION ALL
SELECT col1, col2, col3, NULL, COUNT(*) FROM table1
GROUP BY col1, col2, col3;PostgreSQL's configuration limits are hard-coded during compilation and cannot be changed via postgresql.conf adjustments. On managed platforms (Heroku, AWS RDS), you typically cannot recompile PostgreSQL, making schema refactoring the only practical solution. The max_stack_depth parameter can be increased on self-hosted PostgreSQL (HINT message shows current value), but this requires platform ulimit coordination—on managed services this is often impossible. Always prefer schema redesign over trying to bypass compiled limits. Consider using TOAST (The Oversized-Attribute Storage Technique) for large text/bytea columns, which stores oversized data separately from main tuples and avoids bloating indexes.
insufficient columns in unique constraint for partition key
How to fix "insufficient columns in unique constraint for partition key" in PostgreSQL
ERROR 42501: must be owner of table
How to fix "must be owner of table" in PostgreSQL
trigger cannot change partition destination
How to fix "Trigger cannot change partition destination" in PostgreSQL
SSL error: certificate does not match host name
SSL error: certificate does not match host name in PostgreSQL
No SSL connection
No SSL connection to PostgreSQL