Acquia Developer (D10) study materials
Acquia Developer (D10) study resources

Acquia Developer (D10): Performance, Caching, and Security

Acquia Developer (D10) · Work through your exam, one topic at a time.

All guide sections

Performance, Caching, and Security

What to know

Drupal's render pipeline is cacheable: render arrays carry #cache with keys, contexts, and tags. Cache contexts vary output (e.g., user.roles, url.path); cache tags invalidate (e.g., node:5, config:system.site); max-age sets lifetime. The Internal Page Cache serves anonymous pages; Dynamic Page Cache caches rendered responses for authenticated users; BigPipe streams placeholders.

Cache invalidations happen when entities save (tags), config changes, or cron clears. drush cr rebuilds caches. Varnish/CDN sit in front; Acquia uses Varnish with tag-based purging.

Performance levers: enable CSS/JS aggregation, use lazy image loading, avoid #cache max-age: 0 unless necessary, prefer cache.backend.* (Redis/Memcache) for high traffic, and keep views paginated.

Security: output escaping (Twig auto-escape), input validation, CSRF tokens on forms, and the permission system. Avoid |raw on user data. Use Xss::filter() for allowed tags. SQL injection is prevented by placeholders. File uploads need extension validation. The security advisory policy means core and contrib get SA releases; keep composer outdated in check.

Traps

  • Contexts vs. tags: contexts vary cache keys; tags invalidate. Mixing them up is a classic question.
  • max-age: 0 disables caching for that element-sometimes required, often a mistake.
  • BigPipe vs. Dynamic Page Cache: both serve authenticated users; BigPipe streams, DPC caches.
  • |raw bypasses escaping and is a common XSS trap.
  • Varnish purge relies on cache tags; missing tags mean stale content.

Rule of thumb

If output depends on who or where, add a cache context. If it depends on what data, add a cache tag. If it must never cache, set max-age: 0 deliberately.

Worked example

A block showing the current user's name needs contexts: ['user']; a block listing nodes needs tags: ['node_list'] so new nodes invalidate it.