Skip to content
biscuit

biscuit

pg_biscuit : IAM-LIKE pattern matching with bitmap indexing

Overview

ID Extension Package Version Category License Language
2170
biscuit
pg_biscuit
3.0.0
FTS
MIT
C
Attribute Has Binary Has Library Need Load Has DDL Relocatable Trusted
--s-d--
No
Yes
No
Yes
no
no
Relationships
Schemas public
Requires
plpgsql
See Also
pg_trgm
pg_similarity
fuzzystrmatch
smlar
pg_bigm
pgpcre
re2
pgroonga

Latest stable PGXN distribution and packaged extension version are 3.0.0; upgrading from 2.x requires REINDEX; package name is biscuit.

Packages

Type Repo Version PG Major Compatibility Package Pattern Dependencies
EXT
PIGSTY
3.0.0
18
17
16
15
14
pg_biscuit plpgsql
RPM
PIGSTY
3.0.0
18
17
16
15
14
biscuit_$v -
DEB
PIGSTY
3.0.0
18
17
16
15
14
postgresql-$v-biscuit -
Linux / PG PG18 PG17 PG16 PG15 PG14
el8.x86_64
PIGSTY 3.0.0
PIGSTY 3.0.0
PIGSTY 3.0.0
N/A
N/A
el8.aarch64
PIGSTY 3.0.0
PIGSTY 3.0.0
PIGSTY 3.0.0
N/A
N/A
el9.x86_64
PIGSTY 3.0.0
PIGSTY 3.0.0
PIGSTY 3.0.0
N/A
N/A
el9.aarch64
PIGSTY 3.0.0
PIGSTY 3.0.0
PIGSTY 3.0.0
N/A
N/A
el10.x86_64
PIGSTY 3.0.0
PIGSTY 3.0.0
PIGSTY 3.0.0
N/A
N/A
el10.aarch64
PIGSTY 3.0.0
PIGSTY 3.0.0
PIGSTY 3.0.0
N/A
N/A
d12.x86_64
PIGSTY 3.0.0
PIGSTY 3.0.0
PIGSTY 3.0.0
N/A
N/A
d12.aarch64
PIGSTY 3.0.0
PIGSTY 3.0.0
PIGSTY 3.0.0
N/A
N/A
d13.x86_64
PIGSTY 3.0.0
PIGSTY 3.0.0
PIGSTY 3.0.0
N/A
N/A
d13.aarch64
PIGSTY 3.0.0
PIGSTY 3.0.0
PIGSTY 3.0.0
N/A
N/A
u22.x86_64
PIGSTY 3.0.0
PIGSTY 3.0.0
PIGSTY 3.0.0
N/A
N/A
u22.aarch64
PIGSTY 3.0.0
PIGSTY 3.0.0
PIGSTY 3.0.0
N/A
N/A
u24.x86_64
PIGSTY 3.0.0
PIGSTY 3.0.0
PIGSTY 3.0.0
N/A
N/A
u24.aarch64
PIGSTY 3.0.0
PIGSTY 3.0.0
PIGSTY 3.0.0
N/A
N/A
u26.x86_64
PIGSTY 3.0.0
PIGSTY 3.0.0
PIGSTY 3.0.0
N/A
N/A
u26.aarch64
PIGSTY 3.0.0
PIGSTY 3.0.0
PIGSTY 3.0.0
N/A
N/A
Package Version OS ORG SIZE File URL
biscuit_18 3.0.0 el8.x86_64 pigsty 105.1 KiB biscuit_18-3.0.0-1PIGSTY.el8.x86_64.rpm
biscuit_18 2.4.0 el8.x86_64 pgdg 62.4 KiB biscuit_18-2.4.0-1PGDG.rhel8.10.x86_64.rpm
biscuit_18 2.2.2 el8.x86_64 pgdg 63.6 KiB biscuit_18-2.2.2-1PGDG.rhel8.10.x86_64.rpm
biscuit_18 3.0.0 el8.aarch64 pigsty 98.6 KiB biscuit_18-3.0.0-1PIGSTY.el8.aarch64.rpm
biscuit_18 2.4.0 el8.aarch64 pgdg 59.2 KiB biscuit_18-2.4.0-1PGDG.rhel8.10.aarch64.rpm
biscuit_18 2.2.2 el8.aarch64 pgdg 59.1 KiB biscuit_18-2.2.2-1PGDG.rhel8.10.aarch64.rpm
biscuit_18 3.0.0 el9.x86_64 pigsty 101.6 KiB biscuit_18-3.0.0-1PIGSTY.el9.x86_64.rpm
biscuit_18 2.4.0 el9.x86_64 pgdg 62.8 KiB biscuit_18-2.4.0-1PGDG.rhel9.8.x86_64.rpm
biscuit_18 2.2.2 el9.x86_64 pgdg 65.2 KiB biscuit_18-2.2.2-1PGDG.rhel9.8.x86_64.rpm
biscuit_18 2.2.2 el9.x86_64 pgdg 65.3 KiB biscuit_18-2.2.2-1PGDG.rhel9.7.x86_64.rpm
biscuit_18 2.2.2 el9.x86_64 pgdg 65.4 KiB biscuit_18-2.2.2-1PGDG.rhel9.6.x86_64.rpm
biscuit_18 3.0.0 el9.aarch64 pigsty 96.4 KiB biscuit_18-3.0.0-1PIGSTY.el9.aarch64.rpm
biscuit_18 2.4.0 el9.aarch64 pgdg 61.9 KiB biscuit_18-2.4.0-1PGDG.rhel9.8.aarch64.rpm
biscuit_18 2.2.2 el9.aarch64 pgdg 62.6 KiB biscuit_18-2.2.2-1PGDG.rhel9.8.aarch64.rpm
biscuit_18 2.2.2 el9.aarch64 pgdg 62.6 KiB biscuit_18-2.2.2-1PGDG.rhel9.7.aarch64.rpm
biscuit_18 2.2.2 el9.aarch64 pgdg 62.8 KiB biscuit_18-2.2.2-1PGDG.rhel9.6.aarch64.rpm
biscuit_18 3.0.0 el10.x86_64 pigsty 102.0 KiB biscuit_18-3.0.0-1PIGSTY.el10.x86_64.rpm
biscuit_18 2.4.0 el10.x86_64 pgdg 64.7 KiB biscuit_18-2.4.0-1PGDG.rhel10.2.x86_64.rpm
biscuit_18 2.2.2 el10.x86_64 pgdg 67.9 KiB biscuit_18-2.2.2-1PGDG.rhel10.2.x86_64.rpm
biscuit_18 2.2.2 el10.x86_64 pgdg 67.9 KiB biscuit_18-2.2.2-1PGDG.rhel10.1.x86_64.rpm
biscuit_18 2.2.2 el10.x86_64 pgdg 68.6 KiB biscuit_18-2.2.2-1PGDG.rhel10.0.x86_64.rpm
biscuit_18 3.0.0 el10.aarch64 pigsty 98.2 KiB biscuit_18-3.0.0-1PIGSTY.el10.aarch64.rpm
biscuit_18 2.4.0 el10.aarch64 pgdg 63.4 KiB biscuit_18-2.4.0-1PGDG.rhel10.2.aarch64.rpm
biscuit_18 2.2.2 el10.aarch64 pgdg 64.8 KiB biscuit_18-2.2.2-1PGDG.rhel10.2.aarch64.rpm
biscuit_18 2.2.2 el10.aarch64 pgdg 64.8 KiB biscuit_18-2.2.2-1PGDG.rhel10.1.aarch64.rpm
biscuit_18 2.2.2 el10.aarch64 pgdg 64.8 KiB biscuit_18-2.2.2-1PGDG.rhel10.0.aarch64.rpm
postgresql-18-biscuit 3.0.0 d12.x86_64 pigsty 250.2 KiB postgresql-18-biscuit_3.0.0-1PGSTY~bookworm_amd64.deb
postgresql-18-biscuit 3.0.0 d12.aarch64 pigsty 242.5 KiB postgresql-18-biscuit_3.0.0-1PGSTY~bookworm_arm64.deb
postgresql-18-biscuit 3.0.0 d13.x86_64 pigsty 251.3 KiB postgresql-18-biscuit_3.0.0-1PGSTY~trixie_amd64.deb
postgresql-18-biscuit 3.0.0 d13.aarch64 pigsty 243.1 KiB postgresql-18-biscuit_3.0.0-1PGSTY~trixie_arm64.deb
postgresql-18-biscuit 3.0.0 u22.x86_64 pigsty 258.2 KiB postgresql-18-biscuit_3.0.0-1PGSTY~jammy_amd64.deb
postgresql-18-biscuit 3.0.0 u22.aarch64 pigsty 252.0 KiB postgresql-18-biscuit_3.0.0-1PGSTY~jammy_arm64.deb
postgresql-18-biscuit 3.0.0 u24.x86_64 pigsty 250.7 KiB postgresql-18-biscuit_3.0.0-1PGSTY~noble_amd64.deb
postgresql-18-biscuit 3.0.0 u24.aarch64 pigsty 244.7 KiB postgresql-18-biscuit_3.0.0-1PGSTY~noble_arm64.deb
postgresql-18-biscuit 3.0.0 u26.x86_64 pigsty 247.3 KiB postgresql-18-biscuit_3.0.0-1PGSTY~resolute_amd64.deb
postgresql-18-biscuit 3.0.0 u26.aarch64 pigsty 241.3 KiB postgresql-18-biscuit_3.0.0-1PGSTY~resolute_arm64.deb

