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 Cache Memory Laravel Package

sanchescom/laravel-cache-memory

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. sanchescom/laravel-cache-memory is a cache store backed by a host-local shared-memory segment, exposed through the standard Laravel Cache contract. Release 2.1.0 materially changes what it is for: prior to this version it was a fast-but-approximate store (non-atomic add() with TTL was emulated with get() + put()); it is now a correct single-host coordination primitive. Atomic add() (semaphore-guarded, false on live entry, verified by a 16-process × 50-key × 6-round fork test) plus a real LockProvider (Cache::lock() with owner-checked releaseLock() in one critical section, verified by 16 processes × 20 non-atomic RMWs landing on exactly 320) means the package can host idempotency keys, rate limiters, "first writer wins" elections, and mutexes — not just read-through caching. The architectural constraint is unchanged and absolute: coordination is per-host, per-segment. It is a fit for single-node apps, php-fpm workers on one box, CLI/batch jobs that must serialize against each other, and test suites; it is not a fit for any horizontally scaled, multi-node, or multi-tenant-by-node topology where Redis/DB would be the correct answer.

Integration feasibility. Low effort, high leverage. It is a drop-in store driver: composer require, register the store in config/cache.php, point the relevant cache at it. The 2.1.0 additions require no new application code to take effect — Cache::add() with TTL becomes atomic for free on this driver with return semantics unchanged, and Cache::lock() begins working wherever the store is used as the lock backend. The interesting integration surface is therefore not "can we install it" but "which code paths should now point at it," which is a config-and-ownership question, not an engineering one.

Technical risk.

  • Namespace collision is the headline risk. Lock names share the key space with cache keys, and flush(), requestDeletion(), and the overflow path discard held locks along with the data. Any code that flushes the store — deploy hooks, cache-clear endpoints, test teardown, an overflow — silently releases mutexes other processes believe they hold. This is the same semantic as every Laravel cache-backed lock, but on a small fixed-size segment, overflow is a realistic trigger, not a theoretical one.
  • Overflow is destructive and only warned about. The overflow path empties the store and raises E_USER_WARNING; 2.1.0 correctly makes add() return false so MemoryLock::acquire() cannot report a lock it does not hold even when the warning is masked. That is the right fix, but it converts an availability problem into a correctness-preserving failure — work still stops.
  • refresh() is unsupported. Any job that extends a lock's TTL mid-flight (long-running imports, queue workers, report generation) will behave differently here than on Redis. This needs a code audit, not an assumption.
  • Capacity is fixed and must be sized deliberately. stats() and memory:stats now give visibility (segment key, usable capacity, bytes used/free, item count, expired count, read under the lock without purging) — but they are observability, not autoscaling.
  • No breaking changes in 2.1.0, which lowers upgrade risk; the risk profile is dominated by the capability itself, not the version bump.

Key questions.

  1. Which PHP extension(s) does the driver bind to for the segment and semaphore, and are they present in every target image (local Docker, CI runner, staging, prod php-fpm, CLI/cron containers)?
  2. What is the configured segment size, and what is the expected working set (cache keys + lock keys) at peak? Who owns that number?
  3. Which existing code paths call Cache::flush() / cache:clear against this store, and what holds locks at those moments?
  4. Does any lock in the codebase rely on refresh()? Which jobs, and what is their max runtime versus lock TTL?
  5. Is the same segment key ever used by two applications or two environments on the same host?
  6. Under Laravel Octane or a persistent worker, what is the segment lifecycle across worker restarts and graceful reloads?
  7. What is the expected behavior when a lock is lost to overflow — retry, fail fast, or alert?
  8. Is the package's maintainer bandwidth and test posture (forked contention tests are a good signal) sufficient for a coordination-critical dependency?

Integration Approach

Stack fit. Best fit: single-host Laravel deployments with php-fpm plus CLI workers sharing one machine, where the alternative is installing/maintaining Redis purely for locking and rate limiting. Also a strong fit for test suites and CI, where per-process isolation and memory:stats make contention behavior inspectable. Poor fit: multi-node clusters, serverless/ephemeral containers, anything where a lock must be visible across hosts.

