agentleFS
AnyOrgNameAnyOrgName/php-skills/skills/databases/redis/SKILL.md

redis

Skill4 starsChanged 4 months agoMITView on GitHub

Use Redis from PHP as a cache, session store, queue backend, and rate-limiter store — pick phpredis or predis, model data with the right structures, and tune persistence (RDB/AOF), eviction, and clustering for production. Use when the user wants to cache expensive query results, computed values, or fragments in memory to reduce database load and speed up responses; the user needs to choose or configure a Redis client for PHP — phpredis (the C extension) versus predis (pure PHP) — or connect PHP to a Redis server or cluster; the user wants to store sessions, rate-limiter counters, locks, or a queue backend in Redis, and needs the right data structure, expiry, and persistence. Keywords: redis, cache, caching, performance, sessions, rate-limiting, phpredis, predis, persistence, eviction, clustering, queue.

11 other projects use a version of this.

Adopted by

Most recently taken up by

Used with

Projects with it also use mysql, postgres and 5 more.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • planetscaleSkill

    mysql

    Plan and review MySQL/InnoDB schema, indexing, query tuning, transactions, and operations. Use when creating or modifying MySQL tables, indexes, or queries; diagnosing slow/locking behavior; planning migrations; or troubleshooting replication and connection issues. Load when using a MySQL database.

    Also in 3 projects that use this

  • digitalocean-labsSkill

    postgres

    Configure DigitalOcean Managed Postgres with bindable variables or schema isolation. Use when setting up databases, creating users, managing permissions, configuring multi-tenant schemas, or troubleshooting database connectivity on App Platform.

    Also in 3 projects that use this

  • VercelSkill

    aws

    Emulated AWS cloud services (S3, SQS, Cognito, IAM, STS) for local development and testing. Use when the user needs to interact with AWS API endpoints locally, test S3 bucket and object operations, emulate SQS queues and messages, test Cognito sign-up, sign-in, JWTs, or Identity Pools, manage IAM users/roles/access keys, test STS assume role, or work without hitting real AWS APIs. Triggers include "AWS emulator", "emulate AWS", "mock S3", "local SQS", "test IAM", "emulate S3", "AWS locally", "STS assume role", or any task requiring local AWS service emulation.

    Also in 3 projects that use this

  • VercelSkill

    react

    React renderer for json-render that turns JSON specs into React components. Use when working with @json-render/react, building React UIs from JSON, creating component catalogs, or rendering AI-generated specs.

    Also in 3 projects that use this

  • OpenAISkill

    observability

    Vercel Observability expert guidance — Drains (logs, traces, speed insights, web analytics), Web Analytics, Speed Insights, runtime logs, custom events, OpenTelemetry integration, and monitoring dashboards. Use when instrumenting, debugging, or optimizing application performance and user experience on Vercel.

    Also in 3 projects that use this

  • MicrosoftSkill

    api-design

    Guide for designing and documenting RESTful APIs. Use when asked to design an API, create endpoints, or document an API.

    Also in 3 projects that use this

The file

Show its rules and text

We split this skill into the rules it gives an agent

