Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Scout Postgres Laravel Package

pmatseykanets/laravel-scout-postgres

A PostgreSQL full-text search driver for Laravel Scout. Index Eloquent models with native tsvector and GIN indexes, run ranked searches, and paginate results using PostgreSQL's built-in search capabilities instead of external services.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • This is a drop-in Laravel Scout engine that implements Laravel\Scout\Engines\Engine on top of PostgreSQL native full-text search (tsvector, tsquery, ts_rank, GIN indexes). Architecturally it removes an entire hop: no Algolia/Meilisearch/Typesense cluster, no scout:import/queue-sync pipeline, no dual-write consistency problem. Searchable data is derived inside the same transactional store as the source rows.
  • Best fit is a Postgres-backed Laravel monolith where search is a secondary feature — catalog/product/name lookup, admin-side filtering, internal tools. It is a poor fit where relevance quality is the product (typo tolerance, synonyms, faceting/aggregations, multilingual stemming, vector/semantic search, per-result highlighting via API).
  • Ranking is ts_rank-based and dictionary-driven. Language configuration, stopwords, and stemming become product decisions that live in migrations, not in a managed search console — a real difference in who owns relevance tuning.
  • Because results are returned as Eloquent builders, Scout's where() constraints and existing scopes still apply. That is a significant simplicity win versus external engines, which require replicating filterable attributes.

Integration feasibility

  • Low mechanical effort: composer require, publish config, add a tsvector column (generated column on PG12+ or trigger-maintained), GIN index, backfill, set SCOUT_DRIVER=postgres. One model can be piloted in a day; a whole domain in a sprint.
  • The package is small (a driver, a service provider, a config file) — small enough that a fork is cheap if upstream is dead.
  • The real integration work is not the package, it is the schema: choosing the text source columns, concatenation/weighting (setweight A/B/C/D), dictionary, and index build strategy on large tables (build GIN concurrently, off-peak).

Technical risk

  • Primary risk: staleness. Last release 2021-01-06, 163 stars, effectively single-maintainer and dormant. Laravel has moved 8 → 11 and Scout 9 → 10 since; the Engine contract has changed (e.g. mapIds, lazyMap, paginate signatures, PHP 8.1+ type requirements). Expect to vendor/fork and patch method signatures as part of adoption, not as an afterthought.
  • Version coupling across four axes — Laravel, Scout, PHP, PostgreSQL — means the compatibility matrix is unverified. A spike is mandatory before committing.
  • tsvector has a hard 1 MB limit; oversized documents truncate silently and become partially unsearchable. Needs a guardrail on indexed text length.
  • Relevance is materially weaker than a dedicated engine: no typo/fuzzy matching, no synonyms out of the box, no faceting. If product expectations were formed on Algolia, this is a perceived regression even when it is technically adequate.

Key questions

  1. What are the pinned versions of Laravel, Scout, PHP, and PostgreSQL in production — and is Scout ≥10 in scope?
  2. Who owns the fork when a Scout upgrade breaks the engine contract? Is there an internal owner with PHP depth?
  3. What search quality bar exists today — is typo tolerance or faceting in the acceptance criteria?
  4. Read/write ratio and row counts for the searchable tables, and is there headroom on the primary, or a read replica available?
  5. Is multilingual content in scope, and which dictionaries must be installed?
  6. Are there raw-SQL or bulk-load write paths that would bypass trigger-maintained tsvector columns?

Integration Approach

Stack fit

  • Strong fit for a Postgres + Laravel stack with no existing search infrastructure, or where an external search SaaS is being retired for cost/complexity. Weak fit for polyglot or MySQL-only estates — there is no portability story here, the driver is Postgres-specific by design.
  • Eliminates third-party credentials, egress, vendor SLAs, and a class of "index drifted from database" incidents. That is the headline operational argument for a TPM.