Migration path. Two independent tracks:

  1. Version upgrade (2.0.0 → 2.1.0): composer update sanchescom/laravel-cache-memory. No breaking changes per the release notes and UPGRADE.md. Verify the existing store config still boots and that add()-with-TTL callers tolerate the now-genuinely-atomic semantics (they should — return semantics are unchanged) and the new false on overflow-discarded writes.
  2. Capability adoption (new): move Cache::lock() consumers from the default lock driver to this store, and route idempotency keys through Cache::add(). This is a behavioral change for the application even though it is not a change to the package's API, so it needs its own rollout.

Compatibility. Confirm the Laravel and PHP versions in use are supported by 2.1.0, and confirm extension availability in every runtime image. Explicitly document the known deltas versus other drivers in an internal note: refresh() unsupported; locks share the key space with cache entries; flush() and overflow release locks.

Sequencing.

  1. Upgrade the package in a non-production environment; confirm store boot, memory:stats output, and segment key/capacity settings.
  2. Instrument: schedule memory:stats (or call stats()) into existing monitoring so used/free bytes, item count, and expired count are visible before load changes.
  3. Size the segment against observed peak usage plus headroom; treat this as a config value under change control.
  4. Adopt atomic add() first — lowest risk, no API change, immediate correctness win for idempotency keys and rate limiting.
  5. Adopt Cache::lock() on one low-blast-radius path with a short critical section (a scheduled command, a single job type), with a contention test.
  6. Audit and remediate refresh() usage and flush()-during-lock-hold before widening lock adoption.
  7. Expand to remaining lock consumers; retire any bespoke file-lock or DB-lock shim.

Operational Impact

Maintenance. Small, focused dependency with a credible correctness story (forked contention tests for both add() and lock mutual exclusion are exactly the evidence a TPM wants). The maintenance burden shifts to us in two places: segment capacity sizing, and keeping the lock-vs-cache key namespace discipline. Both are config and code-review items, not ongoing engineering. Pin the version and review changelogs on release; the 2.1.0 note that add() returns false on overflow is the kind of subtle semantic change worth reading for every time.

Support. No vendor support; community package. Internal ownership should sit with whoever owns the cache/queue infrastructure. Because the failure modes are host-local, debugging is straightforward — memory:stats gives a direct read on capacity pressure without purging, which is a genuine support improvement over 2.0.0. Escalation path is "read the segment stats, check for overflow warnings, check for flush events," which is a short runbook.

Scaling. Strictly vertical and per-host. Throughput scales with cores and segment size on a single box; it does not scale out at all, and it does not degrade gracefully — it hits a capacity wall (overflow, store emptied, warning raised). Growth plan must be explicit: when the app needs a second node, the locking layer must move to Redis/DB before the second node lands, not after. Locking correctness and horizontal scaling are mutually exclusive here.

Failure modes.

  • Segment overflow → store emptied, E_USER_WARNING, add() returns false, locks released, cache cold. Correct-by-design in 2.1.0 (no phantom locks) but user-visible as a thundering herd plus lost mutexes. Primary mitigation: capacity headroom plus alerting on used/free.
  • flush() / requestDeletion() during a held lock → silent mutex loss. Mitigation: forbid blanket flushes on this store; scope clears by key.
  • Expired lock re-acquired, old holder releases → prevented by 2.1.0's owner-checked releaseLock() in a single critical section. This is the release's most valuable operational property; it removes a class of double-release corruption.
  • Unsupported refresh() → lock expires mid-job, concurrent execution. Mitigation: audit and cap job runtime below lock TTL.
  • Missing extension / wrong image → store fails to initialize; caught at deploy if staging matches production images.
  • Worker/container restart → segment lifecycle ends; all locks and cache entries vanish. Acceptable for locks with TTLs, but any code assuming lock durability across restarts is wrong.

Ramp-up. Low for developers — it is the standard Cache facade, and Cache::lock() now "just works," so there is little new API to learn. The ramp-up that matters is conceptual and should be a short written note in the team's docs: this store is per-host; locks share the key space with data; overflow and flush release locks; refresh() is unsupported; check memory:stats before debugging. Roughly a half-day of onboarding plus the refresh() audit. The most likely adoption mistake is treating this as a Redis substitute rather than as a single-host coordination primitive.

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.
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator