Skip to content
dbexplore

Question: Upgrades

Do I need to run ANALYZE after pg_upgrade?

Answered in the first paragraph. Last updated .

This changed recently, so check which version you are upgrading to before copying anybody’s runbook. Upgrading to PostgreSQL 18 or later transfers most optimizer statistics, and the new cluster starts with plans rather than guesses. Every earlier version discards them entirely, which is why a cluster that was healthy before the upgrade spends its first hour on its knees. Either way, some statistics do not travel and a pass afterwards is still the correct final step.

What does not come across, on any version

Statistics you created explicitly across several columns are not transferred, and neither are any provided by an extension. The cumulative activity counters are separate machinery and start again from nothing, so every dashboard reading from them shows a cluster that was born this morning. What a statistics reset does and does not clear applies here in full.

One thing that does survive is anything stored as a property of the column rather than as a sample, which includes a hand-set distinct-value estimate. Those are part of the schema and come through with it, so an override you set to correct a bad estimate is still in place afterwards, which is worth knowing because it is the one correction people assume they have to redo.

The recommended finish is therefore two passes: one that quickly fills in anything with no statistics at all, and a full one afterwards. On a large cluster, run them with the cost pacing turned off and with parallelism, because until they complete the planner is working from whatever survived.

Why the old behaviour caused outages

On anything before 18, the new cluster opens for traffic with empty statistics. Every plan is built on default guesses, which produces table scans where index scans belong, and the load those plans generate is what prevents the statistics pass from finishing. The cluster is not broken and it is not slow because of the version; it is slow because it is planning blind, and it recovers the moment the pass completes.

That is the whole reason the staged form of the pass exists: get rough statistics into every table fast, accept that they are rough, and refine afterwards. Treat it as part of the upgrade window rather than as cleanup for the morning after.

Two other things belong in the same window. Extensions have to exist and be compatible on the target before the upgrade will even run, which pg_upgrade and extensions covers. And if the operating system changed underneath at the same time, text indexes may be ordered by a rule that no longer applies, which is do I need to reindex after a major upgrade.

Put every Postgres you run on autopilot.

We onboard teams in small batches. Tell us about your fleet and we will reach out when a seat opens. One email, no drip campaign.