Question: Configuration
What should random_page_cost be on SSD?
Answered in the first paragraph. Last updated .
Lower than the default of four, and the exact figure matters less than people expect. The documentation is explicit that these are arbitrary units whose only meaning is relative to the sequential page cost of one, and that scaling every cost by the same factor changes no decision at all. On flash storage something between one and two is the usual landing spot, and on a database small enough to sit in memory the argument for going close to one is stronger still.
What the setting is actually asserting
It states how much more expensive the planner should believe a random page read is than a sequential one. On rotating disks that ratio was genuinely large, because a seek was mechanical. On flash it is small. When the page is already in cache it is nothing at all, which is why a cached database wants a lower value than the same database on the same hardware would if it did not fit.
That last point leads to the setting people should be arguing about instead. The planner’s assumption about how much cache is available to a single query shifts exactly the same decisions, defaults to a figure that is wrong on most dedicated servers, and is more often the cause of an index being ignored. Effective cache size covers it.
Changing it without guessing
Do it in a session first. Both settings are reloadable and can be set for one connection, so you can re-plan the queries you care about at several values and watch where the choice flips before changing anything cluster-wide. The signal you are looking for is a plan moving between an index scan and a table scan, which is the decision the whole cost model exists to make.
Two warnings. Do not tune this to force one query into the plan you wanted, because the usual reason a good index is ignored is a bad row estimate rather than a bad page cost, and lowering the cost until the estimate is overridden leaves every other query planned by a model you have deliberately bent. The two causes are separated in why Postgres is not using my index.
And treat the change as a plan-wide event. Lowering it shifts many queries at once, most of them in the direction you want and a few of them not, so capture the plans of your important statements before and after rather than only the one that prompted the change. Query plan regression covers making that comparison routine instead of heroic.