Migration path

  • Typical origin states: (a) Algolia/Meilisearch via Scout — swap the driver, retire the external index; (b) hand-rolled LIKE/ILIKE queries — replace with Scout calls, gaining ranking and index-backed performance; (c) database Scout driver — like-for-like swap with better relevance.
  • Recommended path: publish config → per-model migration adding the text vector column and GIN index → backfill → feature-flag SCOUT_DRIVER per environment → pilot one model → expand model by model.
  • Rollback is clean and cheap: env-var flip back to the previous driver. Keep the old index populated during the pilot window, then decommission. No destructive schema change is required, only additive columns.
  • Decommissioning step is easy to forget: remove Scout queue workers and scheduled scout:import jobs when the external engine is dropped, otherwise dead jobs accumulate.

Compatibility

  • Treat as "adopt-and-fork": pin the package via a VCS/path repository, run a compatibility spike against the target Scout version, and patch the Engine implementation if signatures have drifted. Do not assume the 2021 release works on current Laravel.
  • Validate Postgres version for generated columns (PG12+) versus trigger-based maintenance; validate pg_trgm availability if prefix/substring matching is required alongside FTS.
  • Confirm behavior of Scout's paginate, take, raw, and where callbacks against the engine — these are the interfaces most likely to have shifted between Scout majors.

Sequencing

  1. Discovery spike (1–2 days): install, run against a scratch model on target versions, confirm Scout compatibility and measure relevance on a real query sample.
  2. Decide fork ownership and budget before, not after, the spike.
  3. Schema/migration design and index build rehearsal on staging-sized data.
  4. Single-model pilot behind a flag, with relevance evaluation against current behavior.
  5. Roll out remaining models; concurrently, harden query construction (websearch_to_tsquery/plainto_tsquery, never raw to_tsquery on user input).
  6. Decommission the prior engine and remove sync infrastructure.

Operational Impact

Maintenance

  • Code surface is small, so maintenance cost is low in absolute terms — but it is unowned upstream. Budget an explicit fork-maintenance line item: re-validate on every Laravel/Scout major, patch signatures, and keep a changelog. Realistically a few days per year, spiking around framework upgrades.
  • Relevance tuning (dictionaries, weights, stopwords) becomes internal work performed via migration and config changes rather than a vendor dashboard. Assign that to a named owner or it will rot.

Support

  • No vendor, no SLA, no upstream security response. MIT license means the fork is legitimate and safe legally; the support burden is entirely internal.
  • Onboarding cost is low: a Laravel developer reads the driver in an hour. The harder skill is reading EXPLAIN ANALYZE, understanding GIN index behavior, and diagnosing slow ranked queries — that is a DBA-ish competency the team should have or borrow.

Scaling

  • Postgres FTS with a GIN index handles millions of rows comfortably for typical application search. Limits appear as: index maintenance cost on write-heavy tables, CPU-heavy ranking on large result sets, and index bloat requiring VACUUM/REINDEX care.
  • Search load shares the OLTP database. At high query volume, route search to a read replica or accept contention with transactional traffic — a tradeoff an external engine would not impose.
  • No independent horizontal scaling of the search tier. If search QPS grows disproportionately, this architecture forces a re-evaluation (partitioning, replica, or a move back to a dedicated engine).

Failure modes

  • Missing or unused GIN index → silent sequential scans and latency cliffs under load.
  • Dictionary/config change without reindexing → inconsistent or stale relevance.
  • Documents exceeding the tsvector 1 MB cap → silently unsearchable fields; needs a length guardrail and monitoring.
  • Trigger-maintained vectors + bulk/raw writes → drift between row content and search vector.
  • Unsanitized user input into to_tsquery → syntax errors surfaced as 500s; use websearch_to_tsquery.
  • Orphaned Scout queue jobs after engine switch → background noise and false alarms.

Ramp-up

  • Day 1: install, configure, migrate one model, ship a flagged pilot.
  • Week 1: relevance evaluation, query sanitization, index verification, rollback rehearsal.
  • Week 2–4: remaining models, backfill on production-sized data, retire prior engine.
  • Ongoing: one named owner for fork maintenance and relevance tuning; team-wide awareness of the EXPLAIN-and-index basics.

TPM verdict: This is a high-leverage, low-blast-radius simplification for a Postgres-backed Laravel app whose search needs are "find the right row," not "beat Algolia." The dominant risk is not technical but organizational — an unmaintained 2021 package requires a named internal owner and an explicit fork budget before adoption. Approve as a spike-and-fork initiative, not as an unqualified dependency drop-in.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource