PostgreSQL
SQL injection remains most financially damaging application vulnerability
9SQL injection vulnerabilities from unescaped user input interpolation remain the perennial top contender for most financially damaging application security vulnerability. Developers continue to make mistakes in this area.
No In-Place Major Version Upgrades
8PostgreSQL does not support in-place major version upgrades. Upgrades require either dumping and restoring the entire dataset or setting up logical replication, with rigorous application compatibility testing required. Delaying upgrades increases complexity and risk, as outdated versions miss critical security patches, transforming routine maintenance into a complex, high-risk migration project.
Poor Performance with Large Data Volumes and Analytics
8PostgreSQL is not optimal for applications requiring real-time or near-real-time analytics. For massive single datasets (billions of rows, hundreds of gigabytes) with frequent joins, queries can take hours. PostgreSQL lacks native columnar storage support, necessitating non-core extensions and increasing architectural complexity.
Table corruption issues in PostgreSQL
8PostgreSQL experiences table corruption problems that can result in data integrity issues. This was significant enough to motivate organizations like Uber to evaluate alternative databases.
Scaling custom admin solutions causes cascading failures
8Custom admin panels that work for small teams degrade rapidly as the user base or data grows, leading to performance issues, broken queries, and unexpected feature failures. Significant rebuilding is often required if scalability wasn't planned from day one.
Schema evolution breaks tests and introduces silent failures
7When making schema changes to evolve the application's data handling, modifications either break tests immediately or don't, creating a worse scenario where tests no longer guarantee correctness. This requires iterative fixing of data integrity issues.
Building secure database access interfaces for non-technical users
7Creating secure admin panels for non-technical users requires juggling encryption, access control, and usability concerns. The complexity rivals building a secondary software system, making it difficult to maintain alongside the primary application.
Stored procedures lack version control, CI/CD integration, and debugging capabilities
7Business logic and jobs stored in PostgreSQL stored procedures have no git version control, exist only in production without documentation of authorship, and cannot be tested in CI/CD pipelines. Debugging is difficult without proper stack traces or logging tools, making maintenance a time-consuming nightmare.
Query plan instability causes unpredictable performance degradation
7PostgreSQL query execution plans can become unstable, causing previously performing queries to suddenly degrade. Developers must use advanced tools like Query Plan Management (QPM) and pg_hint_plan to ensure consistent query performance.
Network latency and infrastructure constraints in enterprise environments
7In corporate production environments, database requests traverse multiple network hops through firewalls and antivirus software, causing severe latency issues. Developers lack control over database configuration and cannot install extensions like PGVector, PG Cron, or PG Crypto, and often don't know which region their database is deployed in.
Row-Level Security (RLS) causes severe query performance degradation
7When Row-Level Security is enabled in production, query execution plans degrade dramatically. Fast SELECT queries become slow with unexpected multi-table joins, and indexes become ineffective, turning a simple database operation into a performance nightmare.
Schema migrations cause downtime due to exclusive locking on busy tables
7Certain PostgreSQL schema changes (like adding NOT NULL UNIQUE columns or renaming columns) require exclusive locks that block all other queries. On busy tables, migrations can be delayed waiting for exclusive locks, causing production downtime. Constraint backfilling and backwards-incompatible changes require multi-step migration processes.
Horizontal scalability limitations at high load
7PostgreSQL lacks native horizontal scalability features. When instance sizes become insufficient, teams experience downtime during scaling operations. Aurora vacuuming and scaling issues persist, and teams desire alternatives like CockroachDB that support true horizontal scaling without downtime.
Absence of Native Multi-Region Replication
7PostgreSQL does not offer native multi-region replication capabilities. Organizations must rely on logical replication and third-party tools like pglogical or BDR, increasing vendor dependency, expertise requirements, and operational overhead while creating potential vendor lock-in risks.
Complex configuration and monitoring required for replication and high availability
7Managing PostgreSQL replication requires intricate configuration and careful monitoring to prevent data loss or corruption. Achieving high availability demands automated failover mechanisms, load balancing between primary and standby servers, and selecting the appropriate replication strategy.
Read-heavy workload performance without proper replica/caching architecture
7Read-heavy workloads like reporting and analytics can severely degrade performance if read replicas and caching layers aren't properly configured. This requires upfront architectural planning that many teams delay.
Write-heavy workload bottlenecks without proper indexing and partitioning
7Write-heavy workloads with financial transactions and real-time updates require careful indexing and partitioning strategies to avoid slow inserts and locking issues. Without these, performance suffers significantly.
Default Security Configuration Weaknesses
7PostgreSQL default installations can allow passwordless logins ('Trust' method) if not managed, lack robust password policies, do not enable SSL/TLS encryption by default, and commonly grant unnecessary superuser privileges. Many vulnerabilities stem from misconfiguration and operational oversight rather than software flaws.
PostgreSQL failover on Kubernetes requires additional tooling expertise
7While Kubernetes can restart failed pods, it doesn't provide PostgreSQL-specific failover capabilities needed for production. Teams must implement tools like Patroni for proper leader election and failover, adding complexity and requiring dual expertise in both PostgreSQL and Kubernetes.
Inefficient write architecture compared to other databases
7PostgreSQL has an inefficient architecture for write operations compared to alternatives like MySQL. This limitation was significant enough for organizations like Uber to switch database systems.
Complex and error-prone autovacuum configuration
6Configuring autovacuum correctly is challenging due to its complexity. Default global settings are inappropriate for large tables with millions/billions of tuples. If autovacuum invocations take too long or are blocked, dead tuples accumulate and statistics become stale, causing gradual query slowdown. Manual intervention is often required.
Time-consuming and error-prone SQL query creation
6Building complex SQL queries is tedious, error-prone, and time-consuming. Developers frequently resort to AI assistance rather than writing queries manually, and must often redo work when requirements change or new clients appear.
Lack of expressive data model understanding leads to poor schema design
6Development teams unfamiliar with expressive data modeling often fail to apply important constraints like foreign keys, instead relying on familiar application-level patterns. This results in databases without essential integrity constraints.
Replicas lack true MVCC support
6PostgreSQL replicas apply WAL updates, making replicas identical copies of the master at any point in time. They don't have true replica MVCC support, preventing queries from reading different versions of data on replicas compared to the primary. This design poses significant constraints for distributed systems.
Difficult debugging with long application workflows and complex database logic
6Diagnosing failures becomes increasingly difficult when issues could originate from the database or application code. Long workflows and complex database-side logic require extensive investigation, making root cause analysis time-consuming.
PostgreSQL configuration parameters require server restart and are difficult to debug
6Configuration adjustments require a full server restart to take effect, making it risky to tune in production. Logs are noisy and difficult to access in ephemeral or PaaS environments, especially without tools like PG Badger.
Connection Pooling Neglect and Resource Exhaustion
6Failing to implement connection pooling is a common mistake in PostgreSQL deployments. Each connection consumes approximately 10MB of RAM, and applications that create new connections for each database operation can quickly exhaust server resources, leading to performance degradation and application failures.
MVCC version copying creates excessive data duplication
6PostgreSQL's MVCC implementation copies all columns of a tuple when any column is modified, regardless of which columns change. This causes significant data duplication and increased storage demands, especially for large tables with many columns. No practical workaround exists without major PostgreSQL rewrites.
Excessive or duplicate indexes degrade write performance and storage
6Unused or duplicate indexes cause every database modification to unnecessarily update those indexes, resulting in high storage utilization and IOPs consumption. This creates a silent performance drag that isn't immediately obvious.
Built-in replication cannot selectively replicate individual databases
6PostgreSQL's built-in replication replicates entire clusters with the same settings and priority, not individual databases. This forces teams to manage multiple separate clusters to control replication groups, significantly increasing management complexity and operational overhead.
Backup and disaster recovery complexity at scale
6As data volume grows to terabytes and petabytes, teams struggle to establish robust backup and recovery systems that ensure zero data loss. The complexity of managing backups at scale, combined with the need for rapid recovery, creates operational burden and concerns about data durability.
pg_dump and pg_restore have confusing workflows and incomplete backup defaults
5PostgreSQL backup and restore tools have counter-intuitive workflows: pg_dump by default does not include global objects like roles, so backups are incomplete unless users manually dump additional information. pg_dumpall doesn't support custom format, and pg_restore requires non-obvious flags like -C to create databases. File naming conventions (.backup) are inconsistent with documentation.
Complex decision-making between specialized PostgreSQL extensions
5Developers must make complex architectural decisions about which PostgreSQL extensions to use. For example, PostGIS for geospatial needs and pgvector for ML/embedding use cases are "killer apps," but selecting and integrating specialized extensions requires significant expertise.
Difficulty managing missing primary keys at scale
5Managing tables without primary keys presents challenges that scale poorly. No decent solution exists for identifying and managing missing primary keys in large-scale PostgreSQL deployments.
Complex querying of nested JSON data in PostgreSQL
5Working with JSON data in PostgreSQL requires special operators and functions that are difficult to use, especially with nested structures. While JSON saves time and space, querying it is error-prone.
Only receiving first validation error slows debugging cycles
5PostgreSQL validation returns only the first error per record, forcing developers to iterate through multiple correction cycles to resolve all data integrity issues. This extends debugging workflows substantially.
Difficulty navigating complex foreign key relationships
5Developers struggle to navigate database schemas with many foreign keys, jumping between related tables creates confusion and slows development speed even though foreign keys improve database architecture and performance.
Table Bloat from Lack of Regular VACUUM
5Failing to run VACUUM regularly can lead to bloated tables and degraded performance. Without VACUUM, PostgreSQL cannot reclaim space from deleted rows, accumulating dead tuples that consume disk space and slow down query performance over time.
PostgreSQL configuration and management are overly complex with many non-obvious settings
5PostgreSQL requires extensive tuning across memory management, vacuum, background writer, write-ahead log, and free-space map settings. Configuration files are long with many unnecessary options for typical users. Default logging is unhelpful for new users, and there is no built-in out-of-band monitoring to diagnose startup failures or query issues without manually launching backends.
Limited ability to debug complex nested database operations
4PostgreSQL provides insufficient tracing and debugging capabilities for nested operations like PL/pgSQL calls and cascaded foreign key actions. Developers cannot easily understand what is happening in complex nested contexts without extensive manual investigation.
Inconsistent Data Types Across Related Tables
4Using inconsistent data types across tables (e.g., SERIAL vs BIGINT for primary keys) can lead to unexpected behavior and foreign key relationship issues. This creates subtle bugs and requires careful schema design coordination across development teams.
PostgreSQL documentation lacks clarity, tutorials, and organization
4PostgreSQL documentation could be improved with better organization, clearer explanations, and more practical tutorials. This affects onboarding experience and developer productivity.