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

Ai Redis Store Laravel Package

symfony/ai-redis-store

Redis vector store integration for Symfony AI Store. Index and query embeddings with Redis Search, using FT.CREATE and FT.SEARCH commands, KNN vector search, and DIALECT 2 querying for fast similarity lookups.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • symfony/ai-redis-store is a store implementation, not a framework-agnostic library. It sits inside Symfony AI's StoreInterface contract and translates store operations into Redis Query Engine calls: FT.CREATE for index definition and FT.SEARCH with KNN + DIALECT 2 for similarity retrieval. That is a correct, narrow design — the abstraction is thin and the failure surface is Redis, not PHP.
  • For a Laravel codebase the fit is adjacent, not native. Laravel has no awareness of Symfony AI's container, bundle configuration, or service wiring. What is reusable is the contract and the Redis command construction, not the Symfony bootstrap. Two viable shapes:
    1. Bridge — pull symfony/ai-store (interfaces) plus this package via Composer, wrap instantiation in a Laravel service provider, and supply a Redis transport backed by Laravel's Redis facade (rawCommand on PhpRedis, executeRaw on Predis).
    2. Contract-only — depend on VectorDocumentInterface and reimplement the ~few-hundred lines of FT.CREATE/FT.SEARCH glue directly. The package's durable value is the document contract, not the command strings.
  • Do not let application code import Symfony store classes directly. Introduce a project-owned VectorStore interface and keep the Symfony package behind it. This is the single most important design decision: it makes the vendor package swappable and turns a potential framework lock-in into a replaceable adapter.
  • VectorDocumentInterface (v0.14) is the seam that makes the Laravel bridge tractable — a small, stable target (id, vector, metadata) rather than mapping into undocumented Symfony internals. It also makes a per-backend adapter strategy realistic later (Redis today, pgvector/Qdrant tomorrow) without touching feature code.
  • count capability (v0.14) is materially useful operationally: index-size and filtered counts without hydrating vectors. Maps to tenant quota enforcement, "N results" UX, and pre-flight guards before expensive KNN calls.

