PostgreSQL Ignored My Index — Until I Fought Back (A Planner Battle Story)
I noticed that a seemingly harmless query on one of our lookup tables was responsible for ~13% of total CPU usage in production. This was surprising, especially since the query targeted a text field backed by a trigram GIN index — which should’ve made it lightning fast. But PostgreSQL had other ideas. It kept choosing a sequential scan, leading to unnecessary CPU load. This post walks through how I investigated the problem, why I rejected some common solutions, and the subtle one-line trick that ended up working — without extensions, transactions, or rewriting the query.

I noticed that a seemingly harmless query on one of our lookup tables was responsible for ~13% of total CPU usage in production. This was surprising, especially since the query targeted a text field backed by a trigram GIN index — which should’ve made it lightning fast.
But PostgreSQL had other ideas. It kept choosing a sequential scan, leading to unnecessary CPU load.
This post walks through how I investigated the problem, why I rejected some common solutions, and the subtle one-line trick that ended up working — without extensions, transactions, or rewriting the query.