Source

pig build pkg pg_biscuit;		# build rpm/deb

Install

Make sure PGDG and PIGSTY repo available:

pig repo add pgsql -u   # add both repo and update cache

Install this extension with pig:

pig install pg_biscuit;		# install via package name, for the active PG version
pig install biscuit;		# install by extension name, for the current active PG version

pig install biscuit -v 18;   # install for PG 18
pig install biscuit -v 17;   # install for PG 17
pig install biscuit -v 16;   # install for PG 16

Create this extension with:

CREATE EXTENSION biscuit CASCADE; -- requires plpgsql

Usage

Sources:

biscuit 3.0.0 is a PostgreSQL 16+ positional-bitmap index access method for exact LIKE and ILIKE filtering. It is strongest for anchored patterns, _ wildcards, length predicates, and multi-column conjunctions. Version 3.0.0 stores index state in WAL-logged relation pages, so crash recovery, point-in-time recovery, physical replication, and hot-standby reads use PostgreSQL’s ordinary recovery path. It does not require shared_preload_libraries or a restart.

The project remains under active development and recommends representative staging tests. Its per-connection memory, write amplification, and cache-reload behavior make it best suited to read-mostly analytical workloads rather than continuously updated OLTP tables or very large connection pools.

Build and Query an Index

Load the data first, then create the index. The default biscuit_ops supports both case-sensitive and case-insensitive predicates. Use biscuit_like_ops or biscuit_ilike_ops when only one mode is required, avoiding the unused structure set.