13 rules. 0 are common, 7 are distinctive, and 6 are very specific to this project.

  • 0

    Common

    Most of the 10 edited versions we read keep these.

  • 7

    Distinctive

    This author's own choices. Worth a look.

  • 6

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Do not use Redis as the primary durable store for records you cannot afford to lose.

    line 80
  2. Distinctive:

    Do not reach for Redis when the workload needs ad-hoc queries, joins, secondary indexes, or transactions across many rows.

    line 82
  3. Distinctive:

    Verify: A warm key returns from Redis and the database query is skipped.

    line 132
  4. Distinctive:

    Verify: Concurrent misses trigger one database load and the value is stored with a TTL.

    line 135
  5. Very specific:

    When the underlying record changes, DEL the cache key (or bump the key version) inside the same write path so the next read repopulates …

    line 136
  6. Distinctive:

    Verify: Updating the record makes the next read miss the cache and reload from the database.

    line 138
  7. Very specific:

    Verify: $redis->ping() returns true and the connection is persistent across requests.

    line 154
  8. Very specific:

    Verify: CONFIG GET maxmemory and maxmemory-policy return the intended values.

    line 157
  9. Very specific:

    Run a smoke test that writes and reads a TTL key, then check INFO for used_memory, evicted_keys, and connected_clients to confirm healthy …

    line 158
  10. Distinctive:

    Verify: The smoke key round-trips, expires on schedule, and INFO shows stable memory and client counts.

    line 160
  11. Very specific:

    Use RDB snapshots when a cache can tolerate losing the last few minutes on crash.

    line 167
  12. Very specific:

    When issuing many commands, batch them with a pipeline (multi(Redis::PIPELINE)) or multi-key ops like MGET/MSET instead of one blocking …

    line 172
  13. Distinctive:

    Not applicable — no I/O, auth, or untrusted input.

    line 233

“Common” is measured: kept by at least 6 in 10 of the 10 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md
<!-- generated: do not edit — source: knowledge/atoms/databases/redis/ --><!-- schema: atomVersion=3 skillVersion=2 graphVersion=1 --><!-- compile: @php-skills/compiler v1.0.0 (deterministic build) -->

Redis for PHP

When to use

  • The user wants to cache expensive query results, computed values, or fragments in memory to reduce database load and speed up responses.
  • The user needs to choose or configure a Redis client for PHP — phpredis (the C extension) versus predis (pure PHP) — or connect PHP to a Redis server or cluster.
  • The user wants to store sessions, rate-limiter counters, locks, or a queue backend in Redis, and needs the right data structure, expiry, and persistence.

When NOT to use

  • Do not use Redis as the primary durable store for records you cannot afford to lose; keep the source of truth in a relational or document database.
  • Do not reach for Redis when the workload needs ad-hoc queries, joins, secondary indexes, or transactions across many rows; use a relational database instead.

Core guidance

  • Prefer phpredis in production, predis when you cannot install extensions — Use the phpredis C extension for production throughput; fall back to predis (pure PHP) only when you cannot install PHP extensions, such as some managed hosts.
  • Set a TTL on every cache key — Give every cache entry an explicit TTL (SET key val EX 3600 or SETEX) so stale data expires and memory is reclaimed automatically.

Decision Engine

Walk this section before choosing an implementation path.

Can you install PHP C extensions on the host, and do you need horizontal scale
or high availability beyond a single Redis node?

├── Dataset or write load exceeds one node: → Redis Cluster — data sharded across nodes with hash slots; use hash tags to keep
related keys co-located and accept that multi-key ops must stay in one slot.

├── Can install extensions, single node is enough: → phpredis (C extension) against a single primary — the fastest, lowest-memory
client and the default choice for throughput on one node.

├── Cannot install extensions: → predis (pure PHP) — no extension to compile, easy to deploy on locked-down
managed hosts; accept lower throughput than phpredis.

└── Need failover but data fits one master: → Redis Sentinel with a primary/replica set — automatic failover and read
replicas while the dataset still fits one master's memory.

Full engine: references/decision-engine.md — Decision Tree, Priority Matrix, Decision Table.

Workflows

Workflow: Cache Aside

Progress:
- [ ] Compose a namespaced, versioned key (`user:v1:42:profile`) and `GET` it; on a hit,
decode and return the cached value without touching the database
- [ ] On a miss, take a short `SET lock NX EX` so only one worker recomputes, load from
the database, then `SET key value EX <ttl>` (add jitter) and release the lock
- [ ] When the underlying record changes, `DEL` the cache key (or bump the key version)
inside the same write path so the next read repopulates fresh data
  1. Compose a namespaced, versioned key (user:v1:42:profile) and GET it; on a hit, decode and return the cached value without touching the database.
    • Verify: A warm key returns from Redis and the database query is skipped.
  2. On a miss, take a short SET lock NX EX so only one worker recomputes, load from the database, then SET key value EX <ttl> (add jitter) and release the lock.
    • Verify: Concurrent misses trigger one database load and the value is stored with a TTL.
  3. When the underlying record changes, DEL the cache key (or bump the key version) inside the same write path so the next read repopulates fresh data.
    • Verify: Updating the record makes the next read miss the cache and reload from the database.

