The first version of any AI knowledge base ends with a metadata JSONB column.
It feels right. JSONB is flexible. Customers want to attach arbitrary fields to their documents — customer ID, priority, ARR bracket, region, "is internal." A JSON blob covers all of it, indexes are a GIN away, and the demo runs fast on 10,000 rows. Then the customer puts 5 million rows in and asks "find me every document where customer='ACME' and arr > 1000 and isInternal=true."
That query just turned into a sequential scan with three jsonb path expressions stacked on top of each other. The demo that ran in 80ms now runs in 8 seconds. Customers leave.
AACFlow uses a different shape. It is less flexible. It is 100 times faster.
JSONB Is Flexible. It Is Also Slow.
A metadata JSONB column is essentially "schema-on-read." Every query has to crack the blob, walk the JSON tree, and extract the fields it needs. A GIN index can help with key/value containment queries, but it doesn't help with range queries (>, <), it doesn't help with sort, and it doesn't help with composite filters across multiple keys.
Worse, the planner has no idea about the cardinality of because that statistic doesn't exist for synthetic JSONB paths. You can until your knees give out and Postgres still picks a plan that scans 4 million rows.