CREATE EXTENSION biscuit;

CREATE INDEX message_body_biscuit_idx
ON message USING biscuit (body biscuit_like_ops);

ANALYZE message;

EXPLAIN (ANALYZE, BUFFERS)
SELECT id, body
FROM message
WHERE body LIKE 'timeout%';

Expression and multi-column indexes are supported. The query must use expressions and operators compatible with the chosen operator class. Check representative plans after loading statistics, especially for unanchored patterns.

Operator Classes and Query Boundaries

  • biscuit_ops is the default text operator class and indexes LIKE, NOT LIKE, ILIKE, and NOT ILIKE.
  • biscuit_like_ops indexes only LIKE and NOT LIKE.
  • biscuit_ilike_ops indexes only ILIKE and NOT ILIKE.

Biscuit returns exact matches without a heap recheck, but it is a filtering index: it does not provide ordered, backward, index-only, or unique scans, cannot back CLUSTER, and does not support regular expressions, similarity search, fuzzy search, or locale-aware collation. A B-tree with text_pattern_ops is usually a better fit for selective prefix lookups, while pg_trgm is designed for unanchored substring, regular-expression, and similarity searches.

Diagnostics and Configuration

Important inspection objects include biscuit_indexes, biscuit_status, biscuit_index_stats(oid), biscuit_index_memory_size(), biscuit_pending_list_stats(oid), and biscuit_pending_list_usage. The memory function reports the current backend’s session-local copy. total_pending_bytes is refreshed during VACUUM, so pending-list figures can lag live writes by up to one vacuum cycle.

  • biscuit.delta_compaction_slots defaults to 20000 and controls how many pending rows are tolerated before compaction. It is a privileged setting because raising it can increase reload work for other sessions.
  • biscuit.diag_scan_trace defaults to off and emits verbose per-scan candidate accounting. Enable it only for a focused reproducer.

Every backend lazily loads its own copy of an index and keeps it for the connection lifetime. A committed write invalidates other cached copies; their next access reloads the index rather than refreshing it incrementally. Size pools for this memory behavior and avoid interleaving frequent writes with latency-sensitive reads.

Live-index INSERT and UPDATE generate substantial WAL; monitor pg_wal, replication lag, and replication-slot retention, and consider a bounded max_slot_wal_keep_size. Bulk loading before index creation is substantially cheaper. VACUUM drains pending work but does not shrink the index; use REINDEX to reclaim index space.

Upgrade to 3.0.0

Version 3.0.0 is an incompatible on-disk format change. Updating the extension catalog does not convert existing index pages: every Biscuit index created under 2.x must be rebuilt. Plan enough maintenance time and WAL capacity for the rebuild.

ALTER EXTENSION biscuit UPDATE TO '3.0.0';

SELECT schema_name, index_name
FROM biscuit_indexes;

REINDEX INDEX CONCURRENTLY public.message_body_biscuit_idx;

The unpatched upstream 3.0.0 archive ships and installs only the 2.5.0--3.0.0 step, while earlier stable packages exposed catalog versions 2.4.0 or 2.4.1. Pigsty’s 3.0.0 RPM and DEB packages restore that missing catalog path before applying the upstream step. For another source build or package, inspect pg_extension_update_paths('biscuit') before ALTER EXTENSION; regardless of the available SQL path, the mandatory REINDEX or REINDEX CONCURRENTLY remains a separate manual operation.

Last updated on