directorytree/activeredis
ActiveRedis provides a simple, efficient, Eloquent-like active record API for interacting with Redis hashes in Laravel. Define models and create, update, delete, expire, and query records, with support for casts, events, timestamps, chunking, and searching.
Architecture fit
ActiveRedis promotes Redis from a cache/side-channel into a system of record for hash-shaped entities, wrapped in an Eloquent-shaped API. That is the central architectural decision, and it is only a good fit for a narrow class of domains:
setExpiry) and cheap hash writes.orderBy, no true limit, and no transactional boundary. Query semantics stop at "scan everything with this prefix and filter on a pre-declared searchable list."The secondary architectural risk is API-mimicry as a footgun. The façade is deliberately Eloquent-like (create, find, destroy, chunk, each, model events, observers, casts, booted). Engineers will pattern-match to Eloquent semantics and then discover there is no query planner, no where on undeclared attributes, and that chunk() sizes are non-deterministic per the README's own warning. That gap is where most production incidents on this package would originate.
Integration feasibility
Integration cost is low: one Composer package, no service mesh, no external infrastructure beyond Redis you likely already run. Requirements are PHP ≥ 8.1, Laravel ≥ 9.0, Redis ≥ 3.0 — a mainstream Laravel matrix. Setup is a model class, a dedicated connection entry in config/database.php, and a $searchable declaration.
The counterweight is evidence of adoption: 73 stars, 0 dependents, and effectively no third-party production validation to borrow. DirectoryTree is a recognizable Laravel vendor, so the risk is not "abandoned toy" so much as "single-maintainer, low-traffic package we will end up owning." MIT license means forking is a viable contingency. The listed last-release date (2026-07-09) should be verified against Packagist before scheduling work — treat any metadata anomaly as a signal to confirm the package is actively tagged rather than assume it.
Technical risk
Ranked by blast radius:
SCAN {cursor} MATCH visits:id:* COUNT {count}. COUNT is a hint, not a limit. Every full-collection read walks the keyspace of that logical database. On a shared Redis DB containing cache, sessions, and queues, this is both slow and dangerous — the README correctly mandates a dedicated connection, and that must be treated as a hard requirement, not advice.$searchable are maintained alongside the hash write. Absent an atomic Lua script (not documented), a failure between the HSET and the index update leaves records that exist but are unfindable — or findable but deleted. This requires an owned reconciliation job.DuplicateKeyException and offers force: true to "ignore the exception and delete the existing record." That is a destructive primitive masquerading as an idempotency helper, and it should be banned or heavily reviewed in application code.: and * are forbidden in keys and in searchable attribute values. Nothing in Redis enforces this — it must be validated at the application boundary or key parsing silently corrupts.SCAN is per-node, and the key scheme has no hash tags, so a cluster deployment breaks the "scan the whole model" assumption. Equally, a primary-store Redis must not run maxmemory-policy allkeys-lru — the standard cache configuration will silently evict system-of-record data under pressure.Key questions for the package owner / architecture review
Stack fit
Reasonable if and only if: Laravel 9+ (ideally 10/11/12 — verify the CI matrix covers our version), PHP 8.1+ runtime already in place, Redis already operated with monitoring, and a dedicated logical database or dedicated instance can be allocated. If Redis is treated as shared, best-effort cache infrastructure today, the fit is poor and the org-level work to promote it to a durable store should be scoped as a prerequisite, not a follow-on.
Migration path
Do not migrate existing Eloquent entities. Adopt greenfield, in one bounded context, chosen for ephemerality and low query complexity. Recommended pilot candidates: request/visit telemetry with TTL, one-time tokens, or ephemeral per-user UI state. Explicitly exclude anything finance, support, or compliance will query ad hoc.
Compatibility
composer outdated review gate and a documented fork procedure.Sequencing
$key, $searchable, and reserved-character validation rules documented before any production write. This is the single most expensive decision to reverse.noeviction or volatile-* policy, memory ceiling and alerting, backup/restore rehearsal.force: true code-review prohibition, TTL defaults.Maintenance
Assume we own this. Cadence appears low, the license permits forking, and the realistic steady-state cost is modest — a base model, a reconciliation job, and a schema doc — but it is our cost, not a vendor's. Budget roughly 0.1–0.2 FTE ongoing plus a named owner for the key/index conventions. Two maintenance obligations are non-obvious and should be written into the runbook: secondary-index reconciliation, and reserved-character validation on every new searchable attribute.
Support
Community-only: GitHub issues, no commercial backing, bus factor of one. There is no SLA and no meaningful peer-support corpus at this adoption level (73 stars, 0 dependents). Escalation plans must be internal: reproduce, patch, vendor-fork. This is acceptable for a bounded, non-critical domain and unacceptable for anything on a revenue or compliance path.
Scaling
Scaling is governed by key count and memory, not by request volume. Small hashes are memory-inefficient in Redis, so cost per record is higher than intuition suggests. Every read is a keyspace walk, so adding records degrades reads for all consumers of that instance, including cache and queue workloads. Mitigations: mandatory TTLs on every model, per-model prefixes so scans stay narrow, alerting on keyspace size growth rate, and a hard cap with a documented archival path. Horizontal scaling is constrained — Cluster shards the keyspace and breaks full-collection SCAN semantics, so "add nodes" is not a real answer without re-architecting the query layer.
Failure modes
allkeys-lru → primary data disappears with no error. Highest severity, easiest to prevent, easiest to forget.find() works but query() misses records, or vice versa. Degrades quietly; requires scheduled reconciliation to detect.force: true → an intended idempotency guard deletes a live record under a genuine race.: or * become unparseable or match unintended patterns; corrupt in a way that is hard to trace back.Ramp-up
Low to learn, deceptively low. A Laravel engineer is productive in under a day, which is precisely the risk: the API invites Eloquent assumptions. Counter with a one-hour onboarding session and a review checklist covering the four things the façade hides — no relations, no ordering/pagination, no transactions, frozen searchable schema. Budget 1–2 engineer-days including the ADR, and treat the checklist as the real deliverable.
How can I help you explore Laravel packages today?