Why Drupal performance and caching is harder than enabling a module
A Drupal site that slows under peak traffic or after a content launch usually has a performance problem spread across several layers, and the team has to decide whether to tune it in house or bring in a partner. Drupal performance and caching is a layered job across Drupal core caches, the cache backend, the web tier and the edge. Each layer can hide the problems of the others, so a fix applied in one place can leave the real bottleneck untouched. Before anyone changes a setting, the team should know which layer is slow, and that starts with measurement, not configuration. Correct caching in Drupal depends on cache tags and cache contexts. Tags tell Drupal which cached items must be invalidated when a piece of content, a configuration entity or a user changes. Contexts tell Drupal which variations of a page are valid, such as the current user's roles, the language or the URL query. When these metadata are missing or wrong, a page can be served stale to every visitor, or personalized content can leak to anonymous users. Custom blocks, custom modules and some contributed modules are common places where this metadata is lost, so the reader should ask who reviews cacheability in the code and how that review is tested. Slow Views and slow database queries must be profiled before caching is applied. Caching a slow view only hides the cost until the cache expires or is cleared, and a cold cache after a deployment can then produce the slowest page loads of the day. Profiling should identify the expensive queries, the entity loads and the render steps, then confirm whether the fix is an index, a query change, a view redesign or a cache policy. Ask any partner to show the profiling output that supports each proposed change. Several features make caching harder than it looks. Personalization, authenticated users, editorial workflows and third-party integrations each change what can be cached and for how long. Logged-in editors who see draft content and unpublished revisions bypass most anonymous page caching, so a site with a large editorial team may have less cacheable traffic than its public numbers suggest. Third-party integrations add external calls whose latency and freshness rules must be understood, and each one may need its own cache lifetime or invalidation path. This section does not give performance figures, because results depend on the site's own measurements: its traffic mix, content volume, hosting, module set and the share of logged-in users. Before asking for a quote, the team should collect a baseline for page response times, cache hit ratios and database load under a realistic traffic pattern, and ask the partner how it will measure improvement against that baseline.
Which caching layers you tune, from page cache to the edge
Drupal caches at several layers, and each one serves a different audience and fails in a different way. The core caches handle anonymous and personalized pages, cache tags and contexts control when entries expire, and the cache backend, reverse proxy and CDN sit around the site. Start with the layer that serves the most traffic, measure hit rates, and check Views and database queries when the cached layers look correct but pages stay slow.
Core page cache for anonymous requests
Drupal core stores the full rendered response for visitors who are not logged in, so repeat requests skip most bootstrap and rendering work. For public sites this layer often carries the bulk of traffic. Check that the page cache is enabled on production, that pages a visitor cannot personalize are eligible for it, and that no module sets a session cookie for anonymous users in a way that silently disables caching across the site. Confirm the behavior on a staging copy with a load test, because hit rates depend on your own content and traffic.
Dynamic page cache and render cache
These two core caches handle output that varies by user or context. The dynamic page cache stores responses for authenticated users per context, and the render cache stores individual rendered elements, such as a block or a teaser, so they can be reused across pages. The main risk is a block or element that renders per-user data without declaring the correct context, which can expose one user's output to another or quietly lower hit rates. Review custom blocks and any module that renders current-user data during code review.
Cache tags and contexts for invalidation
Each cached item carries cache tags naming the entities it depends on, such as a node or a taxonomy term, and cache contexts naming the variables it varies by, such as user role, language or URL. When content changes, Drupal invalidates only the entries with matching tags. Misconfiguration usually appears as stale pages after an edit or as pages cached too broadly. Check custom render arrays and controllers for missing cacheability metadata, and test edits against cached pages before sign-off.
BigPipe for authenticated pages
BigPipe is a core module that sends the cacheable parts of a page first and streams placeholders for personalized or slow sections as they finish. Logged-in users see most of the page sooner, which matters where a full-page cache cannot serve each user the same response. Check that placeholders render correctly in a browser with JavaScript enabled, and test with your front-end theme and any custom scripts that touch the page, since they can interfere with placeholder replacement.
Cache backend: database, Redis or Memcache
Drupal stores cache entries in the database by default. Larger or multi-server sites often move cache bins to an in-memory store such as Redis or Memcache through a contributed module, which reduces database load and shares the cache across web nodes. The choice depends on your hosting, the number of web nodes and your operations skills. Check that the backend is reachable from every web node, that cache bins are assigned deliberately, and that a backend outage has a tested fallback, because a failing cache layer can slow or break requests.
Reverse proxy and CDN at the edge
Varnish or another reverse proxy can sit in front of Drupal and serve cached full responses before requests reach PHP. A CDN serves static assets such as CSS, JavaScript, images and files from locations closer to users. Proxy rules must respect Drupal's cache headers and session cookies, or the proxy may serve one user's page to another or cache authenticated responses. For the CDN, confirm which paths are cached, how purges reach it after content changes, and how file URLs stay stable across deployments.
Which cache backend and edge layer fit your traffic
This table compares the main cache backend, edge, page delivery and hosting choices for a Drupal site, with the operational work each one adds. Read each row against your traffic pattern, your hosting environment and your team's capacity to run another service. The main takeaway is that every cache service you add becomes one more component to monitor, patch and back up, so start with the simplest option that meets your load.
| Option | When it fits | What it costs operationally |
|---|---|---|
| Default database cache backend | Low to moderate traffic, a small team, or a first release where simplicity matters most | No extra service. Cache load falls on the database, so watch query volume and database capacity as traffic grows |
| Cache bins moved to Redis or Memcache | Authenticated traffic or frequent cache writes are loading the database, or several web servers need a shared cache | A separate service to size, patch, secure, monitor and back up or rebuild. Cache data is generally disposable, so plan for cold starts rather than restores |
| Varnish in front of Drupal | Large volumes of anonymous page views, with cacheable responses and a team able to write and test cache rules | VCL rules to write, test and review with each change. Purge and invalidation paths must be wired to Drupal cache tags and verified |
| CDN alone without Varnish | Mostly static assets and anonymous pages, with cache headers Drupal sends that the CDN can honor | Lower server-side components to run. Confirm which paths, cookies and query strings the CDN caches, and how purges reach it |
| Anonymous page caching only | Most visitors are anonymous, or personalized content is limited to small blocks | Lowest complexity of the page-level options. Dynamic content for signed-in users is served uncached, so capacity planning must reflect that |
| BigPipe for authenticated users | Logged-in users see pages with a mix of cacheable and personalized regions, and perceived load time matters | Requires testing of each personalized block and of the front-end behavior it depends on. Confirm compatibility with your theme and any caching proxy |
| Views cached with time-based expiry | Listings change on a predictable schedule and some staleness is acceptable to the business | Simple to reason about, but editors may see outdated content until expiry. Tune intervals per view and document them |
| Views cached with tag-based invalidation | Content changes must appear quickly, and editors expect updates after saving | Requires correct cache tags in custom code and contributed modules. Verify invalidation during testing, since missed tags cause stale pages |
| Managed hosting platform | Your team lacks capacity to run cache and edge services, or the hosting provider already bundles them | Recurring platform fees and less control over versions, rules and network placement. Ask which cache and edge components are included and who patches them |
| Self-hosted cache services inside your network | Data residency, network policy or audit requirements call for services under your own control | You own sizing, patching, backups, access control and monitoring. Confirm that the chosen Redis or Memcache and Varnish versions support your PHP runtime and Drupal version, since Drupal 11 requires PHP 8.3 or later |
How to build a caching stack in a safe order
This sequence adds Drupal caching in layers, measuring first and proving each layer on a staging copy before the next one goes in. The result is a site that is faster under load while editors still see fresh content and logged-in users still see their own pages.
Record a performance baseline on staging
Work on a staging copy that matches production in code, configuration and a representative content volume. Measure page load times, database query counts and the slowest Views on a set of representative pages, including anonymous landing pages, a long listing, a node page and an authenticated dashboard. Record the results in a shared table so every later change can be compared against the same pages. The step is done when the team has a baseline document that a second person can reproduce on the same staging copy.
Confirm page and dynamic page cache behavior
Check that Drupal core's page cache serves anonymous requests and that the dynamic page cache handles blocks and content for logged-in users. Identify blocks, plugins or custom code that mark responses as uncacheable or add cache contexts that split the cache too finely, such as per-request values or session data. Fix those in code or block configuration, then repeat the baseline measurements. The check is a response header review on sample URLs for anonymous and authenticated users, showing the expected cache status for each.
Optimize slow queries and Views before adding cache
Profile the slow pages from the baseline with a database query log or an application profiler, and trace each expensive query to a Views display, entity query or custom service. Simplify the query, remove unneeded joins or filters, or add database indexes where the execution plan shows full scans, then test the change against the same pages. Caching a slow query only hides the problem until the cache is cleared, so this step comes first. The check is a query count and page timing comparison against the baseline, with each change recorded alongside its result.
Move cache bins to the chosen backend
Configure the cache bins for the backend the team selected, such as Redis or Memcache, in staging only. Confirm that the backend is reachable from every web node, that its memory and eviction settings are documented, and that failure of the backend degrades to the database rather than to an error page. Then test that cache tags invalidate correctly: edit a node, a taxonomy term and a menu item, and confirm that each change appears on every page that displays it, including listings and blocks. The step is done when a test edit appears on the correct pages on every run and no stale page remains.
Enable BigPipe where authenticated pages benefit
Turn on BigPipe, the core module that streams cached page regions after the initial shell, only on authenticated pages where personalized regions are slow and the rest of the page can be cached. Review each affected template with the front-end team to confirm that placeholders render correctly, that no sensitive content is cached in a shared location and that scripts still load in the expected order. Compare the time to first meaningful content against the baseline for logged-in users. The check is a side-by-side test for at least one editor role and one standard authenticated role.
Add Varnish or a CDN with authenticated exclusions
Place Varnish or a CDN in front of the web nodes, with rules that bypass caching for requests carrying session cookies, administrative paths, form submissions and any route that renders personalized content. Confirm the reverse proxy respects the cache headers Drupal sends and that the exclusion rules are tested for each logged-in path. Then connect publish events to purge requests for the affected URLs, and confirm that publishing a test node clears the edge cache for the pages that show it. The step is done when anonymous edits appear at the edge within the purge process and logged-in pages are never served from the shared cache.
Review hit ratios and document the runbook
Once every layer is in place on staging, review cache hit ratios for the database backend, the page cache and the edge tier over a representative period of traffic, using the logs and metrics each layer exposes. Confirm which hit ratios are expected for which pages and record the thresholds that should trigger an investigation. Document the purge procedure, the cache clear commands, the backend failover behavior and the rollback steps, then rehearse them once before production. The check is a signed-off runbook and one rehearsed purge and rollback on staging.
What drives performance work cost and how to keep it down
This table lists the factors that change how much effort Drupal performance and caching work takes, with a containment step for each. Read each row as a question to answer during scoping, since the same driver can add effort in one site and almost none in another. The main takeaway is that most of the effort comes from uncached or personalized output, so fixing the cache policy early keeps the written scope small.
| Driver | Why it changes effort | How to keep it down |
|---|---|---|
| Number of content types, views and blocks with personalized output | Each personalized view or block needs its own cache contexts and tags, so every one must be tested for correct caching and invalidation. | Isolate personalized blocks with contexts and lazy builders, and list the personalized views in the written scope rather than auditing the whole site. |
| Authenticated traffic share | Logged-in users bypass the page cache in Drupal core, so high authenticated traffic puts load on PHP and the database and shifts work toward dynamic caching. | Confirm the share from analytics before scoping, and decide with the business which authenticated pages must be fast and which can stay uncached. |
| Custom modules that render uncached data | Custom code that builds render arrays without cache metadata forces uncached responses, and each module needs review and tests. | Require cache metadata (max-age, contexts, tags) in custom module code review, and limit the performance review to a fixed list of custom modules. |
| Third-party APIs called on page render | Live calls to external services during render add latency and failure modes, and often need timeouts, fallbacks and cached responses. | Move calls into queued or scheduled jobs that store results, and document which external calls are allowed on the request path. |
| Environments that must match production cache settings | Development, staging and test environments with different cache backends or settings hide problems and need extra testing time to confirm parity. | Keep cache settings in version-controlled settings files, and confirm which environments must match production before work starts. |
| Cache backend and CDN or Varnish topology already in place | Existing Redis, Memcache, Varnish or CDN layers may need configuration, purge rules and header alignment with Drupal, or they may need to be added. | Inventory the current stack first, then scope work against the existing layers instead of replacing them, and confirm who operates each layer. |
| Compliance requirements such as logging of access to personal data | Access logs, retention rules and cached personal data in shared caches add review steps and may restrict which pages can be cached. | Ask the compliance owner which pages hold personal data, document the cache policy for those pages, and keep them out of shared caches where required. |
| Size of the content and media library that drives purge scope | Large libraries with many references produce broad cache tag invalidation, which can slow publishing and needs testing under load. | Test purge behavior on a representative content set, and agree in writing which content types and pages are in the performance scope. |
How caching changes on a single node, HA cluster or air-gapped network
On one web server, Drupal's caching can stay close to its defaults. The database cache backend holds render, dynamic page and configuration data, and a local Varnish instance or a CDN can sit in front of the site if traffic requires it. Because there is only one application process pool, cache tags and invalidations are seen by the same node that wrote them, so no shared cache service is strictly required to keep content consistent.
What to plan for on a single node:
- Database cache load: Cache reads and writes use the same database as content, so confirm that database capacity covers both under peak traffic.
- Local Varnish placement: If Varnish runs on the same host, confirm memory allocation and how purge requests reach it from Drupal.
- Core page and dynamic page cache settings: Confirm which cache contexts and max-age values are used for authenticated and anonymous users.
- Single point of failure: A node restart clears in-process state, so confirm that warm-up behavior and rebuild time are acceptable.
- Upgrade path: Confirm that moving to a shared cache backend later does not require redesigning cache tags.
Before go-live, ask the team to confirm the exact Drupal, PHP, web server and database combination against the platform's current system requirements, because supported pairings change between releases.
When several web nodes sit behind a load balancer, each node keeps its own in-process state, so a cache tag invalidated on one node must be visible to all of them. A shared cache backend such as Redis or Memcache gives every node the same tags and invalidations. Without it, a node can serve stale content after an editor publishes, which is the most common symptom of a misconfigured multi-node cache.
What to plan for across nodes:
- Shared cache backend: Choose Redis or Memcache, then confirm the Drupal module and client library versions with your platform team.
- Consistent purge path: Every node must receive invalidations, and any external Varnish or CDN purge must reach the correct front end.
- Session and file storage: Confirm that sessions and shared files are stored centrally so that nodes do not depend on sticky sessions.
- Cache backend failure behavior: Confirm what happens when the shared cache is unavailable, including whether requests fall back to the database and how that affects load.
- Network placement: Place the cache service on a network path with low latency to all web nodes.
Before go-live, ask the team to test a publish on one node and confirm the change is visible from every other node within the expected window.
In an orchestrated deployment such as Kubernetes, pods are created, replaced and scaled automatically, so cache state must live outside any single pod. The cache service and the purge endpoint must be reachable from every pod, and cache configuration must be identical across replicas. Service discovery, network policies and secret handling become part of the caching design, not just the infrastructure layer.
What to plan for in orchestrated environments:
- Cache service as a managed workload: Decide whether Redis or Memcache runs inside the cluster or as a managed service, and confirm its persistence and failover model.
- Network policies: Confirm that web pods can reach the cache service and the purge endpoint, and that only the intended components can call the purge endpoint.
- Purge endpoint exposure: Restrict who and what can send purge requests, and confirm how requests are authenticated.
- Configuration parity: Confirm that cache settings come from the same configuration source for every replica and every environment.
- Pod lifecycle: Confirm that warm-up and cache rebuild behavior is acceptable during rolling updates and autoscaling events.
Before go-live, ask the team to run a rolling update during a test window and confirm that cache invalidations and purges still reach every replica.
On an air-gapped network, there is no public CDN and no route to external package registries, so both the delivery path and the supply chain for cache components change. Static assets must be served from internal infrastructure, and every module, library and cache service must be installed from approved internal mirrors. Caching design is then constrained by what can be built and updated inside the network, not only by what Drupal supports.
What to plan for in air-gapped environments:
- Internal static asset delivery: Replace the CDN with internal static asset delivery, and confirm how assets are versioned and invalidated.
- Internal mirrors: Install all contributed modules, Composer dependencies and cache service packages from approved internal mirrors, and confirm how updates are approved and transferred.
- Cache service approval: Confirm that Redis, Memcache or Varnish is permitted under the organization's software approval process and that its images or packages are scanned.
- Update cadence: Plan how security releases from Drupal's monthly and security windows are brought across the boundary and tested before deployment.
- Purge scope: Without an external CDN, confirm which purge operations are still required and which internal components receive them.
Before go-live, ask the team to confirm the exact supported combination of Drupal core, PHP, web server and database against the current system requirements, and to document how each cache component was obtained and verified.
Keeping cache layers from leaking private data
Caching makes Drupal fast, but every cache layer also stores copies of pages, responses and values that belong to specific users or to the operator. The six cards below cover the risks that recur in caching setups, each with the control that closes it and the check that proves it works.
Personalized pages served to other users
An edge cache or reverse proxy in front of Drupal may store a page built for one signed-in user and return it to the next visitor who requests the same URL. This happens when cache rules ignore session cookies or when Drupal cache contexts do not cover the values that change the page. The control is a bypass rule for session cookies at the edge, combined with cache contexts for the current user and roles. Check it by requesting a personalized page with two accounts and confirming that each receives its own content.
Caching authenticated and form pages
Pages rendered for logged-in users, account screens and forms carry session data and form tokens that should never sit in a shared cache. Bypass rules should cover the session cookie, administrative paths and the routes that accept form submissions, and these responses should not carry public cache headers. Ask the implementation team to show the response headers for a logged-in request and for a form page, and to confirm that a cached token cannot be replayed.
Purge endpoints without authentication
Cache purge endpoints let an operator clear Varnish, CDN or Drupal cache entries on demand. If they accept requests without authentication, anyone who can reach them can empty caches, which pushes load back to the origin, or invalidate content at moments that suit an attacker. Restrict purge access to the deployment network or to a signed token issued to the release pipeline, and store that token in the secrets manager. Confirm that an unauthenticated purge request from outside the allowed network is refused.
Sensitive values in shared cache backends
Redis and Memcache are fast because web nodes share them, and any host that can reach the port can read the same data. Keep the cache backend on a private network segment, allow connections only from the web tier, and enable authentication and transport encryption where the chosen backend and Drupal module support them. Confirm the supported options in the module documentation and the backend's own documentation. Keep secrets and API keys out of cache bins, because cached values can outlive the session that created them.
Debug and statistics pages left open
Verbose error output, development services, cache statistics dashboards and status pages can reveal file paths, module versions and cache key patterns to anyone who finds them. Production settings should disable development services and on-screen error display, and administrative reports should sit behind role checks and, where possible, the internal network. After each deployment, crawl the public routes without logging in and confirm that no debug or statistics path returns content.
Monitoring cache modules for advisories
The Drupal Security Team publishes advisories for core and contributed projects with CVE identifiers and risk scores, and ships security fixes in Wednesday release windows, with security releases on the third Wednesday of the month. Add cache, purge and edge integration modules to the monitored dependency list alongside core, so that a cache-related advisory triggers review. Ask the team who receives each advisory, how a patch is tested in staging, and how the fix is verified in production.
How to prove caching works and fails safely
A caching setup is only proven when tests show that pages update correctly after content changes, that personalized data never leaks through a shared cache, and that the site keeps working when a cache layer fails. Treat these as acceptance criteria for the Drupal performance and caching work, and agree on them before tuning starts. Otherwise the team will judge results by how the site feels on a given day rather than by evidence. Start with functional tests. Edit a node that appears on several pages, such as a teaser on the homepage, a listing view and the node page itself, then confirm that each page reflects the change once the cache tags for that node have been invalidated. Repeat the check for an edit to a taxonomy term or a menu item that feeds a view, because those dependencies are easy to miss. Next, log in as at least two users with different roles and different personal data, such as a saved account field or a role-specific block, and confirm each user sees only their own content. Then request an anonymous page twice and inspect the response headers from the Drupal page cache and from Varnish or the CDN, if one sits in front. Confirm that the second response is served from cache and that the cache-control and cache-tag headers match what your configuration promises. Load tests come next. Run them on a staging environment with a copy of production-like content volume, view counts and user roles, because a small test database will hide slow views and cold cache effects. Record response times and database query counts for the same scripted journeys before and after each caching change, and keep the test harness, traffic mix and warm-up steps identical between runs so the comparison is fair. Ask your team or partner to state, in writing, the acceptance thresholds for response time, query count, error rate and cache hit ratio for each key page type. No benchmark figures are supplied for this topic, so these numbers must come from your own traffic goals and infrastructure. Failure tests show whether the design fails safely. Stop the cache backend, such as Redis or Memcache, and confirm that Drupal still serves pages from the database. Expect slower responses, and decide in advance what slowdown is acceptable and whether the site should show an error for personalized pages. Stop Varnish or the CDN and confirm that traffic reaches Drupal directly, that origin capacity holds, and that the origin is not exposed in a way your security team would reject. The most important test is a purge failure: simulate a failed invalidation request, then log in as a user with personal data and confirm that stale personalized content is not shown to anyone else, and that a failed purge is logged and alerted. Record each result, and rerun the suite after every change to cache configuration, module upgrades or infrastructure moves.
What to monitor, purge and document after launch
After launch, cache performance depends on routine operations. The six items below connect monitoring, content model reviews, purges, updates, backups and documentation, so operations staff can keep the cache behaving as designed and hand it to the next team intact. Each one has an owner, a schedule and a record that a reviewer can check.
Monitoring cache performance
Track cache hit ratios for the page cache, dynamic page cache and any external cache backend, along with response times, database load and slow query logs. A falling hit ratio after a deployment often points to a new cache tag, a personalized block or an exclusion rule that was not in the test plan. Also watch the health of Redis or Memcache and the proxy or CDN layer, since a silent cache outage pushes full page loads onto the database. Agree alert thresholds with the team during launch, using the baseline captured before go-live.
Scheduled review of Views and blocks
Review Views and block placements on a fixed schedule and whenever the content model changes. A new content type, a field rename or a taxonomy change can turn a cached listing into a query that scans far more rows than it did at launch, or add a cache context that splits the cache into many variants. Check each View's cache settings and exposed filters, and confirm that custom blocks declare their cache tags. Record the review date and the person who signed off.
Purge procedures and ownership
Write a purge procedure for each cache layer: Drupal's internal caches, the external cache backend, the reverse proxy and the CDN. Name who may run each purge, who approves a full purge on a production site, and when a targeted tag-based invalidation is enough. Full purges can send a traffic spike to the origin, so the runbook should include a warm-up step and a rollback contact. Test the procedure in a non-production environment before the first live use.
Keeping core and contributed modules current
Schedule updates around Drupal's published release windows. Core bugfix releases come out on the first Wednesday of each month, and security releases on the third Wednesday. Test each update on staging with cache-sensitive paths, because contributed modules that touch caching, Views or CDN integrations can change how pages are cached. Track the PHP version each release requires, since Drupal 11 requires PHP 8.3 or later.
Backing up cache configuration
Back up the configuration that defines cache behavior along with the database. That includes Drupal's cache bin settings in settings.php, the cache backend connection definitions, reverse proxy rules, CDN behavior such as cache TTLs, and exclusion paths. Store these files in version control with the rest of the codebase, and keep a dated copy of CDN and proxy settings exported from the provider's console, since those are often edited outside the repository.
Documenting the cache policy and baseline
Document the cache policy, exclusion rules, purge runbook and performance baseline in one place the next team can read. The policy states which pages, roles and tags are cached, for how long and why. The baseline records hit ratios, response times and database load measured at launch under a stated load profile. Without these records, a future team cannot tell whether a slowdown is a regression or the expected result of a change, and cannot rebuild the setup.
How much does Drupal performance tuning cost and what do you need to provide?
Does Drupal have a license fee for performance tuning work?
No. Drupal core is licensed under the GNU General Public License, version 2 or later (GPL-2.0-or-later), and there is no paid edition of Drupal itself. Contributed modules hosted on Drupal.org that are derivative works of Drupal carry the same license. Your spending on performance work therefore goes to labor, hosting and any third-party services you choose, such as a managed cache service, a CDN or a monitoring product. Each of those has its own pricing and terms, so confirm them directly with the provider. Ask your partner to list third-party services separately in the quote, so you can see which costs recur every month or year and which are one-time setup effort. The licensing details are published on the Drupal.org licensing page.
What drives the cost of a Drupal caching and performance project?
The main cost drivers are the size and variety of the site and the number of moving parts you want tuned. Scope of pages is the largest lever: the number of templates, content types and listing views that need profiling and cache-tag work sets most of the effort. Personalization matters because per-user content limits what can be cached at the page level and often requires careful cache contexts. The edge layer, such as Varnish or a CDN in front of Drupal, adds configuration, purge rules and testing. Number of environments multiplies test and deployment effort when development, staging and production each need matching cache settings. Integrations with external APIs add invalidation paths that must be tested. A fixed-scope quote should show each driver as its own line, so you can see what changes if one of them grows.
Can our in-house team tune Drupal caching without outside help?
Yes. A team with Drupal and web operations skills can tune caching in house. Core page cache and dynamic page cache behave predictably once the team understands cache contexts, cache tags and max-age settings, and the Drupal.org documentation covers BigPipe and cache backends such as Redis or Memcache. The harder parts are profiling slow queries and Views under production-like load, and designing cache invalidation so editors see fresh content without flushing everything on every save. Those tasks benefit from experience, because a wrong invalidation rule either serves stale pages or defeats the cache entirely. If your team has not run load tests or profiling before, consider a short design review before you commit, and agree in writing what that review will deliver.
How long does Drupal performance tuning take from start to finish?
No fixed duration can be given without a baseline. The time needed depends on how slow the site is today, how many page types and views are involved, whether personalization or an edge layer is in scope, and how many environments must be verified. Before work starts, the partner should measure a baseline on agreed pages and traffic patterns, then propose phases with dates. Ask for the timeline in the written quote and check that it names the baseline measurements, the test cycles and the cutover window. Also check how the schedule accounts for Drupal release windows. Bugfix releases arrive on the first Wednesday of each month and security releases on the third Wednesday, so the plan should say how updates that land mid-project are handled. Confirm all dates with the partner before you rely on them.
Which inputs must our team hand over before a tuning project starts?
Your partner needs five inputs before profiling starts. Staging access with a copy of production configuration and representative content, so tests reflect a production-like page structure. Traffic data from analytics or web server logs, showing peak periods, top landing pages and the share of logged-in versus anonymous visitors. Hosting access to the web servers, database and any cache or CDN accounts, under an agreed change process. A list of critical pages, such as the home page, service or product listings and forms, ranked by business importance. Acceptance criteria written as measurable targets agreed with your team, such as response time on named pages under a named load profile. Without acceptance criteria, a tuned site can pass technical checks and still fail the business. Provide these inputs in writing at kickoff so that delays do not sit with the vendor.
What should a written quote for performance work include?
Ask for a written scope that lists the pages, views, cache layers and environments in and out of scope, along with the assumptions behind each item. The quote should name the test plan: the baseline measurements, the load profiles, the tools used, the pass criteria and who signs off each stage. Require handover documents as deliverables, including a description of cache contexts and tags per content type, the invalidation rules, the edge configuration, the monitoring dashboards and a runbook for clearing caches and diagnosing slow pages. Ask which items are one-time work and which recur, such as retainer support or tests after monthly releases. Check the acceptance steps, the change control for out-of-scope requests and what happens if the baseline points to a different bottleneck than expected. Most engagements are fixed-scope, so these terms should be agreed in writing before work begins.
Should we tune performance before upgrading from Drupal 10 to 11?
Plan the tuning on the version you will run. Drupal 10 reaches end of life on December 9, 2026, and Drupal 11 is the current major version, requiring PHP 8.3 or later. Caching work completed on Drupal 10 may need retesting after the move, because core cache behavior and contributed modules change between versions. If the upgrade is scheduled in the same window, sequence the work so the caching design is validated on the target version, otherwise the team will tune twice. Ask the partner to document which cache settings depend on the Drupal version and whether the test plan reruns after the upgrade. Also confirm that your hosting supports PHP 8.3 before the upgrade begins, since the PHP version is a separate prerequisite that can block the upgrade on its own.
How DeployOpen works on this
DeployOpen plans, implements, tests, documents and supports Drupal performance and caching inside your own infrastructure, whether that is your cloud account, data center or air-gapped network. Work usually runs as a fixed-scope engagement with scope, deliverables and timelines agreed in writing before any tuning starts.
How we scope
- Profile the current site under representative load to identify slow pages, expensive views and cache hit rates before naming any change
- Record which caching layers are in scope: core page and dynamic page caches, cache backends, BigPipe, and any reverse proxy or CDN in front
- Agree in writing which environments, traffic patterns and pages the performance targets apply to, and how they will be measured
How we build
- Tune cache metadata, cache tags and contexts on custom modules and views so invalidation is correct before adding more caching
- Configure the agreed cache backend, such as Redis or Memcache, and reverse proxy or CDN rules, with cache bypass for authenticated and editorial traffic
- Test cache invalidation after content edits, role changes and deployments, and record results against the baseline profile
How we hand over
- Deliver configuration as code through configuration management, so cache settings move between environments with the rest of the site
- Document cache layers, invalidation paths, purge procedures and known exceptions in a runbook your team can operate
- Walk your engineers through profiling steps and the checks they should repeat after each Drupal or module update
How we support
- Offer ongoing support, performance re-checks after major releases and continuous testing as a retainer, separate from the initial fixed-scope work
- Review cache behavior when contributed modules change, since cache metadata bugs often appear after module updates
- Confirm with your team which Drupal and PHP versions the tuning must support, because the platform requirements change over time

