jobs table current in your database. With the indexes below, plain SQL over that table can serve a job board’s search page. To set up the feed, start with the Postgres, Supabase or Bolt destination guide.
Turn on the indexes
When you create the feed, tick the searches you run under Indexes in step 3, Where jobs land. On an existing feed, open its Settings tab and find Indexes under Connection and data. Jobo adds the indexes on the next sync without blocking reads or writes, and removes any you untick.
Each index uses disk space and slows writes a little, so tick only what your page uses.
Feeding a table you created yourself? Jobo adds the indexes only when its database user owns the table. Otherwise the Indexes panel shows the
CREATE INDEX SQL to run as the table’s owner, and the queries below work the same with your column names.
Keyword search with filters, newest first
Postgres combines the indexes it needs, so you can stack filters freely. Each line’s comment names the index it uses.websearch_to_tsquery accepts what people type into a search box: nurse -travel, "night shift", nurse or midwife. Word forms match too, so nurse also finds nurses.
Job type values are the ones shown on the job:
employment_type:Full-time,Part-time,Contract,Internship,Freelance,Temporaryworkplace_type:Remote,Hybrid,On-site
Rank by relevance
The index finds matches but can’t rank them.ts_rank re-reads the whole description of every match, so ranking a broad search like sales across a large table takes seconds. Rank on the title instead, which stays fast because titles are short. Jobs whose title matches come first, then jobs that match only in the description, newest first:
Title search as you type
Keyword search matches whole words. To match part of a title as someone types (engin finding Software Engineer), tick Title search and useILIKE:
pg_trgm extension. Jobo never installs extensions; if your database lacks it, the Indexes panel says so. Run this once as a database owner, and the index builds on the next sync:
% keeps titles that are similar enough, and similarity ranks them:
The other filters
hourly, daily, weekly, monthly and yearly.
Location, company, skills and occupation filters match exact values inside the JSON. {"city": "Berlin"} matches a job in Berlin, but not “berlin” or “Berlin, Germany”.
Occupation
The JSONBoccupation column holds each job’s occupation, or NULL for a job that isn’t classified. Jobo adds the column to tables it created on the next sync. Rows written before then stay NULL until the job is delivered again or you run a full resync.
- Unlike the API filters, these comparisons are case-sensitive. Use the category and subcategory exactly as they appear on the job (
Healthcare, nothealthcare). - Filter one occupation by its
id, never itsname: names can improve over time, IDs don’t.GET /api/occupationslists every value. - For speed on a large table, tick Occupation under Indexes and write the filters with
@>as above.occupation->>'id' = '…'can’t use the index. - On a table you created yourself, map occupation to a
jsonbcolumn.jsonandtextcolumns can’t hold this index.
jobs_occupation_idx, drop it once Jobo’s is ready. Two identical indexes only slow down writes.
Paging
Page from the last row you showed, not withOFFSET. OFFSET 10000 still reads the 10,000 rows it skips; this reads only the next page.
ORDER BY date_posted DESC, id DESC exactly as written:
- Most jobs have a posting date without a time of day, so thousands can share one
date_posted. Theidbreaks those ties, so no job is skipped or shown twice. - The Newest jobs first index includes
id, so each page reads only its 20 rows. date_posted IS NOT NULLkeeps jobs without a posting date from crowding the top of a newest-first list.
Filter counts
Counts like “Remote (1,234)” are aGROUP BY over the same WHERE clause as the results:
Pull only what changed
To keep a cache or second system current, fetch the jobs that changed since your last run. Tick Recently changed to make this fast.When to use a search engine instead
Postgres with these indexes suits a search page over up to a few hundred thousand jobs. If you need any of the following, add an Elasticsearch, Algolia or Meilisearch outbound feed alongside this one:- Typo tolerance across descriptions (title search above covers titles only)
- Instant filter counts across millions of jobs
- Radius search, such as “within 50 km of Berlin”
- Search tuned per language (keyword search here stems every job as English)

