pg-jev adds natural-language conditions to PostgreSQL queries by sending row data to a decision model. It can filter, rank and classify without creating embeddings. Its batching and read-ahead also mean that three returned rows are not necessarily three evaluated rows. Use explicit spend guards rather than treating LIMIT as a billing boundary.

The project documentation describes an ordinary SQL function: jev(row, condition) returns a boolean, while jev_prob exposes the probability used for ranking or threshold selection. The model judges supplied data; it does not generate a replacement SQL query. Exact dates, arithmetic and identifiers can remain ordinary database operations.

A small result can require a larger scan

The execution guide describes batches of 20 rows and asynchronous read-ahead. Up to twice the configured concurrency can be in flight. With the default concurrency of 16, that is a window of up to 32 requests, each potentially containing 20 rows. Multiplication gives a possible 640-row request window, not a fixed charge for every query.

If qualifying rows are rare, the database may need to inspect many candidates before finding three matches. Work already submitted can also extend beyond the point at which the executor has enough results. The number returned, number evaluated and number sent should therefore be separate counters. Lower concurrency can narrow outstanding work, but may also reduce throughput; it cannot make rare matches appear earlier.

Ranking adds another distinction. To return the three highest-probability rows from a candidate set, the system generally needs scores for that set. An early exit after finding three acceptable rows answers a different question from finding the best three. Choose the query’s semantics before trying to optimize its cost.

Bound model work explicitly

The settings reference provides jev.max_rows_per_statement and jev.max_chars_per_statement. Both default to zero, meaning disabled. They abort a statement that would send too much data; they do not silently return an exhaustive answer from an incomplete scan.

For an installation already configured with an approved endpoint, a documentation-based starting point is:

SET jev.max_rows_per_statement = 2000;
SET jev.max_chars_per_statement = 500000;
SET statement_timeout = '30s';

SELECT id, subject,
       jev_prob(v, 'the customer explicitly threatens to cancel') AS p
FROM ticket_for_jev AS v
ORDER BY p DESC
LIMIT 3;

SELECT jev_stats();

This assumes ticket_for_jev is an approved view containing only necessary fields and candidates. It is an example, not an EyesTech execution log. The large-table guide recommends shrinking the input with indexed filters and reducing row width. A 2,000-row ceiling is a workload policy, not a model accuracy setting.

Do not infer execution order merely from placing a cheap predicate before jev() in the text. PostgreSQL’s expression evaluation rules explain that boolean expressions can be reorganized. Inspect the plan and request counters; when a strict candidate boundary matters, prepare an approved candidate relation before model evaluation. Avoid using a billing API as a harmless probe of a query plan.

Cache reuse is tied to a backend session

The current repository warns that answers accumulate for unique row-content and question pairs in the backend session. jev.max_prefetch_rows limits aspects of read-ahead, not the entire answer cache or total memory. Changing the threshold can reuse an existing probability, while a new question creates different work.

A connection pool makes that behavior less obvious. Two clients can reuse one backend’s warm state, while identical queries on separate backends can populate separate caches. The caveats page says jev_cache_clear() affects the current session. Compare fresh-session and warm-session performance, and include cache clearing or session termination in the operating policy for large, changing datasets.

Local endpoints change the bill, not the SQL semantics

The extension’s host requirements list PostgreSQL 14–17, plpython3u and superuser installation. Managed hosts withholding those capabilities cannot run this extension as documented. This is a server dependency, not something an analyst can solve with a client-side SQL command.

The local-server guide permits a Jev-compatible endpoint in place of TypeSafe. Keyless local operation requires version 0.2.1 or later. Requests originate from the database server, so loopback refers to that server or container. The displayed cost estimate still uses TypeSafe’s list price; on a local endpoint it is not an invoice for local compute.

Before adopting either endpoint, label a sample of real rows, choose the condition and threshold against those labels, and inspect borderline probabilities. Structured output removes text parsing, but does not establish that the classifications are correct. The useful deployment record combines accuracy, rows sent, request count, memory growth and endpoint provenance—not just the number of rows printed by SQL.

Prepared with AI assistance from primary project and PostgreSQL documentation. Cover: AI-generated conceptual illustration. EyesTech did not execute the sample query or independently benchmark the extension.

Last Update: October 13, 2026