Workflow: Configure Client

Progress:
- [ ] Install the phpredis extension (`pecl install redis`), then in code `pconnect()`
to the host and `AUTH` if required, setting connect and read timeouts
- [ ] In redis.conf set `maxmemory` to a safe ceiling, choose `maxmemory-policy`
(allkeys-lru for cache), and set persistence (RDB save points and/or `appendonly yes`)
- [ ] Run a smoke test that writes and reads a TTL key, then check `INFO` for
used_memory, evicted_keys, and connected_clients to confirm healthy operation
  1. Install the phpredis extension (pecl install redis), then in code pconnect() to the host and AUTH if required, setting connect and read timeouts.
    • Verify: $redis->ping() returns true and the connection is persistent across requests.
  2. In redis.conf set maxmemory to a safe ceiling, choose maxmemory-policy (allkeys-lru for cache), and set persistence (RDB save points and/or appendonly yes).
    • Verify: CONFIG GET maxmemory and maxmemory-policy return the intended values.
  3. Run a smoke test that writes and reads a TTL key, then check INFO for used_memory, evicted_keys, and connected_clients to confirm healthy operation.
    • Verify: The smoke key round-trips, expires on schedule, and INFO shows stable memory and client counts.

Best practices

  • For a pure cache, set maxmemory and maxmemory-policy allkeys-lru (or allkeys-lfu); for a store mixing cache and durable keys, use volatile-lru so only keys with a TTL are eligible for eviction
  • Use RDB snapshots when a cache can tolerate losing the last few minutes on crash; enable AOF (appendonly yes, appendfsync everysec) when you need near write-durability; run both for fast restarts plus a durable log
  • Under PHP-FPM, open persistent connections with pconnect() (or a pool in long-running workers) so each request reuses a socket instead of a fresh handshake
  • When issuing many commands, batch them with a pipeline (multi(Redis::PIPELINE)) or multi-key ops like MGET/MSET instead of one blocking call per key

Anti-patterns

Anti-patternWhy it failsDo instead
Storing giant blobs or one huge collection in a single keyBig keys make every op on them slow and block the server, replication ships the<br>whole value, and eviction of one key can drop a large slice of state at once.Split large data into smaller keys or Hash fields, cap collection sizes, and keep<br>values small; store large binaries in object storage and cache only a pointer.
Opening a new connection per operationA fresh TCP connect plus AUTH per call adds latency and exhausts the server's<br>client limit under load, causing intermittent connection errors.Reuse a persistent connection with pconnect() under PHP-FPM, or a shared client<br>or pool in long-running workers, with sane connect and read timeouts.
Using Redis as the primary system of recordRedis is memory-first and can drop recent writes on crash depending on<br>persistence config; treating it as the source of truth risks silent data loss.Keep the durable record in a relational or document database and use Redis as a<br>cache or ephemeral store, rebuildable from the source of truth.

See references/anti-patterns.md.

