Why Drupal high availability takes more than a second web server
Drupal high availability means the site keeps serving pages and accepting edits when a web server, database node or cache node fails, without a person having to rebuild the service from scratch. Adding a second web server behind a load balancer is the easy half. The harder half is that Drupal keeps state in several places, and every one of them must survive a node loss in the same way the web tier does. If your site has outgrown a single server or must tolerate a node failure, the design decisions you face are about where that state lives and who owns it, not about how many Apache or Nginx instances you run.
The state that matters falls into a few groups. Public and private files are the first: uploads written by editors live on local disk unless you place them on shared storage that every web node can reach. Sessions, which keep logged-in editors and form submissions tied to a user, must be stored somewhere all nodes can read, not in local process memory. Cron, the scheduled task runner, must run on one node at a time, or it will fire the same jobs twice. The cache layer, whether it is Drupal's database cache or an external backend, must either be shared or be safe to lose. Finally, database writes from content saves, user changes and module state all go to one primary, so the database topology and its failover behavior determine how much of the site is writable during an incident.
Each of these choices has trade-offs that depend on your platform. Drupal runs on Apache or Nginx, with MariaDB, MySQL or PostgreSQL as the database, and the replication, failover and storage options differ across those combinations. Your team should confirm, with the vendor documentation for the database and storage products you intend to use, how writes are promoted during failover, how long a failover takes to complete, and whether your chosen storage layer supports the file locking behavior Drupal expects. Do not assume that a database cluster product behaves identically under Drupal's write pattern until you have tested it.
This is why a Drupal high availability design has to be verified under failure, not only assumed. A diagram that shows redundant nodes proves little. Verification means stopping a web node during a publish, killing the primary database during an editor's save, failing the cache node, and confirming that cron runs once, sessions survive, and uploads remain readable. It also means measuring how long users see errors and whether editors lose unsaved work. Ask any partner to show the failure tests they will run, the expected results, and the evidence they will hand over at the end, and treat the answers as part of the scope you agree in writing.
Which Drupal components must become redundant
A Drupal site stays available only when every layer that holds state or serves requests is either duplicated or deliberately kept to one instance. The cards below walk through each layer, what Drupal writes to it, and what happens when two nodes disagree about it.
Load balancer and health checks
The load balancer is the single entry point that spreads requests across web nodes and removes unhealthy ones from rotation. Define a health check that exercises Drupal itself, not only the web server port, so a node with a broken PHP pool or database connection is pulled out. Confirm session affinity settings, since Drupal's login sessions must work regardless of which node answers.
Stateless web nodes with PHP
Apache or Nginx with PHP-FPM should hold no site data of its own, so any node can serve any request. Every node must run the same Drupal codebase, the same settings.php and the same PHP version, because a mismatch produces errors that appear only on some requests. Build nodes from one versioned artifact and check that deploys update all of them before traffic returns.
Shared public and private file storage
Drupal writes uploaded images, documents and generated image styles to the public files directory and writes restricted uploads to the private files directory. If nodes keep these on local disks, a file uploaded on one node returns a broken link on another, and a generated style can exist on one node only. Move both directories to shared storage that every node mounts, and confirm the private path is outside the web root.
Database and its replication
The database is the system of record for content, configuration, users and sessions, so it is the component where disagreement does the most damage. Replication lets a standby take over, but a read replica can lag behind the primary, which can show stale content or fail a write-then-read sequence. Confirm which engine you run (MariaDB, MySQL or PostgreSQL), how failover is promoted, and that SQLite is not used, since it is a file-based engine that does not suit a multi-node setup.
Cache backend and Varnish
Redis or Memcache can hold Drupal's cache bins so that all nodes share one view of cached data, and Varnish can sit in front to serve anonymous pages. If each node caches locally, one node may show an edited page while another still serves the old version, and cache tags will not invalidate across nodes. Decide which bins move to the shared backend and confirm that purges reach Varnish and every node.
Cron and queues on one node
Scheduled cron jobs, queue workers and some migrations must run on one node only, or they execute twice and can duplicate emails, imports or scheduled publishing. Designate a single scheduler or a lock-protected runner, and keep cron disabled on the other nodes. Verify the choice by checking the cron log on each node after a failover drill.
Which HA design choices fit your team, and what each costs to run
This table compares the main Drupal high availability choices for sessions, shared files, database topology, caching and cron, with the team profile each one suits and the ongoing work it creates. Read each row against your own team's skills and your provider's failover tooling. The main takeaway is that the cheapest design to build is not always the cheapest to run, because failover, cache invalidation and file administration recur after go-live.
| Design area | Option | When it fits | Operational cost to run |
|---|---|---|---|
| Session handling | Database sessions | Web nodes sit behind a load balancer that cannot hold affinity, or you want any node to serve any request. | Session reads and writes add database load. Someone must monitor and clean the session store. |
| Session handling | Sticky sessions at the load balancer | Your load balancer supports cookie affinity and you want to keep session state off the database. | Sessions pinned to a failed node are lost. Affinity rules need testing, and load can spread unevenly. |
| Shared file storage | Network file system | Your organization already runs a managed network file service and wants standard paths for public and private files. | The file service is a single point of failure unless it is clustered. Someone must administer permissions, locking and capacity. |
| Shared file storage | Object storage through a contributed module | Large media libraries, and a team comfortable with a module-managed file backend. Confirm the module supports your Drupal version. | The module must be updated with Drupal releases. Public and private file handling needs review, and request and egress fees recur with the provider. |
| Database topology | Primary with replicas or a managed cluster | Read-heavy sites, or a team that wants the provider to manage failover and backups. Confirm the engine is MariaDB, MySQL or PostgreSQL. | Writes go to the primary. Replication lag must be handled in configuration. Managed clusters add recurring service fees and limit engine tuning. |
| Database topology | Synchronous multi-writer | Writes must be accepted at more than one site with strong consistency. This is uncommon for typical Drupal sites. | Highest administration effort. Conflict and locking behavior under Drupal's transaction patterns must be tested, and engine support confirmed. |
| Cache placement | Redis or Memcache per site | Web nodes in one site need a shared cache backend for Drupal's cache tags and render caches. | Another stateful service to run and monitor. Memory sizing and eviction behavior need periodic review. |
| Cache placement | Varnish or a CDN at the edge | Anonymous traffic dominates, or you need to absorb traffic spikes. Authenticated pages usually bypass the edge cache. | Purge rules must match Drupal cache tags. Mistakes serve stale content. CDN usage fees recur. |
| Cron | One designated runner for cron | Any multi-node site, so scheduled tasks run once rather than on every web node. | If the runner fails, cron stops without an obvious error. Alert on the time of the last successful run. |
How to build a Drupal HA stack in the right order
This sequence moves a single Drupal site onto redundant web nodes, shared state and a health-checked load balancer, with a verification check at each step so a failure is caught before the next layer depends on it. The order matters because each layer assumes the one before it already holds state correctly.
Provision the database with replication
The database team or the implementation partner sets up a primary database with one or more replicas on the platform the site already uses, such as MariaDB, MySQL or PostgreSQL, as listed in Drupal's system requirements. Confirm that replication is healthy and that the application can write only to the primary. Then run a planned manual failover: promote a replica, point the site at the new primary, and confirm that content can be created and edited. Record how long the switch took and what the application did during it. The step is done when a failover has been rehearsed end to end and the runbook reflects the actual steps. Exact replication and connection settings depend on your database version and on the Drupal.org documentation for your Drupal version, so confirm them there before you build.
Move public and private files to shared storage
Public and private file directories must be on storage that every web node can read and write, such as a network file system or object storage mounted through a supported module. Local disks on each node will drift apart as editors upload media. Confirm the Drupal file system paths and the private file location in the site configuration, then upload a file through one node and check that it is visible and downloadable from every other node. Also confirm that image styles generated on one node are served correctly from the others. The step closes when a test upload lands on all nodes with the same content and permissions. Ask your storage provider and your Drupal developer which mount options and caching behavior they support.
Move sessions and the cache backend to shared services
Sessions and the render or data cache must live in a shared service, typically Redis or Memcache, so that any web node can serve any logged-in user. Keeping them in local files or local memory breaks logins as soon as the load balancer routes a request elsewhere. Install and configure the cache backend module chosen for your version, then confirm that cache bins are written to the shared service rather than to local disk. Verification: log in, restart one web node, and confirm the session survives and the user is still authenticated on the other node. The step is complete when a login survives a node restart with no re-prompt. Check the exact cache and session settings against the Drupal.org documentation for your version.
Deploy identical code and settings to two web nodes
Build the code once, through your normal Composer and deployment pipeline, and deploy the same artifact to two web nodes running the same PHP version. Keep settings.php outside the code tree, usually in a location the web server cannot serve, and inject database, cache and file-path values from the environment or a secrets store. Keeping the file outside the tree prevents a deployment from overwriting host-specific values and prevents credentials from entering version control. Verification: compare checksums of the code tree on both nodes and load the same page on each, confirming that they render identically and connect to the same database and cache. The step is done when both nodes are byte-identical in code and report the same configuration state.
Place the load balancer with health checks on a dedicated status path
Put a load balancer in front of the web nodes and configure health checks against a dedicated status path that reports whether the node can reach the database and cache, rather than against the homepage, which can be cached and hide failures. Restrict that path to the load balancer's address range. Verification: stop the web service on one node and confirm that the balancer removes it from rotation within its configured check window, with no user-facing errors on the remaining node. Then restore the node and confirm it rejoins. The step is complete when a single node failure is absorbed without visible errors. Confirm the health check mechanics with your load balancer vendor and your Drupal developer, since the status path must be implemented in the site.
Designate one node for cron
Scheduled tasks such as cron, queue processing and search index updates should run on one designated node, not on every web node, or they will overlap and duplicate work. Disable automatic cron on the web nodes, then configure a single scheduler, either on a dedicated worker or on one node, to run cron through Drush at a fixed interval. Verification: check the cron log and the last-run timestamp, then stop the designated node and confirm that the scheduler fails over or alerts, depending on how you built it. The step is done when cron runs exactly once per interval across the cluster and a missed run triggers an alert. Confirm the recommended cron approach for your Drupal version in the Drupal.org documentation.
Run a full checkout across nodes and confirm cache invalidation
Finish with an end-to-end test that behaves like a real customer. Add a product or order through the storefront, pass through the load balancer several times to hit both nodes, and confirm that every node displays the same cart, the same prices and the same content. Then edit a piece of content on one node and check that the change appears on the other node and on any reverse proxy or CDN in front of it within the expected time. Cache invalidation failures are the most common source of stale data in a clustered Drupal site. The step is complete when a full checkout succeeds on every node and a content edit propagates everywhere without a manual cache clear. Keep this test as a repeatable script for every release.
What drives the effort and cost of a Drupal HA build
This table lists the main factors that change the scope of a Drupal high availability build, with a note on how to keep each one under control. Read each row as a question to answer about your own site before asking for a quote. The main takeaway is that the largest costs usually come from state the site keeps outside the code, not from the web servers themselves.
| Driver | Why it changes effort or cost | How to keep it down |
|---|---|---|
| Content and file volume | Every web node must see the same public and private files, so the shared storage, its copy and its backup window grow with the file library and the number of media items. | Audit the file system before design, remove unused media, separate private files from public files, and confirm which storage service the hosting environment provides. |
| Traffic patterns and peak events | Peaks such as product launches, enrolment windows or election results decide how many web nodes, cache layers and database read paths you need, and how load tests must be designed. | Collect traffic history from the current site, identify the top few peak events, and agree in writing which peaks the HA design must absorb versus which ones a static or queued page can handle. |
| Stateful integrations and sessions | SSO, search, payment callbacks and other services that hold sessions or state must work when a request lands on any node, which adds configuration, testing and failover cases. | List each integration with the state it holds, prefer stateless tokens where the provider supports them, and confirm session storage and timeout behavior with each vendor. |
| Environments that must match production | Staging, performance and disaster recovery environments need the same web, database, cache and storage topology to produce results that predict production behavior. | Standardize environments with the same infrastructure definitions and Drupal configuration, and limit differences to size and data masking. |
| Custom caching and session layer | Custom cache bins, cache tag handling, or bespoke session code must be tested across nodes and invalidation paths, and they are rarely covered by vendor documentation. | Use the core cache and the standard Redis or Memcache backends where they meet the requirement, keep custom cache logic in one reviewed module, and document every cache invalidation path. |
| Compliance evidence needs | Assessors may ask for logs, change records, backup restore tests, access reviews and proof of failover, each of which is extra work to design and to keep current. | Agree the evidence list with your auditor before the build, generate it from the pipeline and monitoring tools where possible, and schedule evidence collection as recurring work. DeployOpen prepares evidence but does not issue audit reports. |
| Operator skills available | Teams that already run Drupal, load balancers and database replication need less training and fewer handover sessions than teams that are new to one of these layers. | Confirm which named staff will operate the platform, plan knowledge transfer and runbooks into the scope, and decide early whether a support retainer will cover on-call or patching. |
| Code that keeps state on the server | Local file writes, in-memory sessions or code that assumes one web node force rework when more nodes are added, and they are often found late in the build. | Keep code stateless, move uploads and temporary files to shared storage, and review contributed and custom modules for local state before the design is fixed. |
How the HA pattern changes by deployment model
A single node is the baseline that the other models extend. One server runs the web server, PHP and Drupal, and often the database and cache as well. It removes the multi-node complexity, but it also removes redundancy: a failed host takes the site down until it is restored. Teams use this model for low-risk sites, development or staging environments, and as a recovery target for backups.
- Shared storage: not needed for the code and files on one host, but the public files directory still needs a documented backup schedule.
- Database: runs on the same host or on a separate instance. Confirm backup frequency and restore testing with the owner of that host.
- Images and code: deployed directly from a build, with a rollback copy of the previous release kept on disk.
- Caching: the page and dynamic page caches work out of the box; an external cache is optional.
- Failover: not provided. Confirm the recovery time objective with the business owner before accepting this model.
What does not change: the Drupal configuration sync workflow, the PHP version requirement and the need for a tested restore. Confirm with your platform owners how the host is patched and who is paged when it fails.
This is the classic multi-node model in one data center. Two or more identical web nodes sit behind a load balancer, and every node runs the same release. Because nodes must not hold state, the public files directory moves to shared storage, sessions and caches move to shared backends, and the database becomes a replicated or clustered service.
- Shared storage: an NFS export or a clustered file service mounted on every node for the public files directory. Confirm the file system's locking and latency behavior with your storage team before you rely on it.
- Database: usually a primary with one or more replicas, or a managed cluster in your own cloud account. Confirm who owns failover and how Drupal connects to the writer.
- Images and code: each release is built once and rolled to nodes in batches, so that a failed batch can be pulled from the load balancer.
- Caching: an external cache such as Redis or Memcache is shared across nodes, and a reverse proxy such as Varnish can sit in front of the load balancer.
- Configuration: configuration sync runs once per release, not on each node.
What does not change: the stateless web tier, the requirement that every node runs the same code, and the need for health checks on the load balancer. Confirm with your network and platform owners the health check path, session affinity policy and maintenance window process.
On Kubernetes, the web tier runs as a deployment of containers, and the orchestrator handles replica count, rolling updates and restarts. The pattern stays the same, but the stateful pieces are usually consumed as services rather than managed inside the cluster. Verify container and orchestration support for your Drupal and PHP versions against your own platform documentation, because image layout, PHP extensions and the supported storage classes depend on your build and cluster.
- Shared storage: a ReadWriteMany volume from your storage class, or an object storage integration for public files. Confirm which option your cluster supports and how it performs under concurrent writes.
- Database: commonly a managed service or a stateful set run by a database operator. Confirm who patches it and who restores it.
- Images and code: images are built in a pipeline, tagged per release and promoted through environments by digest, so that staging and production run the same artifact.
- Caching: Redis or Memcache runs as a separate service, and the ingress or a CDN may handle edge caching.
- Configuration: configuration import runs as a job before the new replicas receive traffic.
What does not change: the stateless web tier, the shared file and cache requirements, and the need for a tested database failover. Confirm with your platform owners the cluster version support policy, the ingress controller and the secret management approach.
In an air-gapped or on-premises network, the same HA pattern is built from components that your team can install and update without reaching public package repositories or external services. The main change is the supply chain. Composer packages, container base images, PHP extensions and security updates must be mirrored or delivered into the isolated network through an approved process, and that process has to keep pace with Drupal's release cycle.
- Shared storage: an on-premises NFS or clustered file service, selected by your infrastructure team. Confirm backup and replication at the storage layer.
- Database: an on-premises replicated cluster. Confirm who handles failover and whether it is tested on a schedule.
- Images and code: artifacts are promoted across a controlled boundary, with checksums recorded for each release.
- Caching and identity: external SaaS services are unavailable, so Redis or Memcache and any SSO integration must run inside the network.
- Updates: security advisories from the Drupal Security Team must be triaged and carried across the boundary within your own approval window.
What does not change: the stateless web tier, configuration sync per release and the need for a tested restore. Confirm with your security and platform owners how updates enter the network, who signs off on them and how the mirror is kept current with the Drupal core release schedule.
Zero-downtime releases with configuration sync on a Drupal cluster
A zero-downtime release on a Drupal cluster works only if every web node can serve traffic while the others are being changed. Several web servers share one database and one shared file store, so the rollout has to move through the nodes in sequence: take one node out of the load balancer pool, deploy the new code to it, return it to the pool, then repeat for the next node. The team should write down the node order, the health check that must pass before each node rejoins, and who can halt the rollout between steps. Those decisions matter more than the tooling, because the cluster will briefly run two code versions side by side.
Database updates and configuration imports are the steps that must not run once per node. Database updates (the post-update hooks run through Drush) change shared data, so they run one time, from a single designated node, after the new code is in place on that node and before the rest of the cluster is switched over. Configuration is imported with Configuration Management, using the same exported configuration that was reviewed in the pipeline. The reader should confirm which node is the designated runner, how the import is locked against concurrent runs, and whether the site is put into maintenance mode for the import or kept live.
Zero downtime breaks mainly at schema changes that the old code cannot read. A new required field, a renamed column in a custom module table, or a configuration key that old code does not understand can cause errors on nodes still running the previous release. The usual plan is to split the change into two releases: the first adds the new structure in a way the old code ignores, the second removes the old path once every node runs the new code. Cache rebuilds also need attention. Clearing caches too early can cause a cold-cache spike on nodes that remain in the pool, so the team should confirm the cache backend (for example Redis or the database) and the order in which caches are rebuilt.
Release timing has to fit Drupal's own calendar. Bugfix releases for Drupal core come out on the first Wednesday of each month, and security releases come out on the third Wednesday. A security release can require an unplanned patch cycle, so the release calendar should reserve time after each third Wednesday and keep at least one rehearsal on a staging cluster that mirrors the production node count. Contributed modules often lag core releases, so the team should check compatibility before scheduling an update.
For the pipeline detail that drives these steps, including artifact builds, review gates and automated tests, refer to the sibling page on Drupal configuration management and CI/CD. This section covers the cluster-level sequence and its failure points, and the reader should confirm with their own platform team how the load balancer drains connections, how health checks are defined, and how a failed node is rolled back without affecting the rest of the pool.
How to secure the shared services in an HA Drupal stack
Every web node in a high availability Drupal stack relies on the same shared services: the database, the cache backend, the file stores and the load balancer. A weak setting in any one of them exposes all nodes at once, so these checks apply across the whole cluster. For full hardening coverage, see the Drupal security hardening guide.
Database and replica credentials
Each web node connects to the primary database for writes and may connect to read replicas for queries. Give each environment its own database user with only the privileges Drupal needs, and create separate credentials for the replicas if they are reachable from the web tier. Confirm that a credential rotation can be applied to every node in one controlled change, and that the database listener accepts connections only from the web subnet and the administrative network.
Secrets outside the web root
The settings.php file holds database passwords, hash salts and service keys, so it must not be served or stored in a publicly reachable directory. Keep secrets in a store outside the document root, such as environment variables injected by the platform or a secrets manager, and have settings.php read them at runtime. Check that every node loads the same salt and that no secret appears in version control, container images or deployment logs.
File permissions on shared file stores
The public and private file directories are usually mounted from shared storage so that every web node sees the same uploads. The public directory must be readable by the web server but not executable as code, and the private directory must sit outside the web root with no direct URL access. Review ownership and mode bits after each mount change, and confirm that the deployment user can write only where a deployment step requires it.
Redis and Memcache authentication
When Redis or Memcache serves as the cache backend, every web node writes session and render data to it, so an open cache is a direct path into user sessions. Enable authentication where the chosen service supports it, bind the listener to the private network only, and restrict access with firewall rules or security groups limited to the web tier. Confirm that the Drupal cache configuration reads its connection details from protected settings, not from the repository.
Trusted host patterns for every name
Drupal rejects requests whose Host header does not match the trusted_host_patterns list in settings.php. In a load balanced stack, that list must include the public site name, each internal node name used for health checks or administration, and the load balancer address. Omitting one of these causes errors on some nodes only. Keep the list complete and narrow, and avoid broad wildcard patterns that would accept arbitrary hosts.
TLS and health endpoint access at the edge
The load balancer usually terminates TLS, so confirm which protocol versions and cipher settings it accepts, how certificates are issued and renewed, and where the private keys are stored. Traffic from the load balancer to the web nodes should be encrypted or confined to a private network, and Drupal must receive the original scheme so that links and redirects stay correct. Restrict health check and status endpoints to the load balancer and monitoring addresses, so that they do not reveal node details to the public internet.
How to test that a Drupal HA cluster fails safely
A high availability design is only proven when it is broken on purpose. Before go-live, the owner should run a written test plan that removes one component at a time under realistic load, records what happens to users and data, and compares the result against thresholds the owner has set. The tests below cover the failure modes that matter most for a Drupal site running several web nodes behind a load balancer, shared file storage, a replicated database and an external cache. Each test should have a named operator, a start time, a rollback step and a pass or fail decision recorded before the test begins.
Start with the web tier. Under sustained load, take one web node out of the load balancer rotation and confirm two things. First, authenticated sessions survive, which means the session store is shared (typically in the database or the cache backend) and not held in local memory on the removed node. Second, file uploads started on the affected node complete or fail cleanly, and the uploaded file is readable from every remaining node. Shared file storage is a common gap here: if the public and private file paths are not on shared storage, an upload succeeds on one node and returns a broken image on another. Ask the platform owner to confirm where the files directory and the private files directory are mounted before running this test.
Next, stop the primary database and promote a replica using the documented runbook. The test is about the runbook as much as the database. Someone who did not write the runbook should be able to follow it, and the team should measure how long the site is unavailable to editors and anonymous visitors, and whether any writes were lost or duplicated during promotion. Confirm that Drupal's database settings point to the correct endpoint after promotion, whether that is a virtual IP, a proxy or a configuration change, and that the old primary is fenced so it cannot accept writes if it returns. Record the replication lag measured just before the failure, since it sets the expected data loss window.
Then restart the cache service, such as Redis or Varnish, and watch what the site serves while it is down and while it refills. The safe outcome is a degraded but correct site: pages may be slower, but anonymous and authenticated users never receive another user's personalized content, and stale pages are not served beyond the cache lifetime the owner has approved. Check the cache-control headers and the cache tags on sample pages before and after the restart. Also run cron on one node only and confirm that scheduled jobs do not run twice on the others. The cron setting should be controlled deliberately, for example by disabling automated cron on web nodes and calling it from a single scheduler, and the test should show that job logs contain one run per schedule.
Finally, test change and recovery. Perform a rolling release across the web nodes, one at a time, with configuration import and database updates handled by the agreed pipeline, and count failed requests against a failure threshold the team sets for itself. Then run a rollback of that same release and confirm the site returns to the prior code and configuration. Include a restore test: restore the most recent backup of the database and the file store into a clean environment that has never held the live site, and confirm the restored site boots, logs in and shows expected content. Record the evidence for every test: timestamps, load balancer logs, error rates, replication lag, runbook deviations, restore duration and sign-off by the owner. Every threshold in this plan, including the acceptable failed-request count, the maximum data loss window and the acceptable outage time, should be set by the business owner, not copied from this page.
Questions buyers ask about Drupal high availability
How much more effort and cost does a high availability Drupal build add compared with a single server?
A high availability build adds cost mainly because it adds components that must be built, tested and kept running: a load balancer, two or more web nodes, shared file storage, a replicated or clustered database, and an external cache such as Redis or Varnish. The size of the increase depends on how many environments you need (production, staging, disaster recovery), whether the database and storage are already managed by a platform team, how much automated testing and deployment work is required, and how often failover must be exercised. Ask any partner for a quote built from a written scope that lists each component and who operates it after handover. Drupal itself carries no license fee under GPL-2.0-or-later, so the cost is in infrastructure, build labor and ongoing operations.
How long does a Drupal high availability project take to deliver?
The duration depends on scope, the number of environments, how much of the infrastructure already exists, and how much testing is required before go-live. A project that reuses an existing database platform and adds only web nodes and a load balancer is usually shorter than one that also designs replication, shared storage and zero-downtime deployments from scratch. Failover testing and a rehearsed cutover add time that cannot be skipped in a regulated environment. Do not accept a timeline without a written plan that lists phases, dependencies on your teams, test windows and acceptance criteria. Confirm the plan against your change calendar before work starts.
What does your team need to provide for a Drupal high availability build?
Expect to provide access to the cloud accounts, data center networks or virtualization platform where the nodes will run, and to the DNS and certificate processes that will front the load balancer. Your team must confirm who owns the database and shared file storage after handover, because those layers carry most of the operational risk. You also need a named approver who can authorize failover tests and production changes, and who is available during test windows. Agree these responsibilities in the written scope so that infrastructure, security and application owners know what they are accountable for.
Can our own team build and run Drupal high availability without an outside partner?
Yes, if the team already has working skills in Drupal administration, Linux server operations and database operations, and if it has the time to build and test the design. The team should be comfortable with load balancer health checks, session handling, shared file storage permissions, database replication and cache invalidation. A written runbook is the deciding factor for operations: it should cover normal deployments, node replacement, database failover, cache flushes and rollback steps, and it should be tested by someone other than the author. If one of these skills is missing, that gap is usually the reason to bring in outside help for part of the work.
Does Drupal have a license fee for a high availability setup?
No. Drupal core and contributed projects hosted on Drupal.org that are derivative works of Drupal are licensed under GPL-2.0-or-later, and there is no paid edition of Drupal itself. Your recurring costs come from the infrastructure you run, such as compute, load balancers, managed databases, storage, caching services and monitoring, along with the people who maintain them. Some hosting providers or managed database services charge license or support fees for their own products, so confirm those terms separately. Also check any commercial contributed modules or third-party services your design depends on.
What must we confirm with our hosting provider or database vendor before building Drupal high availability?
Confirm the features and limits of the platform you run on before the design is fixed. Ask whether the provider supports the load balancer health checks, session affinity or stateless design, shared file storage type, and private networking you plan to use. For the database, confirm the replication or clustering model, the failover mechanism, backup and point-in-time recovery options, and the supported version. Ask about maintenance windows, service level terms and support response for production incidents, and get the answers in writing. Where a capability is not confirmed, treat it as an open risk in the plan rather than an assumption.
What happens during a failover test on a Drupal high availability site?
A failover test deliberately removes a web node, the cache, or the primary database so the team can confirm that traffic moves to healthy components without losing content or sessions. Before the test, the scope should define the failure scenarios, expected behavior, rollback steps, the test window and the named approver who signs off the result. Engineers should watch load balancer health checks, error rates, queue backlogs and database replication lag during the test. Record the results and the time to recover, then update the runbook with anything that surprised the team. Repeat the test after significant changes to the platform or the Drupal codebase.
How DeployOpen scopes, builds and hands over Drupal HA work
DeployOpen plans, implements, hardens, documents and supports self-hosted open-source platforms inside the client's own infrastructure, including Drupal high availability. Work starts from a written, fixed scope, so the load balancer, shared storage, database, cache and deployment decisions are agreed before any build begins.
How we scope
- Review the current Drupal version, PHP runtime and hosting so the HA design starts from the real stack.
- Agree in writing which web nodes, shared file storage, database replication and cache layers are in scope.
- Confirm the deployment model, including how Configuration Management changes reach production without downtime.
- Confirm the expected load, failover goals and who owns each layer before a quote is issued.
How we build
- Deploy the web tier behind a load balancer with session handling and file storage shared across nodes.
- Set up database replication and test failover with the client's own monitoring in place.
- Add external cache layers such as Redis or Varnish and verify cache invalidation across nodes.
- Test each failure case, including a node loss during a release, and record the results.
How we hand over
- Deliver architecture diagrams, runbooks for failover, backup and restore, and rollback procedures.
- Walk the client's operations team through deployment steps, alerts and the configuration sync workflow.
- Document every contributed module and settings change that the HA design depends on.
- Provide a verification checklist the client can rerun after upgrades or infrastructure changes.
How we support
- Offer ongoing support, upgrades and continuous testing as a retainer, agreed in writing.
- Plan HA-aware upgrades around the monthly bugfix and Wednesday security release windows.
- Review the HA design when Drupal 10 or Drupal 11 upgrades change PHP or module requirements.
- Confirm with your team which support tasks sit in the retainer and which remain internal.

