~

PostgreSQL pg_trgm — Trigram Similarity Functions

Complete reference for PostgreSQL pg_trgm extension functions covering trigram similarity scoring, fuzzy string matching, word similarity, and GIN/GiST index support for fast fuzzy searches. Includes similarity(), word_similarity(), and the % and <-> operators. Updated for PostgreSQL 16.

5 functions

What are PostgreSQL pg_trgm — Trigram Similarity Functions?

pg_trgm is a PostgreSQL extension that provides text similarity functions based on trigram (three-character n-gram) matching. similarity() returns a value from 0.0 to 1.0 indicating how similar two strings are, and the % operator tests whether two strings meet the similarity threshold set by pg_trgm.similarity_threshold. pg_trgm GIN or GiST indexes dramatically accelerate fuzzy string searches and LIKE/ILIKE queries on large text columns.

similarity

pg_trgm extension available since PG 8.3+. GIN/GiST index support for the % operator introduced in PG 9.1+.real

Returns a number between 0 and 1 representing how similar the two strings are, based on trigram overlap. Requires the pg_trgm extension.

DeveloperData Eng

Signature

similarity ( text, text ) → real

Parameters

ParameterTypeDescription
string1textFirst string to compare
string2textSecond string to compare

Examples

sql
SELECT similarity('hello world', 'hello word');
0.625
sql
SELECT similarity('PostgreSQL', 'PostgreSQL');
1.0
sql
SELECT name FROM products WHERE similarity(name, 'wrieless mouse') > 0.3 ORDER BY similarity(name, 'wrieless mouse') DESC;
Fuzzy product search with typo tolerance
sql
SELECT user_input, query, similarity(user_input, query) AS score FROM search_log WHERE similarity(user_input, query) < 0.5 ORDER BY score;
Audit log of low-confidence fuzzy matches for review
Anti-Pattern

The `%` operator checks `similarity(a,b) >= pg_trgm.similarity_threshold` (default 0.3). Create a GIN index: `CREATE INDEX ON t USING GIN (col gin_trgm_ops)` for O(log n) fuzzy search instead of full table scan.

example
CREATE EXTENSION pg_trgm;
CREATE INDEX ON products USING GIN (name gin_trgm_ops);
SELECT name, similarity(name, $1) AS sim FROM products WHERE name % $1 ORDER BY sim DESC LIMIT 10;
Fast fuzzy product search

word_similarity

word_similarity() introduced in PG 9.6+. The <% and %> operators (word similarity operators) also require PG 9.6+.real

Returns the greatest similarity between the trigrams of the first string and any continuous extent of trigrams of the second string. Better for searching a word within a longer string.

DeveloperData Eng

Signature

word_similarity ( text, text ) → real

Parameters

ParameterTypeDescription
search_termtextShorter search string
documenttextLonger string to search within

Examples

sql
SELECT word_similarity('word', 'two words here');
0.8
sql
SELECT word_similarity('pg', 'PostgreSQL database');
Similarity of short query in longer text
sql
SELECT name, word_similarity('apple', name) AS ws FROM products WHERE 'apple' <% name ORDER BY ws DESC LIMIT 5;
Products whose name contains a word close to 'apple'
sql
SELECT word_similarity('jscript', lang_name) AS ws, lang_name FROM programming_languages ORDER BY ws DESC LIMIT 3;
Closest language names to a misspelled 'jscript'
Anti-Pattern

`word_similarity(query, text)` measures how well the query matches a contiguous word in the text. More accurate than `similarity` when searching for a term within a longer product name or description.

example
SELECT name FROM products WHERE $1 <% name ORDER BY word_similarity($1, name) DESC LIMIT 5;
Products whose name contains something like the query

show_trgm

show_trgm() available since the pg_trgm extension was introduced in PG 8.3+.text[]

Returns an array of all the trigrams in the given string. Useful for debugging trigram-based searches.

DeveloperData Eng

Signature

show_trgm ( text ) → text[]

Parameters

ParameterTypeDescription
stringtextString to extract trigrams from

Examples

sql
SELECT show_trgm('cat');
{" c"," ca","at ","cat"}
sql
SELECT array_length(show_trgm(name), 1) AS trigram_count FROM products;
Number of trigrams per product name
sql
SELECT trgm FROM unnest(show_trgm('hello')) AS t(trgm) WHERE trgm = ANY(show_trgm('hell'));
Shared trigrams between 'hello' and 'hell'
sql
SELECT word, array_length(show_trgm(word), 1) AS n_trgm FROM (VALUES ('a'), ('ab'), ('abc'), ('abcd')) v(word);
Shows that words < 3 chars produce fewer/no useful trigrams
Anti-Pattern

The similarity score is `|A ∩ B| / |A ∪ B|` where A and B are trigram sets. Use `show_trgm` to inspect which trigrams are generated for your strings when debugging unexpected similarity scores.

example
SELECT show_trgm('hello'), show_trgm('hell');
Compare trigram sets to understand the similarity score

set_limit

set_limit() available since pg_trgm PG 8.3+. The equivalent GUC pg_trgm.similarity_threshold was introduced in PG 9.6+ and is preferred in modern deployments.real

Sets the current similarity threshold used by the % operator (default 0.3). Returns the new threshold.

DeveloperData Eng

Signature

set_limit ( real ) → real

Parameters

ParameterTypeDescription
thresholdrealSimilarity threshold between 0 and 1

Examples

sql
SELECT set_limit(0.5);
0.5
sql
SELECT set_limit(0.1); SELECT name FROM products WHERE name % 'phone';
More permissive fuzzy matching
sql
DO $ BEGIN PERFORM set_limit(0.4); END $;
SELECT name FROM brands WHERE name % $1;
Threshold set inside a PL/pgSQL block for a focused search
sql
SELECT set_limit(0.3); -- reset to default after custom search
0.3
Anti-Pattern

`set_limit` changes a session-level value. In multi-threaded applications, prefer setting it via a GUC: `SET pg_trgm.similarity_threshold = 0.5`. This is cleaner and persists correctly for the session.

example
SET pg_trgm.similarity_threshold = 0.4;
SELECT name FROM products WHERE name % $1;
Fuzzy search with explicit threshold

show_limit

show_limit() available since pg_trgm PG 8.3+. In PG 9.6+ you can also inspect the threshold via SHOW pg_trgm.similarity_threshold.real

Returns the current similarity threshold used by the % operator.

DeveloperData Eng

Signature

show_limit ( ) → real

Examples

sql
SELECT show_limit();
0.3 (default)
sql
SELECT set_limit(0.5); SELECT show_limit();
0.5 — confirms the threshold was updated
sql
DO $ BEGIN RAISE NOTICE 'Current trgm threshold: %', show_limit(); END $;
Logs current threshold inside a PL/pgSQL procedure for debugging
sql
SELECT show_limit() AS before, set_limit(0.4) AS after;
Shows old and new threshold in one query for audit logging
Anti-Pattern

Use `show_limit` to inspect and `set_limit` to change the session's similarity threshold. Reset to default (0.3) with `set_limit(0.3)` after a custom search operation.

example
SELECT show_limit(); -- Check current threshold
0.3