Debugging

  1. Using KEYS in production blocks the server — Redis processes commands one at a time, so a full scan stalls all concurrent requests. Fix: Iterate with SCAN/HSCAN/SSCAN using a cursor and small COUNT, or maintain a purpose-built index Set instead of scanning at runtime.
  2. Cache keys without TTL leak memory — Redis never removes a key on its own without a TTL or an eviction policy that targets it. Fix: Always SET ... EX <seconds> (or SETEX) for cache data, and configure an eviction policy so keyless growth cannot OOM the instance.
  3. Non-atomic check-then-set races between requests — The gap between read and write lets a concurrent client change the value, corrupting locks and counters. Fix: Use atomic primitives — INCR/INCRBY for counters, SET key val NX EX for locks, or a Lua script via EVAL for multi-step logic that must be atomic.
  4. Mismatched serialization corrupts cached values — Redis stores opaque bytes, so writer and reader must agree on the encoding. Fix: Pick one serialization strategy per key namespace, set the phpredis serializer consistently, and version or prefix keys when you change the format.

Performance notes

  • Using KEYS in production blocks the server — Calling KEYS pattern* (or SMEMBERS on a huge set) scans the whole keyspace in one blocking pass, freezing the single-threaded server for every other client.
  • Cache keys without TTL leak memory — Writing cache entries with no expiry lets the keyspace grow without bound until Redis hits maxmemory and either evicts unpredictably or rejects writes.
  • Match the maxmemory-policy to the workload — For a pure cache, set maxmemory and maxmemory-policy allkeys-lru (or allkeys-lfu); for a store mixing cache and durable keys, use volatile-lru so only keys with a TTL are eligible for eviction.
  • Reuse connections with pconnect or a pool — Under PHP-FPM, open persistent connections with pconnect() (or a pool in long-running workers) so each request reuses a socket instead of a fresh handshake.
  • Prefer phpredis in production, predis when you cannot install extensions — Use the phpredis C extension for production throughput; fall back to predis (pure PHP) only when you cannot install PHP extensions, such as some managed hosts.
  • Pipeline or MGET batches instead of chatty round-trips — When issuing many commands, batch them with a pipeline (multi(Redis::PIPELINE)) or multi-key ops like MGET/MSET instead of one blocking call per key.
  • Set a TTL on every cache key — Give every cache entry an explicit TTL (SET key val EX 3600 or SETEX) so stale data expires and memory is reclaimed automatically.

Production checklist

  • Counters use INCR, locks use SET NX EX, and multi-step logic uses a Lua script rather than a read-modify-write race.
  • maxmemory is capped and an eviction policy (allkeys-lru or volatile-lru) is chosen, never the default noeviction for a cache.
  • Hot paths use SCAN or an index Set instead of KEYS, and no single key holds an unbounded blob or collection.
  • RDB and/or AOF are configured to match how much recent data the workload can afford to lose on restart.
  • The app uses pconnect or a pool with sane timeouts so it does not open a fresh socket per operation.
  • Every cache entry is written with an explicit TTL so stale data expires and memory is reclaimed.

Version notes

  • LFU eviction and phpredis serializers (PHP >=7.4) — allkeys-lfu/volatile-lfu eviction policies are available from Redis 4.0, and the phpredis igbinary serializer requires the igbinary extension; older Redis supports only LRU/random/ttl policies.
  • phpredis and predis both support PHP 7.4+ (PHP >=7.4) — phpredis 5.x and predis 1.1/2.x both run on PHP 7.4 and up; predis 2.x drops PHP 7.2 support, so pin predis 1.1 only if you must stay on very old PHP.

Security

  • Not applicable — no I/O, auth, or untrusted input.

Testing

  • Activation and decision behavior are verified in eval/scenarios/databases/redis.yaml.

Additional resources

  • references/anti-patterns.md
  • references/core.md
  • references/decision-engine.md
  • references/examples.md
  • references/pitfalls.md
  • references/recipes.md
  • references/version-differences.md

Knowledge graph

Related: audit/performance, audit/project-analysis, laravel/queues, security/rate-limiting

<!-- graph-fragment: graph/fragments/databases/redis.yaml -->

Skill contract

Produces: cache.redis-configured, infra.redis-connected
Risk: medium · Confidence: 0.9

<!-- contract-fragment: contracts/fragments/databases/redis.yaml -->

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.