{"id":1592,"date":"2025-11-09T21:07:09","date_gmt":"2025-11-09T18:07:09","guid":{"rendered":"https:\/\/www.dchost.com\/blog\/never-lose-your-cache-again-high%e2%80%91availability-redis-for-wordpress-with-sentinel-aof-rdb-and-real-failover\/"},"modified":"2025-11-09T21:07:09","modified_gmt":"2025-11-09T18:07:09","slug":"never-lose-your-cache-again-high%e2%80%91availability-redis-for-wordpress-with-sentinel-aof-rdb-and-real-failover","status":"publish","type":"post","link":"https:\/\/www.dchost.com\/blog\/en\/never-lose-your-cache-again-high%e2%80%91availability-redis-for-wordpress-with-sentinel-aof-rdb-and-real-failover\/","title":{"rendered":"Never Lose Your Cache Again: High\u2011Availability Redis for WordPress with Sentinel, AOF\/RDB, and Real Failover"},"content":{"rendered":"<div class=\"dchost-blog-content-wrapper\"><p>So, a quick story. A few summers ago, I was babysitting a WooCommerce sale that was going way too well. The site was humming, Redis was happy, and the object cache was doing its thing\u2014until the primary Redis process quietly vanished in the middle of a promo push. Suddenly, what felt instant started dragging. Queries that used to come from memory were heading to the database, and the admin bar felt like it had weights strapped to it. Nothing exploded, but you know that moment when you can feel the crowd gathering and the stack turning red? That. We survived, but that night I promised myself I\u2019d never run a single Redis node for WordPress again. Not without a plan.<\/p>\n<p>In this guide, I want to share that plan. Let\u2019s talk about high\u2011availability Redis for WordPress object caching\u2014the kind with Sentinel watching your back, AOF\/RDB persistence keeping your data safe, and automatic failover that actually works. I\u2019ll walk you through what to expect, the bits that really matter in production, and the tiny choices that save you during weird 2 a.m. incidents. Think of it like a conversation with a friend who\u2019s already fallen into the ditch you\u2019re trying to avoid.<\/p>\n<div id=\"toc_container\" class=\"toc_transparent no_bullets\"><p class=\"toc_title\">\u0130&ccedil;indekiler<\/p><ul class=\"toc_list\"><li><a href=\"#What_High_Availability_Redis_Really_Means_for_WordPress\"><span class=\"toc_number toc_depth_1\">1<\/span> What \u201cHigh Availability Redis\u201d Really Means for WordPress<\/a><\/li><li><a href=\"#Redis_Sentinel_The_Quiet_Hall_Monitor_That_Saves_Your_Evening\"><span class=\"toc_number toc_depth_1\">2<\/span> Redis Sentinel: The Quiet Hall Monitor That Saves Your Evening<\/a><\/li><li><a href=\"#Automatic_Failover_for_WordPress_The_Plugin_Needs_to_Know_Where_the_Primary_Is\"><span class=\"toc_number toc_depth_1\">3<\/span> Automatic Failover for WordPress: The Plugin Needs to Know Where the Primary Is<\/a><\/li><li><a href=\"#AOF_and_RDB_Persistence_That_Makes_Restarts_Boring\"><span class=\"toc_number toc_depth_1\">4<\/span> AOF and RDB: Persistence That Makes Restarts Boring<\/a><\/li><li><a href=\"#Replication_and_Topology_Keep_It_Simple_and_Quorum-Friendly\"><span class=\"toc_number toc_depth_1\">5<\/span> Replication and Topology: Keep It Simple (and Quorum-Friendly)<\/a><\/li><li><a href=\"#The_WordPress_Layer_Behavior_Timeouts_and_Edge_Cases\"><span class=\"toc_number toc_depth_1\">6<\/span> The WordPress Layer: Behavior, Timeouts, and Edge Cases<\/a><\/li><li><a href=\"#Testing_Failover_Without_Breaking_a_Sweat\"><span class=\"toc_number toc_depth_1\">7<\/span> Testing Failover Without Breaking a Sweat<\/a><\/li><li><a href=\"#Operational_Habits_The_Stuff_That_Prevents_2_am_Surprises\"><span class=\"toc_number toc_depth_1\">8<\/span> Operational Habits: The Stuff That Prevents 2 a.m. Surprises<\/a><\/li><li><a href=\"#Docker_Compose_Example_A_Minimal_HA_Playground\"><span class=\"toc_number toc_depth_1\">9<\/span> Docker Compose Example: A Minimal HA Playground<\/a><\/li><li><a href=\"#Application_Behavior_During_Failover_What_Users_Feel\"><span class=\"toc_number toc_depth_1\">10<\/span> Application Behavior During Failover: What Users Feel<\/a><\/li><li><a href=\"#Common_Gotchas_I_Keep_Seeing_and_How_to_Dodge_Them\"><span class=\"toc_number toc_depth_1\">11<\/span> Common Gotchas I Keep Seeing (and How to Dodge Them)<\/a><\/li><li><a href=\"#Security_and_Access_Keep_Redis_Behind_a_Friendly_Fence\"><span class=\"toc_number toc_depth_1\">12<\/span> Security and Access: Keep Redis Behind a Friendly Fence<\/a><\/li><li><a href=\"#Reality_Check_When_to_Scale_When_to_Rethink\"><span class=\"toc_number toc_depth_1\">13<\/span> Reality Check: When to Scale, When to Rethink<\/a><\/li><li><a href=\"#A_StepbyStep_First_Deployment_You_Can_Try_This_Week\"><span class=\"toc_number toc_depth_1\">14<\/span> A Step\u2011by\u2011Step \u201cFirst Deployment\u201d You Can Try This Week<\/a><\/li><li><a href=\"#Useful_Reading_If_You_Want_to_Go_Deeper\"><span class=\"toc_number toc_depth_1\">15<\/span> Useful Reading If You Want to Go Deeper<\/a><\/li><li><a href=\"#WrapUp_Make_Redis_Failover_the_Most_Boring_Thing_You_Do\"><span class=\"toc_number toc_depth_1\">16<\/span> Wrap\u2011Up: Make Redis Failover the Most Boring Thing You Do<\/a><\/li><\/ul><\/div>\n<h2 id=\"section-1\"><span id=\"What_High_Availability_Redis_Really_Means_for_WordPress\">What \u201cHigh Availability Redis\u201d Really Means for WordPress<\/span><\/h2>\n<p>When we say high availability, we\u2019re not chasing some academic ideal. We\u2019re solving one practical problem: if the Redis primary dies, your site should keep serving cached content within seconds\u2014without your team sprinting to the terminal. That\u2019s it.<\/p>\n<p>WordPress uses Redis as an object cache: query results, transients, and bits of computed state. It\u2019s like a super\u2011fast notebook your site keeps nearby so it doesn\u2019t need to ask the database every little thing. On a quiet day, you might barely notice it. On a busy day, it\u2019s the difference between a checkout that feels instant and one that feels like a spinning wheel.<\/p>\n<p>But here\u2019s the thing\u2014Redis is typically just one process. If that one process gets lonely and leaves, your cache disappears. Your site falls back to the database. That\u2019s not the end of the world if traffic is light. During a sale, though? That\u2019s the sound of your database sweating.<\/p>\n<p>High availability for Redis boils down to three ideas: replication (so there\u2019s always another node ready), <strong>Sentinel<\/strong> (to watch, decide, and promote a new primary), and <strong>persistence<\/strong> (AOF\/RDB) so that restarts don\u2019t wipe your in\u2011memory world. Wrapped together, this is how you get automatic failover that feels almost boring\u2014exactly the kind of boring you want.<\/p>\n<h2 id=\"section-2\"><span id=\"Redis_Sentinel_The_Quiet_Hall_Monitor_That_Saves_Your_Evening\">Redis Sentinel: The Quiet Hall Monitor That Saves Your Evening<\/span><\/h2>\n<p>I like to think of Sentinel as the hall monitor who never sleeps. It watches your Redis primaries and replicas, coordinates who\u2019s alive, and, when the time comes, it promotes a replica to primary. The magic is that Sentinel runs as a separate process and forms a small fleet\u2014usually three nodes is a sweet spot\u2014so decisions aren\u2019t left to one opinionated machine.<\/p>\n<p>In practice, here\u2019s what you do: you set up one Redis primary and at least one replica. Then you run Sentinel on a few nodes (they can sit alongside Redis or on separate tiny instances). Sentinel tracks the primary using a name like <strong>mymaster<\/strong>. When the primary goes offline for long enough, Sentinel holds a quick election and tells a replica to take over. It also tells your clients\u2014like WordPress\u2014where the new primary lives. That last part is critical: WordPress shouldn\u2019t be hard\u2011coded to a single host; it should ask Sentinel for the current primary.<\/p>\n<p>Sentinel isn\u2019t fancy to configure. Here\u2019s a tiny taste of what a <code>sentinel.conf<\/code> might look like for the basics:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">port 26379\nsentinel monitor mymaster 10.0.0.10 6379 2\nsentinel down-after-milliseconds mymaster 5000\nsentinel failover-timeout mymaster 60000\nsentinel parallel-syncs mymaster 1\n<\/code><\/pre>\n<p>That quorum value at the end of the monitor line (here it\u2019s 2) is the minimum number of Sentinels that must agree the primary is down. If you run three Sentinels, a quorum of two is typical. If there\u2019s a flaky network, that number protects you from random split-brain problems. And no, you don\u2019t need to overcomplicate this\u2014just run three Sentinels, keep their clocks sane, and don\u2019t run them all on the same host.<\/p>\n<p>If you want to go deeper into the official fine print, the Redis team has a helpful breakdown of how Sentinel sees the world at <a href=\"https:\/\/redis.io\/docs\/latest\/operate\/redis\/sentinel\/\" rel=\"nofollow noopener\" target=\"_blank\">the Sentinel documentation<\/a>. But you don\u2019t need a PhD to get value out of it. In my experience, a basic setup with good timeouts and a clean network gets you 95% of the way there.<\/p>\n<h2 id=\"section-3\"><span id=\"Automatic_Failover_for_WordPress_The_Plugin_Needs_to_Know_Where_the_Primary_Is\">Automatic Failover for WordPress: The Plugin Needs to Know Where the Primary Is<\/span><\/h2>\n<p>Redis will do the failover dance, but WordPress needs to follow its lead. If your object cache plugin connects to a single host and never asks questions, it will keep trying the dead primary. That\u2019s why Sentinel support in your WordPress Redis plugin is a must.<\/p>\n<p>Most folks I work with use the excellent Redis Object Cache plugin. It supports Sentinel, and once you set it, it just feels\u2026 calm. The idea is simple: you tell the plugin the Sentinel service name (that <strong>mymaster<\/strong> string) and give it the addresses of your Sentinels. From then on, the plugin asks Sentinel for the current primary and connects accordingly. If failover happens mid-traffic, it reconnects to the new primary and keeps going.<\/p>\n<p>If you\u2019re curious about the plugin details or want to peek at the code, the GitHub repo is here: <a href=\"https:\/\/github.com\/rhubarbgroup\/redis-cache\" rel=\"nofollow noopener\" target=\"_blank\">Redis Object Cache plugin on GitHub<\/a>. I like seeing how tools behave under the hood during failover, and this plugin makes sensible choices.<\/p>\n<p>For a typical <code>wp-config.php<\/code>, your Sentinel setup might look like this:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">\/\/ Use the phpredis extension if available\ndefine('WP_REDIS_CLIENT', 'phpredis');\n\n\/\/ Sentinel master name\ndefine('WP_REDIS_SENTINEL', 'mymaster');\n\n\/\/ List of Sentinel endpoints\ndefine('WP_REDIS_SERVERS', [\n    'tcp:\/\/10.0.0.21:26379',\n    'tcp:\/\/10.0.0.22:26379',\n    'tcp:\/\/10.0.0.23:26379',\n]);\n\n\/\/ Optional niceties\ndefine('WP_REDIS_PASSWORD', 'a-strong-password');\ndefine('WP_REDIS_PREFIX', 'wp:prod:');\ndefine('WP_REDIS_DATABASE', 0);\n<\/code><\/pre>\n<p>That\u2019s it. Under the hood, the plugin queries Sentinel for the current primary of <strong>mymaster<\/strong>, connects there, and reconnects if the primary changes. That single detail\u2014connecting through Sentinel\u2014turns chaos into a shrug during a primary outage.<\/p>\n<p>If you\u2019re running WordPress in containers and want to see how Redis fits in alongside Nginx, MariaDB, and Let\u2019s Encrypt, I\u2019ve documented an end\u2011to\u2011end workflow in <a href=\"https:\/\/www.dchost.com\/blog\/en\/docker-ile-wordpressi-vpste-nasil-yasatiriz-nginx-mariadb-redis-ve-lets-encrypt-ile-kalici-depolama-macerasi\/\">my no\u2011drama playbook for hosting WordPress on a VPS with Docker, Nginx, MariaDB, Redis, and Let\u2019s Encrypt<\/a>. The Sentinel bit slots right in.<\/p>\n<h2 id=\"section-4\"><span id=\"AOF_and_RDB_Persistence_That_Makes_Restarts_Boring\">AOF and RDB: Persistence That Makes Restarts Boring<\/span><\/h2>\n<p>Redis is an in\u2011memory store, but you don\u2019t want your cache to evaporate on every restart. That\u2019s where persistence comes in. Two mechanisms live here: <strong>RDB<\/strong> snapshots (periodic point\u2011in\u2011time dumps) and the <strong>AOF<\/strong> append\u2011only log (a write log that replays changes). You can run either or both. For WordPress object caching, my go\u2011to is AOF enabled with <em>everysec<\/em> fsync, plus occasional RDB snapshots for fast restarts and safety.<\/p>\n<p>Think of RDB as a photo you take every once in a while. If Redis restarts, it loads that photo. AOF is like a journal entry for every change. Combining the two means Redis can load a recent photo and then quickly replay the journal to catch up. You get shorter recovery times and fewer cold-cache minutes after a reboot.<\/p>\n<p>Here\u2019s a starter <code>redis.conf<\/code> slice that\u2019s treated me well:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">maxmemory 2gb\nmaxmemory-policy allkeys-lru\n\nappendonly yes\nappendfilename &quot;appendonly.aof&quot;\nappendfsync everysec\nno-appendfsync-on-rewrite yes\n\nsave 900 1\nsave 300 10\nsave 60 10000\naof-use-rdb-preamble yes\n\n# Replica settings (on the replica nodes)\n# replicaof 10.0.0.10 6379\n\n# Security basics\nprotected-mode yes\nbind 0.0.0.0 ::\nrequirepass a-strong-password\nmasterauth a-strong-password\n<\/code><\/pre>\n<p>A couple of notes from the field. That <strong>everysec<\/strong> setting is the sweet spot for most sites\u2014durability with reasonable latency. If you set fsync to <em>always<\/em>, your disk becomes part of every write path, and you\u2019ll feel it. <strong>no-appendfsync-on-rewrite yes<\/strong> helps you avoid IO storms during AOF rewrites. And if you\u2019re in containers, make sure your AOF\/RDB directory is on a persistent volume. I\u2019ve seen folks lose their cache after a restart because their Redis wrote to an ephemeral layer. Not fun.<\/p>\n<p>One more detail: pick an appropriate <strong>maxmemory<\/strong> and a policy that won\u2019t surprise you. For WordPress, <strong>allkeys-lru<\/strong> tends to be a sensible default because almost everything in the object cache is fair game to evict. Just make sure you provide TTLs through your code and caching stack where it makes sense, so the cache naturally churns.<\/p>\n<p>If you want to read the vendor perspective on durability choices, the official docs are tidy: <a href=\"https:\/\/redis.io\/docs\/latest\/operate\/redis\/persistence\/\" rel=\"nofollow noopener\" target=\"_blank\">Redis persistence overview<\/a>.<\/p>\n<h2 id=\"section-5\"><span id=\"Replication_and_Topology_Keep_It_Simple_and_Quorum-Friendly\">Replication and Topology: Keep It Simple (and Quorum-Friendly)<\/span><\/h2>\n<p>Here\u2019s the map I usually start with: one primary Redis node, one or two replicas, and three Sentinels. The Sentinels can live beside the Redis nodes, but don\u2019t stack everything on one host. I\u2019ve had the best luck when the Sentinels run on different machines (tiny ones are fine), so a single box reboot doesn\u2019t cause panic. The replicas should be close to the primary\u2014latency matters for replication.<\/p>\n<p>You\u2019ll see people talk about Redis Cluster, and it\u2019s fantastic for key\u2011space sharding and scaling throughput across many nodes. But WordPress object caching isn\u2019t usually a Cluster problem; it\u2019s a stand\u2011alone Redis with fast failover problem. Sentinel with replication is the right tool for that. It\u2019s simpler, friendlier to single\u2011key operations, and your object cache plugin expects exactly this style of topology.<\/p>\n<p>That said, replicas aren\u2019t purely decorative. They give you a ready\u2011to\u2011promote node, they absorb load during a partial incident, and they\u2019re a clean place to back up persistence files without touching the primary. Just remember that for object caching, writes matter more than fancy read distribution. We\u2019re not building a read\u2011heavy analytics cluster here\u2014we\u2019re building a resilience cushion.<\/p>\n<h2 id=\"section-6\"><span id=\"The_WordPress_Layer_Behavior_Timeouts_and_Edge_Cases\">The WordPress Layer: Behavior, Timeouts, and Edge Cases<\/span><\/h2>\n<p>Once Redis is replicated and watched by Sentinel, WordPress itself becomes the last mile. There are a few small knobs that make big differences. First, <strong>timeouts<\/strong>. Don\u2019t let your PHP processes hang forever waiting for a dead socket. Short, sensible timeouts mean the plugin gives up quickly and asks Sentinel for the new primary. If you have the option to set connect and read timeouts in your Redis client, nudge them to practical values (think seconds, not minutes).<\/p>\n<p>Next, <strong>prefixes<\/strong> and <strong>databases<\/strong>. It\u2019s neat to isolate caches for different environments with a prefix like <code>wp:prod:<\/code> and a consistent database index. This avoids awkward collisions if you have staging and production sharing a Redis fleet\u2014don\u2019t laugh, I\u2019ve seen it.<\/p>\n<p>Also, consider the content of your cache. Are you caching huge transient blobs that never expire? I worked with one team who had a long\u2011lived session object parked in Redis without a TTL. It quietly ballooned their memory usage, and eviction got weird under pressure. Add TTLs where it makes sense and let Redis do its LRU magic without surprises.<\/p>\n<p>Curious about frontend caching too? Object caching is only one piece. When I paired a healthy Redis object cache with careful browser and CDN policy, everything felt snappy even on slow networks. If you want a friendly spin on those headers, I wrote about it in <a href=\"https:\/\/www.dchost.com\/blog\/en\/nereden-baslamaliyiz-bir-css-dosyasinin-pesinde\/\">Stop Fighting Your Cache: the guide to Cache-Control immutable, ETag vs Last\u2011Modified, and asset fingerprinting<\/a>. It pairs nicely with Redis underneath.<\/p>\n<h2 id=\"section-7\"><span id=\"Testing_Failover_Without_Breaking_a_Sweat\">Testing Failover Without Breaking a Sweat<\/span><\/h2>\n<p>Okay, this is my favorite part, because nothing builds confidence like a controlled failover. After you\u2019ve got your Replication + Sentinel setup running, run a test during a calm hour. Use <code>redis-cli<\/code> to ask Sentinel to failover the primary, then watch WordPress keep its cool.<\/p>\n<p>From a machine that can talk to your Sentinels:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\"># See what Sentinel thinks\nredis-cli -p 26379 SENTINEL masters\nredis-cli -p 26379 SENTINEL slaves mymaster\n\n# Trigger a controlled failover\nredis-cli -p 26379 SENTINEL failover mymaster\n<\/code><\/pre>\n<p>Now watch the logs. Your Redis nodes will show the election, the replica being promoted, and the old primary becoming a replica. On the PHP side, you might see a short hiccup if a request lands during the switchover, but it should recover. I typically run a tiny watch script that hits the site every second during the failover and prints status and timing. If you\u2019re wired into logging properly, you\u2019ll catch the whole dance.<\/p>\n<p>And about logs\u2014this is one of those moments where centralized logging pays off. If you haven\u2019t yet built a simple ops trail, my practical write\u2011up on <a href=\"https:\/\/www.dchost.com\/blog\/en\/vps-log-yonetimi-nasil-rayina-oturur-grafana-loki-promtail-ile-merkezi-loglama-tutma-sureleri-ve-alarm-kurallari\/\">centralized logging with Grafana Loki and Promtail<\/a> shows how to keep an eye on Redis, PHP\u2011FPM, and Nginx without drowning in noise. It\u2019s the easiest way to know if failovers are clean or chatty.<\/p>\n<h2 id=\"section-8\"><span id=\"Operational_Habits_The_Stuff_That_Prevents_2_am_Surprises\">Operational Habits: The Stuff That Prevents 2 a.m. Surprises<\/span><\/h2>\n<p>Let\u2019s talk maintenance. Redis loves RAM. Give it room to breathe, and it will love you back. Keep your <strong>maxmemory<\/strong> honest\u2014don\u2019t pretend a 2 GB cache fits into 1 GB. Monitor memory fragmentation over time; it\u2019s normal to fluctuate, but if it climbs endlessly, check your key sizes and patterns. Avoid <strong>big keys<\/strong>\u2014that one giant serialized array someone tucked away a year ago can cause real latency spikes when saved or evicted.<\/p>\n<p>Disk matters too, especially with AOF. Fast disks reduce the latency of those every\u2011second fsyncs. If you\u2019re on cloud block storage, pick a tier that doesn\u2019t stall under bursty writes. When an AOF rewrite runs, you\u2019ll thank yourself. And if you\u2019re in Docker or Kubernetes, put the Redis data directory on a persistent, fast volume\u2014no exceptions.<\/p>\n<p>Security is another quiet hero. Don\u2019t leave Redis wide open. Bind it to private interfaces, use <strong>requirepass<\/strong>\/<strong>masterauth<\/strong> or ACLs, and if your threat model requires it, enable TLS. Redis ships with sensible guardrails\u2014<strong>protected-mode<\/strong> is there for a reason. Don\u2019t flip it off without understanding the blast radius. The official docs have a straight\u2011forward section on security, but the short version is simple: only the things that must talk to Redis should talk to Redis.<\/p>\n<p>Finally, write down your failover plan. I know, it sounds quaint. But I\u2019ve watched experienced teams get flustered at 2 a.m. because no one remembered the exact Sentinel command. A one\u2011page runbook with \u201chow to trigger failover,\u201d \u201chow to check state,\u201d and \u201cwhat healthy looks like\u201d is the difference between a calm five minutes and an anxious hour.<\/p>\n<h2 id=\"section-9\"><span id=\"Docker_Compose_Example_A_Minimal_HA_Playground\">Docker Compose Example: A Minimal HA Playground<\/span><\/h2>\n<p>If you want something you can poke at on a lab server, here\u2019s a simplified example. It\u2019s not meant for production copy\u2011paste, but it shows the moving parts: a primary, a replica, and three Sentinels. Wire in volumes, credentials, and networking to your taste.<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">version: '3.9'\nservices:\n  redis-primary:\n    image: redis:7\n    command: [&quot;redis-server&quot;, &quot;\/usr\/local\/etc\/redis\/redis.conf&quot;]\n    volumes:\n      - .\/primary\/redis.conf:\/usr\/local\/etc\/redis\/redis.conf:ro\n      - primary-data:\/data\n    networks: [net]\n\n  redis-replica:\n    image: redis:7\n    command: [&quot;redis-server&quot;, &quot;\/usr\/local\/etc\/redis\/redis.conf&quot;]\n    volumes:\n      - .\/replica\/redis.conf:\/usr\/local\/etc\/redis\/redis.conf:ro\n      - replica-data:\/data\n    networks: [net]\n\n  sentinel-1:\n    image: redis:7\n    command: [&quot;redis-sentinel&quot;, &quot;\/usr\/local\/etc\/redis\/sentinel.conf&quot;]\n    volumes:\n      - .\/sentinel\/sentinel.conf:\/usr\/local\/etc\/redis\/sentinel.conf:ro\n    networks: [net]\n\n  sentinel-2:\n    image: redis:7\n    command: [&quot;redis-sentinel&quot;, &quot;\/usr\/local\/etc\/redis\/sentinel.conf&quot;]\n    volumes:\n      - .\/sentinel\/sentinel.conf:\/usr\/local\/etc\/redis\/sentinel.conf:ro\n    networks: [net]\n\n  sentinel-3:\n    image: redis:7\n    command: [&quot;redis-sentinel&quot;, &quot;\/usr\/local\/etc\/redis\/sentinel.conf&quot;]\n    volumes:\n      - .\/sentinel\/sentinel.conf:\/usr\/local\/etc\/redis\/sentinel.conf:ro\n    networks: [net]\n\nvolumes:\n  primary-data:\n  replica-data:\n\nnetworks:\n  net:\n<\/code><\/pre>\n<p>In the primary\u2019s <code>redis.conf<\/code>, you\u2019d set your <code>appendonly yes<\/code> and <code>maxmemory<\/code> bits. In the replica\u2019s, add a <code>replicaof<\/code> pointing to the primary\u2019s service name. And in <code>sentinel.conf<\/code> you\u2019d reference the primary host and port via Docker DNS (or static IPs in your environment). Then run a controlled failover and watch the logs. It\u2019s oddly satisfying.<\/p>\n<h2 id=\"section-10\"><span id=\"Application_Behavior_During_Failover_What_Users_Feel\">Application Behavior During Failover: What Users Feel<\/span><\/h2>\n<p>Let\u2019s talk about the human experience. During a failover, a handful of requests might miss the cache and head to the database. On a healthy stack, that\u2019s barely a blip. Modern PHP stacks handle reconnect logic quickly, and the cache warms itself almost immediately for hot keys. On heavier sites, I\u2019ll sometimes stage a warmup script after a restart to pre\u2011pull costly keys, but most WordPress sites don\u2019t need that level of ceremony.<\/p>\n<p>What\u2019s more important is that your database isn\u2019t a single point of failure while Redis is rebalancing. If you\u2019re running a store or membership site, make sure your database has its own high\u2011availability story. I wrote down my practical notes from the trenches in <a href=\"https:\/\/www.dchost.com\/blog\/en\/mariadb-yuksek-erisilebilirlik-galera-cluster-mi-primary%e2%80%91replica-mi-woocommerce-icin-okuma-yazma-mimarisi\/\">the MariaDB high availability guide for WooCommerce<\/a>. Redis smooths performance, but the database is the spine\u2014give it the same love.<\/p>\n<h2 id=\"section-11\"><span id=\"Common_Gotchas_I_Keep_Seeing_and_How_to_Dodge_Them\">Common Gotchas I Keep Seeing (and How to Dodge Them)<\/span><\/h2>\n<p>First, the missing persistence directory. People deploy Redis in a container, forget to mount a persistent volume for <code>\/data<\/code>, and then wonder why the cache is gone after every restart. The cache should survive a normal reboot with AOF and RDB; if it doesn\u2019t, double\u2011check where Redis is actually writing its files.<\/p>\n<p>Second, slow disks during AOF rewrite. You don\u2019t notice it for days, and then a rewrite collides with a busy hour and latency creeps in. Keep an eye on <code>INFO persistence<\/code> metrics and test your disk behavior. If you\u2019re on a tiny <a href=\"https:\/\/www.dchost.com\/vps\">VPS<\/a> with networked storage, be kind to it with <code>no-appendfsync-on-rewrite yes<\/code>.<\/p>\n<p>Third, Sentinels all on one box. It works\u2026 until that box reboots. Spread them out. If you have only two small nodes, consider running two Sentinels on the worker machines and one on a tiny management instance. The goal is quorum even during a small storm.<\/p>\n<p>Fourth, overly sticky objects. If your cache holds onto a few massive keys with no TTL, eviction gets weird under pressure. Get in the habit of storing smaller pieces or attaching practical TTLs. If you\u2019re serializing everything and stuffing it in one key, you\u2019re carrying a couch through a narrow hallway every time.<\/p>\n<h2 id=\"section-12\"><span id=\"Security_and_Access_Keep_Redis_Behind_a_Friendly_Fence\">Security and Access: Keep Redis Behind a Friendly Fence<\/span><\/h2>\n<p>I\u2019ll keep this short and kind. Don\u2019t put Redis directly on the public internet. Bind it to your private network interfaces, keep a firewall wrapped around the fleet, and use authentication. If your stack supports TLS and you\u2019re crossing untrusted networks, enable it. Also, use separate credentials for applications and internals\u2014your replicas and Sentinels don\u2019t need the same scope as your WordPress app. Security fatigue is real, but a tight perimeter here pays off.<\/p>\n<p>If you\u2019re curious about designing the whole environment with some discipline\u2014deploy flow, zero\u2011downtime updates, and a less stressful life\u2014I\u2019ve laid out a battle\u2011tested, scriptable approach in <a href=\"https:\/\/www.dchost.com\/blog\/en\/vpse-sifir-kesinti-ci-cd-nasil-kurulur-rsync-sembolik-surumler-ve-systemd-ile-sicacik-bir-yolculuk\/\">my zero\u2011downtime CI\/CD playbook for a VPS<\/a>. Redis fits neatly into that rhythm.<\/p>\n<h2 id=\"section-13\"><span id=\"Reality_Check_When_to_Scale_When_to_Rethink\">Reality Check: When to Scale, When to Rethink<\/span><\/h2>\n<p>There\u2019s a moment in every project where Redis starts to feel full. You\u2019ll notice eviction counter tick up and hit rates jitter. Before you assume you need a monster node, check what you\u2019re storing, because object caches have a way of collecting things they never needed. Remove overly large or low\u2011value keys, add TTLs, and watch the hit rate again. Nine times out of ten, you\u2019ll regain headroom without more hardware.<\/p>\n<p>If load really keeps climbing, vertical scaling is usually the first step: more RAM, faster disk, better CPU. Horizontal scaling with Redis Cluster is a bigger architectural decision that WordPress object caching rarely needs. When you get there, it\u2019s often not about the cache anymore\u2014it\u2019s about how your app creates and uses data. At that point, the conversation changes.<\/p>\n<h2 id=\"section-14\"><span id=\"A_StepbyStep_First_Deployment_You_Can_Try_This_Week\">A Step\u2011by\u2011Step \u201cFirst Deployment\u201d You Can Try This Week<\/span><\/h2>\n<p>Here\u2019s a simple path that\u2019s worked for teams I\u2019ve helped:<\/p>\n<p>First, set up a single Redis with AOF everysec and a sensible <strong>maxmemory<\/strong> policy. Hook it to WordPress and confirm you\u2019re getting good hit rates. Then add one replica and confirm replication is healthy. Next, deploy three Sentinels, point WordPress at them, and run a controlled failover during a quiet window. Watch your app logs and timings while you do it and take notes. Finally, add basic alerts: disk IO spikes, memory high\u2011water marks, and Sentinel failover notifications.<\/p>\n<p>By the end of this week\u2011long cycle, your object cache will be more survivable than most. And you\u2019ll have muscle memory you can rely on when the odd gremlin appears.<\/p>\n<h2 id=\"section-15\"><span id=\"Useful_Reading_If_You_Want_to_Go_Deeper\">Useful Reading If You Want to Go Deeper<\/span><\/h2>\n<p>If you\u2019re the curious type, two documents are worth skimming:<\/p>\n<p>One is the official <a href=\"https:\/\/redis.io\/docs\/latest\/operate\/redis\/sentinel\/\" rel=\"nofollow noopener\" target=\"_blank\">Sentinel overview<\/a>\u2014helpful for seeing how quorum and failover timing interact.<\/p>\n<p>The other is the <a href=\"https:\/\/redis.io\/docs\/latest\/operate\/redis\/persistence\/\" rel=\"nofollow noopener\" target=\"_blank\">persistence guide<\/a>\u2014the small flags around AOF rewrite and RDB scheduling make a big difference.<br \/>\nAnd if you prefer a more narrative, hands\u2011on tour of a full WordPress stack with Redis in the middle of it, I\u2019ve mapped out a no\u2011drama path here: <a href=\"https:\/\/www.dchost.com\/blog\/en\/docker-ile-wordpressi-vpste-nasil-yasatiriz-nginx-mariadb-redis-ve-lets-encrypt-ile-kalici-depolama-macerasi\/\">hosting WordPress with Docker, Nginx, MariaDB, Redis, and Let\u2019s Encrypt<\/a>. Pair that with <a href=\"https:\/\/www.dchost.com\/blog\/en\/nereden-baslamaliyiz-bir-css-dosyasinin-pesinde\/\">a smarter browser cache strategy<\/a> and <a href=\"https:\/\/www.dchost.com\/blog\/en\/vps-log-yonetimi-nasil-rayina-oturur-grafana-loki-promtail-ile-merkezi-loglama-tutma-sureleri-ve-alarm-kurallari\/\">clean, centralized logs<\/a>, and you\u2019ll sleep better.<\/p>\n<h2 id=\"section-16\"><span id=\"WrapUp_Make_Redis_Failover_the_Most_Boring_Thing_You_Do\">Wrap\u2011Up: Make Redis Failover the Most Boring Thing You Do<\/span><\/h2>\n<p>If I had to compress everything into one sentence, it would be this: use Sentinel with a primary\u2011replica pair, enable AOF everysec (with RDB snapshots), and point WordPress at Sentinel\u2014not a single host. That combination turns a crash into a shrug.<\/p>\n<p>Build the habit of small tests. Trigger a failover when traffic is calm. Verify your plugin reconnects fast. Check your persistence files are landing on a persistent disk. Watch for large keys and memory creep. And give your database the same high\u2011availability care so a momentary cache miss doesn\u2019t snowball into a bigger issue. If you want a friendly chat about database HA trade\u2011offs, I wrote about them in <a href=\"https:\/\/www.dchost.com\/blog\/en\/mariadb-yuksek-erisilebilirlik-galera-cluster-mi-primary%e2%80%91replica-mi-woocommerce-icin-okuma-yazma-mimarisi\/\">my MariaDB HA story for WooCommerce<\/a>\u2014it pairs with this setup like coffee and a good cookie.<\/p>\n<p>That\u2019s it. Nothing exotic. Just a few proven pieces, wired together carefully, that keep your WordPress site smooth when life gets noisy. Hope this was helpful! If you try the failover test this week and want to share how it went, I\u2019d love to hear about it. See you in the next post.<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>So, a quick story. A few summers ago, I was babysitting a WooCommerce sale that was going way too well. The site was humming, Redis was happy, and the object cache was doing its thing\u2014until the primary Redis process quietly vanished in the middle of a promo push. Suddenly, what felt instant started dragging. Queries [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1593,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"class_list":["post-1592","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-teknoloji"],"_links":{"self":[{"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/posts\/1592","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/comments?post=1592"}],"version-history":[{"count":0,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/posts\/1592\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/media\/1593"}],"wp:attachment":[{"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/media?parent=1592"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/categories?post=1592"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/tags?post=1592"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}