Integration feasibility

  • Composer-level risk is low. Laravel already ships a large set of Symfony components, so symfony/* coexisting is normal. Expect no class collisions; expect a version-constraint negotiation against symfony/ai-store if we are pinned to an older Laravel.
  • Framework-level risk is real. There is no laravel-ai-redis-store, no service provider, no config file, no package discovery, no published docs for Laravel. Everything from config to connection lifecycle is ours to write.
  • Transport is the fiddly part. Symfony's store expects a Symfony-flavored Redis client abstraction; Laravel gives us PhpRedisConnection/PredisConnection. Bridging them is a small but non-obvious adapter, and it is where most integration bugs will land (connection reuse, pipelining, error mapping, cluster routing).
  • Redis feature dependency is the true gate. We need the Redis Query Engine with vector search — Redis Stack 7.x, Redis 8, or a managed offering that exposes FT.CREATE/FT.SEARCH. Many managed Redis services (including several ElastiCache/Memorystore tiers and serverless variants) do not expose these commands. Verify against our actual target environment before writing code.

Technical risk

  • Maturity signal is weak. 1 star, 0 dependents, pre-1.0 (currently 0.14). Treat as unproven in production anywhere, regardless of the Symfony org affiliation.
  • Churn in minor releases. clear() arrived in v0.11; VectorDocumentInterface in v0.14. Both useful, both proof that the API surface is still moving. Pin exact minors and read changelogs before every bump.
  • Mitigant: upstream lives in the main symfony/ai monorepo with a real release cadence and review process, so abandonment risk is lower than the star count implies. The realistic risk is API drift, not project death.
  • Mitigant: the integration is genuinely small. If the package becomes a liability, replacing it with in-house FT.SEARCH code is days, not months — provided we kept it behind our own interface.

Key questions

  1. Which Redis deployment is the target, and does it actually support FT.CREATE/FT.SEARCH KNN? (Blocking.)
  2. Is this Redis instance shared with cache/session/queue data? If yes, stop — vector indexes need maxmemory-policy noeviction and a dedicated instance or logical separation.
  3. What is the tenancy model: index-per-tenant, shared index with metadata filters, or single-tenant for v1?
  4. What is the embedding model, dimension, metric (COSINE vs L2 vs IP), and index algorithm (HNSW vs FLAT)? These are baked into the index at FT.CREATE time and changing them means a full rebuild.
  5. Who owns index lifecycle — created at deploy time by a migration/command, or lazily at runtime? (Never lazily on a request path.)
  6. What is the corpus growth forecast over 12 months, and does it stay under ~1M vectors per index?
  7. Are we adopting Symfony AI broadly, or only borrowing this package's contract? The answer determines whether the adapter is a bridge or a reimplementation.
  8. What is the rollback plan if we need to leave Redis for vectors — is there a second adapter written and tested?

Integration Approach

Stack fit

  • Compatible, with glue. Laravel 10/11/12 on PHP 8.2+ with ext-redis (PhpRedis) or Predis. Symfony components are already in the dependency tree. Expect a clean composer require, then all the real work in our own app/VectorStore/ namespace.
  • Components we write (estimate ~200–400 LOC total, all unit-testable):
    • RedisVectorStoreServiceProvider — binds our interface to the Symfony store instance.
    • LaravelRedisTransportAdapter — implements the Symfony Redis client contract over Laravel's connection; rawCommand/executeRaw passthrough.
    • IndexSchemaProvisioner — an artisan command (vector:index:create|drop|info) so index DDL is a deploy step, not a request-time side effect.
    • VectorStore facade + config file (config/vector-store.php) sourced from env: connection name, index name, dimensions, metric, algorithm.
  • Do not expose Symfony types in controllers, jobs, or models. Code against a local VectorStore contract.

Migration path

  • Phase 0 — Spike (3–5 days). Stand up Redis Stack in Docker, composer require the package, prove FT.CREATE + KNN FT.SEARCH end-to-end from a Laravel command, with Laravel's Redis connection as transport. Deliverable: a go/no-go on transport bridging and a measured query latency on a 100k-vector synthetic corpus.
  • Phase 1 — Contract & adapter. Land the local VectorStore interface, the service provider, config, and the transport adapter. Contract tests (upsert / query / remove / clear / count) run against a containerized Redis in CI. Nothing in the app depends on the feature yet.
  • Phase 2 — Ingestion pipeline. Queued jobs (Horizon) for embed → upsert, with idempotent document IDs and batching. This is where most real-world complexity lives, and it is independent of the store package.
  • Phase 3 — Query surface. Semantic search / recommendations endpoint behind a feature flag, with count()-driven pagination or totals and a query timeout.
  • Phase 4 — Governance. Capacity dashboard from count(), per-tenant quota enforcement, alert thresholds.
  • Phase 5 — Portability rehearsal. Implement a second adapter (pgvector or Qdrant) behind the same interface for one non-critical read path. This is cheap insurance and validates that VectorDocumentInterface genuinely decouples us.

Compatibility

  • Redis: Redis Stack 7.2+ or Redis 8 (Query Engine bundled). DIALECT 2 is required for KNN — confirm the server version supports it.
  • PHP: 8.2+; pin symfony/ai-store and symfony/ai-redis-store to exact minors in composer.json, with a Renovate/Dependabot PR gate on changelog review.
  • Laravel: verify no illuminate/* version conflict on the Symfony component constraints; if there is, the fallback is Phase 0's "contract-only" shape, so the decision is never fully blocked.
  • Isolation: dedicated Redis database or instance for the vector index. No allkeys-lru eviction on a vector workload.

Sequencing rule Contracts → adapter → ingestion → query → observability → portability. Never invert the first two; the adapter behind a local interface is what makes every later decision reversible.

Recommendation to the steering group: approve as a bounded pilot (one feature, one index, ≤250k vectors) with an explicit 6-week review. The cost of trying is a few engineer-weeks; the cost of adopting broadly without the portability seam is a framework and vendor commitment we cannot unwind cheaply.

Operational Impact

Maintenance

  • Two maintenance surfaces, not one. Upstream (pin, watch changelogs, expect cadence at 0.x) and our own adapter (owns the Symfony↔Laravel bridge). The second is the larger burden and is entirely on us — budget ~10–15% of one engineer for the first two quarters, tapering to near zero once the interface is stable.
  • Keep the adapter thin and contract-tested. Every line we add there is a line upstream can break. Target under ~300 LOC with a test suite that runs against a real Redis container in CI.
  • Embedding model upgrades are the hidden maintenance cost. Changing dimension or metric requires dropping and rebuilding the index and re-embedding the entire corpus. Plan this as a versioned-index migration (docs_v1 → docs_v2, dual-write, cut over, drop old) rather than an in-place change.

Support

  • No Laravel community support. Issues go to the symfony/ai monorepo. Response quality will be good; response time is Symfony-volunteer-shaped, not SLA-shaped.
  • Escalation path is: our adapter → upstream issue → upstream PR. We should be prepared to carry a small patch if a blocker lands in a release window we cannot absorb.
  • Build in-house Redis vector expertise. One engineer who understands HNSW parameters (M, EF_CONSTRUCTION, EF_RUNTIME), memory sizing, and index rebuild mechanics. Without that person, the first capacity incident becomes an outage.

Scaling

  • Memory-bound, not CPU-bound. Vectors live in RAM. Sizing rule of thumb: vectors × dimensions × 4 bytes for float32, plus HNSW graph overhead (typically 30–60%), plus metadata and Redis overhead. Model this before committing to a corpus size.
  • Practical ceiling ~1M vectors per index without tuning; ~10M with sharding on Redis Enterprise or manual client-side partitioning. Beyond that, this is the wrong tool.
  • count() gives us the missing capacity primitive. Wire it into: a per-tenant quota check before ingest, a Prometheus/Grafana gauge for index size, and alert thresholds at 70% and 85% of projected ceiling. This turns capacity from a post-incident discovery into a leading indicator.
  • Read scaling via replicas is possible but introduces replication lag — semantic search results can be subtly stale. Decide the freshness tolerance per feature.
  • Ingestion throughput is bounded by the embedding provider, not Redis. Queue concurrency and provider rate limits will be the first bottleneck.

Failure modes

Failure Symptom Detection Mitigation
Vector module absent on target Redis FT.CREATE errors at deploy Deploy-time provisioner command fails fast Version check in vector:index:create; block deploy
Index schema mismatch (dimension/metric change) Errors on upsert, or silently wrong neighbors CI contract test + dimension assertion on boot Versioned index names; never mutate in place
Memory eviction of index data Missing results, corrupt-looking index Redis evicted_keys, INFO memory alarm Dedicated instance, noeviction policy
Shared instance with cache/session Key collisions, FT.SEARCH scanning unrelated keys Prefix discipline audit Separate DB/instance — non-negotiable
Unbounded KNN query p99 latency spikes Slow-query logging on FT.SEARCH LIMIT, TIMEOUT args, request-level query budget
Embedding provider outage Ingestion queue backs up, corpus goes stale Queue depth alert Backoff, dead-letter, staleness metric surfaced to users
Upstream breaking change in a minor bump Fatal errors after composer update Pinned versions + changelog PR gate Exact-version pins; adapter isolation limits blast radius
Replication lag on read replicas Stale search results post-ingest Consistency probe in staging Read-your-writes path to primary for critical flows

Ramp-up

  • Engineer ramp-up: ~2 weeks to productive contribution for a Laravel developer comfortable with Redis. Breakdown: 2–3 days on Redis Query Engine concepts (index definition, KNN syntax, DIALECT 2, HNSW parameters); 2–3 days on the Symfony AI store contract and this package's source (it is small — reading it is faster than finding docs); the rest on the transport adapter and CI harness.
  • No tutorial exists for this package in a Laravel context. Onboarding materials must be written by the adopting team — a one-page architecture note, the artisan commands, and the contract test suite as living documentation.
  • Organizational ramp-up is the longer tail: the team needs to internalize when this store is the wrong answer (corpus >1M, GPU needs, ACID requirements across vector and relational data, multi-tenant isolation without manual partitioning). Encode that as a documented decision record so the next team does not re-litigate it.
  • Onboarding exit criteria: the engineer can create/drop an index, explain why dimension changes force a rebuild, size a Redis instance for a given corpus, and articulate the portability path to a second backend. That is roughly a one-week checkpoint after the two-week ramp.
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.
andydefer/laravel-notification
adachsoft/cli-process-tester
jhaskell13/laraflow
sebastienheyd/boilerplate-media-manager
ccast/tagixo-primix
pretendtrue/laravel-builder
sawmainek/laravel-scout-tntsearch-driver
tomshaw/laravel-calendar-table
dibakar/laravel-ownership
steadrun/laravel-monitor
labyrinthe/connect-laravel
elmogy/layan
drewdan/sentinel-client
dskripchenko/laravel-llm
fatryst/nuonuo
stevenay/myanfont
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc