A practical article for founders, CTOs, and engineering leaders on why old PostgreSQL, MySQL, MariaDB, and MongoDB versions are not harmless infrastructure debt — and how to build a regular database upgrade process without heroic migrations.
Production databases usually age quietly. In many teams, the application is deployed frequently, dependencies are updated regularly, infrastructure moves through several minor releases, while PostgreSQL, MySQL, MariaDB, or MongoDB stays on the version chosen years ago. The argument sounds reasonable: the database works, there are no incidents, customers are not complaining, so changing it feels riskier than leaving it alone.
The problem is that database debt does not accumulate only in the server binary. It spreads into drivers, ORMs, extensions, replication topology, backup tooling, migration scripts, cloud-provider policies, and the knowledge of specific engineers. At some point, the question “When should we upgrade?” turns into something else: “Can we upgrade safely at all if tomorrow an audit, a CVE, a growing cloud bill, or our provider forces us to move?”
In September 2026, Percona published its 2026 State of Open Source Database Management Report. According to the official announcement, the research was conducted by Censuswide in July 2026 among 300 U.S.-based DBAs, SREs, and platform engineers working with PostgreSQL, MySQL, MongoDB, Redis, or Valkey (Percona report, press release). The public report page highlights themes that are familiar in infrastructure: cost, performance, security/compliance, vendor lock-in, and AI readiness. For example, 31% of respondents name rising cloud spend as the main barrier to reducing database TCO, 42% name inefficiency or slow throughput as the top performance challenge, and 54% identify vendor lock-in as an obstacle to adapting to changing regulatory requirements.
One widely circulated figure was 97% for obsolete or end-of-support database software. It should be attributed carefully: during the research, that figure was not visible on Percona’s public HTML report page, but media outlets cited it with reference to the report. TechRadar writes that, according to Percona, 97% of U.S. database administrators work with obsolete software, while DigitalToday phrases it as 97% of respondents whose organizations run at least some database versions outside support; the same article mentions 44% reporting a significant share of such databases (TechRadar, DigitalToday). This should not be read as a global statistic for every company in the world. But as a signal for SaaS and SMB companies, it is useful: the problem is widespread precisely because a database upgrade is not an apt upgrade; it is a stateful change with business consequences.
When a team says “we are on an old MySQL” or “we are still on PostgreSQL 13,” that is only the top layer. The real dependency graph is usually much wider.
It includes:
the DBMS engine version: major/minor, community build, or provider build;
extensions and plugins: PostgreSQL extensions, MySQL authentication plugins, MariaDB storage-engine specifics, MongoDB Feature Compatibility Version;
drivers and clients: JDBC, libpq/psycopg, MongoDB drivers, ORM dialects, migration tools;
application runtime: Java/JDK, Python, Go, Node.js, framework versions;
backup/restore tooling and tested recovery procedures;
replication and cutover tooling: physical replicas, logical replication, read replicas, blue/green;
observability agents and query analytics;
provider policies: EOL calendars, extended support, supported upgrade paths, regions/features;
process: whether there is an owner, staging restore, performance baseline, runbook, and abort criteria.
That is why database aging rarely appears as a single ticket. For example, MySQL 5.7→8.0 affected more than the server. MySQL 8.0 introduced a global transactional data dictionary, made caching_sha2_password the preferred/default authentication plugin, removed some deprecated account-management features, and clients or connectors without caching_sha2_password support could hit compatibility issues (MySQL docs). As a result, “upgrade the database” quickly became an audit of applications, drivers, users, migration tools, and CI.
MongoDB shows the same problem in a different way. Atlas major-version upgrade documentation explicitly recommends creating a staging cluster and testing the application before upgrading production; major versions can be upgraded only one at a time, skipping is not supported, and downgrade after a major upgrade is unavailable unless FCV was pinned beforehand (MongoDB Atlas docs). This is not a peculiarity of one managed service. It is normal stateful-system logic: compatibility has to be designed in advance.
It is wrong to explain this only as negligence. Often the team is not avoiding the upgrade because it does not care; the current version is simply the lesser evil in the short term.
In a stateless service, you can roll back a container, revert a feature flag, and survive a bad deploy. With a database, that does not always work: data has already changed, system tables have been updated, the replication topology has been rebuilt, and new binaries may have written a format that the old version does not understand.
So a small SaaS company develops a rational fear: “We will spend the weekend, get downtime, and customers will see no product benefit.” TechRadar’s summary of the Percona report highlights exactly this tension: a production database upgrade often becomes a major risky project requiring cross-stack migration, testing, infrastructure changes, and cloud changes (TechRadar).
A staging environment where an empty schema with seed data is deployed once a month is almost useless for a database upgrade. You need real cardinality, indexes, table sizes, query mix, extensions, parameters, replication lag, and storage behavior. Without that, the team only verifies that “the application starts,” not the things that actually fail under load.
Having a nightly backup does not mean you can recover within acceptable RTO/RPO. The AWS Well-Architected Reliability Pillar explicitly recommends periodic recovery to verify backup integrity and the recovery process itself (AWS Well-Architected). For database upgrades, this is not abstract DR hygiene; it is part of the rollback or roll-forward strategy.
An SMB product may not have a DBA or a separate platform team. One senior backend engineer knows there is an old BI connector somewhere, a legacy cron job has been “almost fully” rewritten, and staging does not bring up the read replica. Until there is external pressure, the upgrade loses to roadmap features.
That does not make the risk less real. It means the process must be minimal and regular, not enterprise-heavy.
EOL does not mean the database stops at midnight. It usually means upstream is no longer expected to provide security fixes, bug fixes, or standard lifecycle support for that version. For the business, this changes the conversation from “technical recommendation” to risk acceptance.
| DBMS | Lifecycle meaning for planning |
|---|---|
| PostgreSQL | The project releases a major version roughly once a year, minor releases at least once every three months as needed for bug/security fixes, and supports each major version for 5 years; after the final minor release, the version becomes unsupported/EOL (PostgreSQL versioning). |
| MySQL | Oracle/MySQL’s EOL notice states that as of April 21, 2026, MySQL 8.0 is under Oracle Sustaining Support; the release notes also state that 8.0.46 marks MySQL 8.0 EOL in April 2026 (EOL notice, 8.0 release notes). |
| MariaDB | MariaDB Foundation states that for End-of-Life releases the Foundation does not provide security updates, although outside contributors may submit fixes/backports. MariaDB Server 10.6 reached EOL on July 6, 2026 (policy, 10.6 EOL). |
| MongoDB | Major releases become available every two years and have a five-year lifecycle; deployments must be manually upgraded before EOL unless managed automation/options are used (MongoDB versioning). |
One important nuance: you do not have to upgrade on the first day of a major release. For PostgreSQL, for example, it is reasonable to account for extension support, managed-provider availability, and early minor releases. The goal is not to always be on the latest version; it is to avoid suddenly being outside support with no tested path forward.
At the time of research, PostgreSQL 19 was planned for September 2026, but a final release had not been confirmed as of September 18, 2026: the roadmap said planned September 2026, the release notes showed a placeholder release date, and the wiki open items mentioned Beta 4 on September 24, 2026 (roadmap, release notes, open items). Even as a planned release, it is a useful example: new major versions bring not only risk but also capability upside — SQL/PGQ property graph queries, the REPACK command, improvements to logical replication, and autovacuum improvements are listed in the draft/live release notes (PostgreSQL 19 notes).
OWASP Top 10 A06 treats software as vulnerable/outdated if it is vulnerable, unsupported, or out of date (OWASP A06). OWASP Infrastructure Security Risks 2024 separately describes outdated software as the accumulation of vulnerability risk due to the absence of update management (OWASP ISR01).
For companies with payments or enterprise customers, this quickly becomes a compliance conversation. The PCI SSC FAQ on unsupported operating systems/software says that PCI DSS requires systems to be kept up to date with vendor-supplied security patches; when unsupported software cannot be patched, compensating controls are needed against vulnerabilities that could lead to exploitation of unsupported code (PCI SSC FAQ 1130).
In other words, an EOL database is not automatically a failed audit, but it is a question that needs a documented answer: what compensating controls exist, what the migration plan is, who accepted the risk, and until what date.
A managed database reduces toil, but it does not eliminate lifecycle management. AWS RDS for MySQL publishes engine release calendars and Extended Support timelines; the pricing page states that restoring a snapshot to MySQL 5.7 after February 29, 2024 incurs RDS Extended Support pricing until upgrade to MySQL 8.0+ or deletion, and read replicas may also incur charges if they run after standard support (RDS MySQL versions, RDS MySQL pricing).
AWS RDS for PostgreSQL publishes tables with community release date, RDS release date, community EOL, RDS end of standard support, Extended Support pricing start, and end of Extended Support (RDS PostgreSQL calendar). This is a good model for an internal company EOL calendar.
Google Cloud SQL policy says instances on community-EOL major versions of MySQL and PostgreSQL are enrolled in extended support (Cloud SQL version policies). Azure Database for PostgreSQL flexible server supports major versions until community EOL and publishes retirement details separately (Azure PostgreSQL version policy).
The practical conclusion: a managed service turns EOL into a billing and policy event, not an invisible problem. Sometimes that helps — snapshots, automated backups, blue/green workflows. Sometimes it hurts — provider-controlled windows, version lag, feature limitations, and extended support charges.
An old database blocks more than security fixes. It constrains the roadmap: new query capabilities, replication improvements, tooling, driver versions, ORM features, and cloud-provider workflows. If the application depends on an old auth plugin or unsupported connector, every product change starts being checked against legacy-stack compatibility.
There is also an organizational risk: the longer a version lives without upgrade practice, the fewer people understand how to upgrade it. When the engineer who remembers the parameters, extensions, and strange workaround in the migration script leaves, technical debt becomes operational fragility.
The most dangerous sentence before a database upgrade is: “If anything happens, we’ll roll back.” Sometimes rollback is possible. Often it is possible only through a prepared restore, cutover back to the old side, or roll-forward.
Examples from documentation:
MySQL 8.0 release notes explicitly state that downgrade from MySQL 8.0 to 5.7, or from a MySQL 8.0 release to a previous MySQL 8.0 release, is not supported (MySQL 8.0 release notes).
MongoDB Community Edition binary downgrades are not supported; Enterprise downgrade requires support assistance, and MongoDB supports only single-version downgrades (MongoDB downgrade docs).
MongoDB Atlas major upgrades cannot be rolled back after the upgrade if FCV was not pinned beforehand (Atlas major version change).
PostgreSQL pg_upgrade link mode speeds up the upgrade and saves space, but after starting the new cluster, the old cluster can no longer be used (pg_upgrade docs).
MariaDB documentation says mariadb-upgrade must be run after an upgrade between major releases to update system tables and check tables; downgrade between major versions has constraints and becomes more complex after steps that change system tables (mariadb-upgrade, major upgrades).
So before the change window, choose a specific strategy rather than relying on “we’ll roll back somehow”:
Snapshot/backup restore — reliable, but may not fit the RTO and loses changes after the backup unless there is an additional mechanism.
Logical replication cutover — often useful for reducing downtime and allowing rollback to the old side until the point of no return, but it requires schema compatibility, careful switchover, and lag control.
Blue/green — a managed option where the provider helps create a green environment and switch over, but constraints depend on engine, version, and region.
Roll-forward — fix the issue on the new version using feature flags, backward-compatible schema, and prewritten remediation scripts.
For databases, roll-forward is often more honest than promising instant rollback.
PostgreSQL documentation describes three main approaches to major upgrades: logical dump/restore, pg_upgrade, and logical replication between major versions (Upgrading a PostgreSQL Cluster). File-system-level backups are not suitable for dump/restore between major versions, while logical replication can work across different major versions.
pg_upgrade is often chosen for speed, but it has operational constraints: cluster settings compatibility checks, limitations around contrib modules, OID-referencing system data types, and standby upgrade flows; link mode changes the rollback trade-off (pg_upgrade).
PostgreSQL 19 migration notes add a good example of why you need a test restore, not just empty staging: migration requires pg_dumpall, pg_upgrade, or logical replication; dumps created by pre-PostgreSQL 19 pg_dump/pg_dumpall with standard_conforming_strings=off may not properly load into PostgreSQL 19 and later (PostgreSQL 19 release notes). This is exactly the class of problem that appears only during rehearsal.
For MySQL, upgrade readiness should start with a compatibility check. MySQL Shell includes the Upgrade Checker Utility for checking MySQL 5.7 or 8.0 instances before upgrade; Oracle recommends running readiness checks before moving to newer releases (Upgrade Checker Utility).
But the checker does not replace dependency audit. MySQL Connector/J documentation publishes compatibility information across MySQL Server and Java versions and recommends the latest Connector/J for MySQL Server 8.0 and higher (Connector/J compatibility). The same applies to ORM dialects, migration tools, BI/ETL connectors, auth plugins, and runtime versions.
A MariaDB upgrade is not just package replacement. After a major upgrade, the documentation requires mariadb-upgrade to update system tables and check tables (mariadb-upgrade). For EOL versions, do not confuse “still starts” with “receives security maintenance”: the Foundation policy explicitly says that for End-of-Life releases, security updates are not provided by the Foundation (MariaDB policy).
MariaDB 10.6 reaching EOL on July 6, 2026 is a useful example of a pragmatic transition state: the Foundation advised users on 10.6 to use the latest 10.6 maintenance release while preparing migration, but emphasized that migration should be prepared now (MariaDB 10.6 EOL).
MongoDB major releases have a five-year lifecycle, and Atlas major upgrades require a staging cluster, application testing, one-major-at-a-time upgrades, and careful FCV handling (MongoDB versioning, Atlas upgrade docs).
FCV is especially important as a control point: if it is not pinned before the upgrade, the downgrade path may disappear. That does not mean FCV is a rollback strategy by itself. It means compatibility state must be planned as part of the runbook.
Amazon RDS Blue/Green Deployments supports MariaDB, MySQL, and PostgreSQL versions and can be used for major/minor engine upgrades, parameter changes, and schema changes in a staging environment; AWS notes that PostgreSQL blue/green may use logical or physical replication depending on conditions (RDS Blue/Green).
This is a useful tool, not magic. You still need release notes review, dependency audit, performance baseline, replication lag checks, success and abort criteria, and an understanding of provider-specific limitations.
A small team does not need a 40-page database platform maturity model on day one. It needs a process that prevents surprises.
The practical order is: first understand which databases you have and when they leave support; then prove you can recover and test an upgrade on production-like data; after that, work through dependencies, performance, and the runbook for a specific window.
Create a table for all production and critical non-production databases:
engine and exact version;
managed/self-managed, provider, region;
owner: team and named person;
business criticality and data sensitivity;
upstream EOL and provider standard support end;
extensions/plugins/FCV/auth plugins;
drivers/ORMs/migration tools;
backup method, retention, last successful restore test;
replicas, logical replication, read replicas, analytics consumers;
observability and alerting coverage.
The main goal is not a perfect CMDB. It is to eliminate unknown production databases.
At minimum, the calendar should include:
current version;
upstream EOL;
managed-provider end of standard support;
extended support start and the point where extra cost begins, if applicable;
target version;
dependency audit deadline;
staging restore rehearsal;
performance test window;
production change window;
risk owner.
AWS RDS PostgreSQL’s release calendar is a good structural example: it shows community release date, RDS release date, community EOL, RDS end of standard support, Extended Support pricing start, and end of Extended Support side by side (AWS RDS PostgreSQL calendar). The same format is useful internally even if you run databases yourself.
After this, the team no longer has an abstract “we should upgrade someday.” It has a visible calendar of risks and decisions.
For every upgrade, check:
official release notes and breaking changes;
server parameters and deprecated/removed features;
extensions/plugins compatibility;
drivers and connectors;
ORM dialects;
migration framework;
application runtime versions;
BI/ETL jobs and read-only consumers;
backup/restore tools;
monitoring agents.
For MySQL, run the Upgrade Checker Utility where applicable (MySQL Shell Upgrade Checker). For PostgreSQL, test the selected path: dump/restore, pg_upgrade, or logical replication. For MongoDB Atlas, rehearse with a staging cluster and one major version at a time.
Staging should be built from a recent backup/snapshot, not synthetic seed data. If data must be anonymized, preserve the important workload properties: volumes, cardinality, distributions, indexes, constraints, and approximate query mix. Otherwise the performance test will look good and tell you very little.
Before the upgrade, capture a baseline:
top queries by time and frequency;
p95/p99 latency at the application and database levels;
throughput;
locks/deadlocks;
replication lag;
checkpoint/vacuum behavior for PostgreSQL;
CPU/IO/storage saturation;
slow queries;
connection pool saturation;
key business transactions.
PostgreSQL ships pgbench and supports custom benchmark scripts (pgbench docs). Percona Monitoring and Management is documented as an open-source monitoring/observability solution for MySQL, PostgreSQL, and MongoDB; Query Analytics helps analyze where queries spend time and compare performance characteristics over time (PMM docs, Query Analytics). MongoDB engineering materials also describe automated performance testing for catching regressions before release (paper, MongoDB engineering blog).
But a generic benchmark is not enough. A database may improve on pgbench and regress on your ORM-generated queries, data distribution, or indexes. The baseline must include production-like workload.
The runbook should answer:
who owns the decision during the window;
which steps are performed and by whom;
which commands have already been tested in staging;
when the freeze on schema/app changes starts;
which health gates count as success;
which metrics are abort criteria;
what to do on replication lag, failed migration, or unexpected slow queries;
which rollback/restore/roll-forward path was selected;
when the rollback window is considered closed;
which destructive cleanup steps are postponed.
If this is not documented before the upgrade window, the team will design the process under pressure.
Database upgrades are often scary not only because of the engine version, but because of a backlog of schema changes. The team thinks: “Since we are touching the database anyway, let’s rewrite the tables too.” This increases the blast radius.
It is better to separate:
engine upgrade;
application compatibility changes;
schema evolution;
data backfills;
destructive cleanup.
For schema evolution, the expand/contract pattern is useful. Prisma describes it as a two-step approach: first add the new shape and copy the data, then remove the old shape after nobody reads it anymore (Prisma docs). GitLab documents post-deployment migrations, separating application deployment from state-mutating database changes; for column removal, it uses a no-downtime pattern: first deploy code that no longer depends on the column, then run the migration that removes the column (GitLab docs).
For large MySQL tables, GitHub’s gh-ost is an example of an online schema migration tool that makes live schema changes low-impact, controllable, auditable, and operations-friendly through a ghost table pattern without triggers (GitHub Engineering). It is not a major-version upgrade tool, but it reduces the general fear of database changes.
Practical rule: if you can avoid combining an engine upgrade, a large schema rewrite, and an application rewrite, avoid it.
The SRE approach to releases applies to databases, but with constraints. The Google SRE Workbook describes canarying as a gradual, measured change where the canary should detect bad candidates with enough confidence; release engineering works with SRE on canaries, non-interrupting releases, and rollback strategies (Canarying Releases, Release Engineering).
For databases, canaries are harder because state is shared and mutable. But gradual exposure is still possible:
read-only shadow traffic;
analytics/read-only consumers first;
internal tenants or internal traffic;
canary tenants, if the multi-tenant architecture allows it;
read replica testing;
blue/green green environment;
controlled cutover with lag monitoring.
Health gates must be concrete:
application error rate;
p95/p99 latency;
slow query volume;
lock waits/deadlocks;
replication lag;
connection saturation;
CPU/IO/storage;
disk growth;
backup success;
business transaction success rate.
After cutover, do not immediately delete the old environment, drop columns, change FCV without need, or clean up the fallback path. Let the system go through a period of heightened monitoring.
| Option | What it simplifies | What remains risky |
|---|---|---|
| Managed DB | Snapshots, automated backups, minor patching, provider workflows, blue/green for supported engines/versions, less operational toil. | Extended support charges, provider-controlled timelines, version lag, feature/extension limitations, forced or policy-driven upgrades, provider-specific rollback limits. |
| Self-managed | Full control over timing, custom replication/cutover, custom tooling, deeper optimization. | Full responsibility for security patches, HA/DR, backup validation, monitoring, upgrade runbooks, DBA/SRE expertise. |
The choice is not simply “managed is better” or “self-managed is more flexible.” For founders and CTOs, the more useful axes are:
whether you have in-house DBA/SRE competence;
how unusual the workload is;
how critical compliance and audit are;
whether you can accept provider timelines;
how important cost predictability is;
what your RTO/RPO is;
which extensions/features the product needs.
Managed DB can be an excellent option for SMBs, but you still need an EOL calendar. You are just tracking provider policy in addition to upstream lifecycle.
Database upgrade debt is dangerous not because an old version will necessarily break tomorrow. It is dangerous because the team loses the ability to choose the timing and method of change.
If you have an inventory, EOL calendar, dependency audit, staging restore, tested backups, performance baseline, and runbook, the CTO can make an informed decision: wait for a minor release, buy extended support for a limited period, add compensating controls, schedule migration after peak season, or accelerate the upgrade because of an audit or product need.
If you do not have this, external events make the decision for you: a CVE, an auditor, a cyber-insurance questionnaire, cloud-provider billing, a forced upgrade window, or the departure of the only engineer who remembers the system.
A minimal plan for the next quarter for a SaaS/SMB team:
Find all production and critical databases.
Record versions, owners, provider, extensions/plugins, drivers, and backup method.
Add upstream EOL and managed-provider support dates.
Check when restore was last performed, not only when backup last succeeded.
Bring up staging from a fresh backup/snapshot.
Run available preflight checks and read the release notes for the target version.
Capture a performance baseline from real workload.
Write a runbook with success, abort, and rollback/roll-forward strategy.
Do not combine the upgrade with a large schema rewrite unless necessary.
Put database upgrades into the same planning system as SLOs, security remediation, and roadmap-enabling platform work.
A good team is not the one that upgrades first. A good team is the one that is not surprised by EOL.
We'll figure it out together—
and show you how to solve
the problem quickly and effectively