Drupal feeds

Jacob Rockowitz: Vibing Drupal: Tale 2 - Using AI to maintain a module, exploring the AI-possible

Drupal Planet -

Introduction

Adopting AI can feel overwhelming, so I am sharing a few tales from my experience creating, maintaining, and assisting with contributed Drupal modules. AI can do a decent job building a "greenfield" Drupal module from scratch, so my first tale is about using AI to build and contribute a module. For my next tale, I want to talk about using AI to maintain an existing "brownfield" Drupal module.

Growing up in NYC, I found brownfields often intimidating, with some so toxic that it can take years for backhoes and dump trucks to remove the contaminated topsoil before construction can begin. With code, a brownfield can contain technical debt, orphaned code, missing tests, etc. Simply put, a brownfield contains unknowns, which means more things can go wrong while working on it. Sometimes a brownfield is so big you need heavy machinery to maintain it, and that is exactly how I felt about using AI on the Schema.org Blueprints module.

Maintaining a large module using AI

Gradually, I have been experimenting with AI to help maintain the Schema.org Blueprints. At first, I would just throw a one-shot prompt at the AI to address a single issue, and it would do a decent job diagnosing and resolving the problem. As I became more confident steering the AI, I started asking it to create issue forks, commits, pushes, and even MRs. As I previously stated in my AGENTS.md I always have "Require me to review all changes before committing and pushing code." and most models respect this rule.

My comfort level reached a point where I am creating {module}-issue-maintenance agent skills that extend my drupalorg-issue-maintenance skills. These maintenance skills have agents to track remote issues in...Read More

joshics.in: Drupal 12 and the End of Legacy Debt: A Forced Modernization for Enterprise Engineering

Drupal Planet -

Drupal 12 and the End of Legacy Debt: A Forced Modernization for Enterprise Engineering bhavinhjoshi Tue, 10/06/2026 - 14:02

Just last month, a prospective client came to Joshi Consultancy Services asking for a cheap cron script to fix a runaway disk usage issue. The reality? They were bleeding money on a deep architectural flaw in their Drupal ingestion pipeline. We see this constantly. For years, the enterprise software industry tolerated a quietly expensive habit: carrying technical debt forward.

Historically, major CMS upgrades were treated as little more than UI refreshes. Agencies seamlessly dragged deprecated code, outdated PHP environments, and fragile database structures from one major version to the next. The result? Senior engineers stuck acting as caretakers for legacy code, while CXOs bled budget on endless maintenance retainers just to keep the lights on.

With the December rollout of Drupal 12, that loophole permanently closes.

The platform is fundamentally altering the rules of engagement. Instead of merely suggesting best practices, Drupal 12 enforces strict architectural modernization right at the server level. Here is why this shift is a massive win for both engineering teams and business leadership.

The Eradication of Deprecated APIs

Spaghetti code. We all hate it. But until now, deprecated code could linger in a system for years, propped up by complex workarounds.

Drupal 12 changes this by aggressively stripping out all deprecated core APIs. The system physically rejects structural laziness. If an agency attempts to stack new logic on top of a legacy foundation, the application simply will not run. You build within clean, modern boundaries from day one. Period.

Enforcing Modern Infrastructure Floors

Previously, organizations delayed server upgrades to save short-term costs, forcing modern applications to run on aging environments.

No longer. Drupal 12 introduces non-negotiable infrastructure floors: a PHP 8.5 minimum runtime alongside raised database requirements (MySQL 8.0 / PostgreSQL 18). This isn't just backend housekeeping. By enforcing these modern tiers, the core framework guarantees a baseline of performance that cannot be compromised by budget-saving shortcuts.

Security as a Structural Guarantee

Enterprise security is too often treated as an expensive, opt-in audit layer applied long after development is complete.

By making Argon2id the default for password hashing, Drupal 12 integrates military-grade resistance against GPU-driven brute-force attacks directly into the core blueprint. For the C-suite, this is an immediate reduction in liability. Security transitions from an ongoing maintenance headache to a baseline structural guarantee.

The Business Outcome: Eliminating the Maintenance Drain

The most profound impact lands directly on the balance sheet.

For CXOs, these forced architectural boundaries solve the most expensive problem in enterprise software: unpredictability. When the core framework refuses to execute legacy PHP and automatically enforces top-tier security standards, the financial drain of technical debt is cut off at the source. Organizations can finally stop paying agency retainers to manage bloated, unmaintainable code.

Drupal 12 is not just a feature upgrade. It is a forced modernization of your engineering culture.

If your organization treats this version bump as a standard IT afterthought, you are actively funding your own future liability. Stop paying for temporary bug fixes. Engineer the blueprint first.

Are your servers, and your budgets, ready for the rollout?

Drupal Drupal 12 Security Drupal Planet Drupal migration Share this Add new comment

DDEV Blog: Docker Provider Performance, 2026: Now Measured Every Night

Drupal Planet -

TL;DR

macOS Docker provider performance has improved significantly over the years, and now all the providers seem to be performing about equivalently. So OrbStack, Docker Desktop, Lima, Colima, and Rancher Desktop are fast and working well.

Introduction

Back in November 2023 we published a hand-run comparison of macOS Docker providers. It was a snapshot: one laptop, one afternoon, one set of versions, and a Google Sheet. It answered the question people were asking, and then it started going stale the moment it was published.

That post is gone now, and this one replaces it, because the way we answer the question has changed. DDEV now runs the same benchmark battery every night, unattended, on every platform and Docker provider we support, and publishes the accumulated history.

Table of Contents Where to see the numbers

The nightly results live at the DDEV performance history dashboard.

The easiest way to find it (and everything else the DDEV GitHub organization publishes) is to start at github.com/ddev/ddev.github.io and follow the "Performance History" link. That repo's README is the index of DDEV's GitHub Pages sites — bookmark it and you don't have to remember any of the other URLs.

The dashboard has two views. Trend over time plots one line per leg so you can see regressions and improvements as they land. Compare environments (latest) gives you a sorted bar chart of each environment's recent median, which is the view that most directly replaces the 2023 post's charts.

Which metric to compare

The harness collects six metrics per run. The one that lines up with the 2023 post is drupal_install_s: Puppeteer drives the Drupal web install wizard end-to-end, in a real browser, through the DDEV router, the web server, and PHP-FPM.

I think it's important that it uses a web-intensive install process for studying web server performance. The interactive installer deliberately breaks each batch step into its own HTTP request and page reload, so every one of those round trips exercises exactly the layer where Docker provider differences show up — bind mount vs. Mutagen, gRPC-FUSE vs. virtiofs, and so on. It's the closest thing in the suite to "what does it feel like to actually use this."

The companion metric drush_install_s runs the same install non-interactively via ddev drush si, which never touches the router or web server at all. If the two track together, filesystem I/O dominates; if they diverge, the gap isolates router/web server overhead. The perf/README.md describes all six metrics and why each one is there.

macOS results

Medians of the nightly runs from 2026-08-31 through 2026-09-30, drupal_install_s in seconds, fastest first. All legs are Apple Silicon (ARM64), all with Mutagen enabled except where noted.

Docker provider drupal_install_s drush_install_s ddev_start_cold_s Rancher Desktop 12.0 9.8 16.5 Lima 12.1 9.9 15.8 Podman (rootless) 12.3 9.9 46.0 Colima (vz) 12.6 10.0 14.4 OrbStack 13.4 10.4 12.2 Docker Desktop 16.7 13.4 21.0 OrbStack, no Mutagen 16.8 11.2 9.2

The headline is how boring this table is. Five of the six Mutagen-enabled macOS providers land within 1.4 seconds of each other on the flagship metric, and their drush_install_s numbers are within 0.6 seconds. On macOS with Mutagen, your choice of Docker provider is mostly not a performance decision anymore. Pick based on licensing, maintenance, and how the tool fits your workflow.

That is a significant change from 2023, when OrbStack was clearly ahead and Colima and Rancher Desktop looked sluggish. Those gaps have largely closed (all are now using VZ/VirtioFS).

Compared with the 2023 numbers

The 2023 test did a Drupal 10 web install with Mutagen and got OrbStack 20s, Docker Desktop 22s, Rancher Desktop 22s, Colima QEMU 33s, and Colima VZ 35s. The fastest then (OrbStack, 20s) compares with 12.0s for the fastest now (Rancher Desktop), and with 13.4s for OrbStack. The slowest providers gained the most: Rancher Desktop went from 22s to 12.0s and Colima VZ from 35s to 12.6s. The spread between providers went from 15 seconds to about 1.4 (excluding Docker Desktop).

Treat these as a rough comparison, not a like-for-like benchmark. The 2023 numbers came from one MacBook Air M1 (2020) on a single afternoon, with DDEV v1.22.5, Drupal 10.1.6, and PHP 8.1. The nightly runs use CI runner machines, and newer DDEV, Drupal, and PHP versions. Both tests drive the demo_umami install through Puppeteer. Each Docker provider has also shipped many releases since 2023, and the Colima leg now uses VZ where one of the 2023 legs used QEMU with sshfs. Some of the improvement comes from the hardware, and some from the software.

When DDEV was young, a web install with Docker Desktop took SEVEN MINUTES. You'd just watch it poke along at each section. Now you don't even see those as they flash by. Now it takes 12-17 seconds. That's progress!

Mutagen is still doing the work

The most interesting row is the last one. OrbStack with Mutagen finishes the browser install in 13.4s; the same provider without Mutagen takes 16.8s — about 25% slower. Note that the no-Mutagen leg is faster on ddev_start_cold_s (9.2s vs. 12.2s), because there's no sync session to establish, and closer on drush_install_s (11.2s vs. 10.4s), because Drush never goes through the web server. The penalty concentrates in exactly the browser-driven path, which is what you use all day.

Mutagen is on by default on macOS for this reason, and these numbers say to leave it on.

However, plenty of people are perfectly happy with turning off Mutagen. Some folks don't like the additional complexity and don't want the speed trade-off. ddev config global --performance-mode=none turns it off. (Mutagen has more benefits than just performance though; with Mutagen, the web server in the container is dealing with a Linux filesystem, more like the real deployment environment, instead of a Docker bind-mount, which is more like a network filesystem.)

:::warning[Read the hardware caveat before comparing rows] The Docker Desktop leg runs on older M1 test runner machines that have dedicated hardware. OrbStack, Rancher Desktop, Colima, Lima, and Podman share a pool of newer machines. Some of the Docker Desktop gap in the table above is that hardware difference, not the provider. We didn't normalize it — the dashboard deliberately doesn't either — so treat Docker Desktop's row as "somewhat pessimistic" rather than as a clean like-for-like comparison. :::

The other platforms, and why you shouldn't rank them against macOS

The dashboard also carries Linux, WSL2, and traditional Windows legs. They're useful for spotting regressions within a leg over time, but the cross-platform bar chart is misleading if you read it as a platform ranking:

  • The Linux leg runs on ephemeral GitHub-hosted runner VMs. It provisions the Drupal codebase from scratch every night and starts with cold image, Composer, and OS page caches. Every macOS and Windows leg reuses a persistent codebase and warm caches.
  • The Windows and WSL2 legs run on entirely different physical hardware from the macOS test runners.

Trends within a leg: meaningful. Bar-chart comparisons across legs: only meaningful when the machines are comparable, which across platforms they aren't.

Getting the raw data

Every chart on the dashboard has a Download CSV button that exports exactly the rows behind whatever is currently displayed — after your leg and metric selections, not the whole dataset. That's the quickest path to your own analysis.

If you want everything, the underlying dataset is one JSON object per line at history.ndjson, with one line per (commit, leg) benchmark run:

curl -sL https://ddev.github.io/ddev/perf/history.ndjson | jq -r 'select(.os=="darwin") | [.timestamp, .docker_provider, .metrics.drupal_install_s] | @tsv' Running it on your own machine

The harness that replaced the old ddev-puppeteer script lives in the DDEV repository and runs locally against a standard DDEV Drupal project:

./perf/run-benchmark.sh \ --project-dir ~/workspace/d11 \ --site-url https://d11.ddev.site/ \ > result.json

It needs jq and Node.js on your PATH in addition to the usual DDEV prerequisites. If your numbers look very different from the nightly legs, we'd like to hear about it.

Summary

Three years ago the answer to "which Docker provider is fastest on macOS?" was worth a blog post with charts. Today the simple answer is that, with Mutagen on, they're close enough that the question is mostly settled, and any lingering differences are small next to the hardware you're running on.

What's better than a fresh answer is a standing one. The nightly harness means the next time performance shifts — a provider regression, a Mutagen improvement, a DDEV build-layer mistake — it shows up on the dashboard within a day, instead of waiting for somebody to run the numbers by hand and write another post.

Have questions, or numbers that look different from the dashboard? Join the conversation in our Discord, open an issue, or reach out via email.

Follow our blog, Bluesky, LinkedIn, Mastodon, and join us on Discord. Sign up for the monthly newsletter.

This article was edited and refined with assistance from Claude Code.

Très Bien Blog: WordPal: Theme Drupal with WordPress block themes

Drupal Planet -

WordPal: Theme Drupal with WordPress block themes

One of the difficulty with starting a Drupal website is the lack of diversity in available themes. There has always been more choice in the WordPress world for themes. Maybe, just maybe, Drupal could use WordPress themes and get the best of both worlds? 

theodore October 5, 2026

The Drop Times: The Demo Is Over. Now Drupal AI Has to Become a Product.

Drupal Planet -

After Rotterdam, one part of Drupal's AI story is no longer theoretical. The Northmoor University demo brought AI search, content review, translation, editing and externally connected assistants together on the same Drupal site. That made a collection of modules feel closer to a product experience, but it also exposed the next question: whether organisations can depend on the path between those pieces in production.

The stack does not yet sit at one level of maturity. Drupal AI 1.5 and Canvas are stable and covered by Drupal's security advisory policy. Context Control Center is a release candidate, while Tool API and MCP Server remain in beta. Rotterdam showed that these parts can work together. Production teams now have to decide which combinations are mature enough to trust, govern and support.

Permissions, human review and traceability are central to that decision. The demo drafts changes rather than publishing them, leaving a person to review what the AI proposes. Tool API brings access checking into executable capabilities, while MCP can expose Drupal tools to assistants outside the site. Context Control Center moves instructions and organisational knowledge toward managed, reviewed material. Taken together, those pieces point toward a production requirement that goes beyond capability: teams need to know what an agent may read, what it may change, which tools it may invoke, what context it received and who remains accountable for the result.

Provider choice and the connection between Tool API, MCP and Canvas make the remaining maturity gap visible. Drupal's provider abstraction supports different commercial and locally operated models, but workflows still need to remain testable as model behaviour, tool calling and context limits change. The Drupal AI Initiative's follow-up also draws a clear line between what Rotterdam demonstrated and what is available today: the simplified MCP approach shown on stage remains a prototype. Canvas Tools, which lets agents manipulate Canvas through Tool API, is likewise still beta and is not covered by the security advisory policy.

That does not make Drupal AI simply ready or not ready for production. Different parts of the stack already support different kinds of real use, with different levels of risk. Rotterdam instead changes what Drupal AI now has to prove: that permissions remain enforceable, context can be governed, costs and activity can be traced, providers can change without losing control, and interfaces can survive upgrades. Productisation does not mean closing the ecosystem or putting everything inside one package. It means reaching the point where an organisation can understand what an AI system will be allowed to do before deployment, and explain what it actually did afterwards.

Follow The DropTimes on LinkedIn, X, Bluesky, and Facebook, or join #thedroptimes on Drupal Slack.

Allen Jason wrote and curated this issue of Editor’s Pick.

Salsa Digital: Drupal AI Context — first release candidate available

Drupal Planet -

Drupal AI Context first release candidate The first release candidate (RC 1) of Drupal AI Context , also known as Context Control Center (CCC), is now available. This is a major milestone for the project. After five beta releases and months of community testing, refinement and expansion, RC 1 marks the final stage before the first stable 1.0 release. We’re currently planning to release CCC 1.0 in about a month, subject to what we learn from testing the release candidate. There may also be an RC 2 release prior to 1.0. CCC helps Drupal sites provide governed, reusable context to AI-powered features, from brand voice and editorial standards to organisational knowledge, governance rules and other information that AI systems need to work effectively.

DrupalEasy: Don’t be afrAId –  trAIn!

Drupal Planet -

Prevent the AI skills gap from becoming an expanse The rapid pace of updates, new versions and new Drupal core and contrib module functionality of the past 5 years almost feels like a crawl compared to the “high-velocity production model” guiding The Drupal AI initiative . It has screamed past beta versions and into an enterprise ecosystem boasting more than 15,000 installs, funding totaling in the $millions (USD,) as well as dedicated product streams like Inside AI and Outside AI; all in just over a year of its official launch. In addition, the community has about made it beyond the debate of if , and are now comfortably addressing the reality of how to best, (and importantly,) responsibly employ Drupal AI so that it contributes to not just efficiencies, but to improved workflows, outcomes and ultimately the bottom line; both Inside and Out . That, after all, is the measurement used in the viability of any new product or process. Astutely, the effort is grounded in the mission: “ …to

Webpro Company blog: AI translation in Drupal: keeping three languages current

Drupal Planet -

An Estonian service page changes its delivery time from five days to ten. The English and Finnish pages still promise five. AI can translate the new sentence quickly, but someone must notice the change and decide when the other languages should go live. Start with service pages WebPro recommends testing AI translation on one content type first: perhaps ten service pages in Estonian, English and Finnish. Use them to check the complete journey from a source edit to a published translation. Translating a thousand pages at once says little about whether next week's changes will reach the right places. Drupal's AI capabilities received renewed attention in Rotterdam in late September. The Drupal AI initiative's updates discuss translation alongside other editorial tools. For a business, the…

Drupal AI Initiative: Drupal AI after the DriesNote Rotterdam: what you can use today and what comes next

Drupal Planet -

Image: DriesNote, DrupalCon Rotterdam 2026 by Paul Johnson

Author: Jeremy Chinquist

At DrupalCon Rotterdam on September 29, 2026, Dries Buytaert used his keynote to show how far Drupal has come and who it can reach next. Dries framed the keynote around three pillars that bring Drupal's strengths to more people: multilingual (reach people in more languages), JavaScript and headless (bring more developers and applications to Drupal), and AI (give people new ways to work with Drupal).

This post zooms in on the AI pillar. For the full keynote, including digital sovereignty, multilingual, headless and the new Drupal Advocacy Program, read the official recap: DriesNote Rotterdam: Drupal is Light-Years Ahead of Its Reputation. To watch the six demos from the keynote, see Proof, not promises. Watch the six demos from the DriesNote Rotterdam.

Watch the full keynote on YouTube

Exclusive interview: James Hall sat down with Dries Buytaert for the Drupal AI Initiative. Watch it on LinkedIn

Image: James Hall, Everyone TV interviews Dries Buytaert following the DriesNote

A strong start for the Drupal AI Initiative

Dominique De Cooman, Head of Partnerships for the Drupal AI Initiative, opened the conference with a short welcome and a clear message: the Drupal AI Initiative is strong and active. Dries later mentioned that over 100 people have contributed to the Drupal AI Initiative so far.

Try it now: "Drupal AI Demo: Northmoor University"

On stage, Dries showed off the demo that the Inside AI team, led by Christoph Breidert, had been developing over the past few months. "Drupal AI Demo: Northmoor University" is a complete university website that shows Drupal AI at work on realistic content. Anyone can try it today at drupal.org/ai/demo. To learn how the demo was built and what it can do, read Christoph's announcement: Introducing the Drupal AI Demo.

Five parts of the demo were highlighted during the talk:

  • Find weak content and fix it. Drupal AI scans the site's programs, courses, people, news, events and policies, checks them for accuracy, tone and inclusive language, and flags weak items.
  • Fix it without the expert. Editors fix the flagged content themselves instead of waiting for a specialist.
  • Grounded answers, every source cited. Visitors can ask the site questions. Drupal AI answers from the site's own content and cites its sources. If the answer isn't there, it marks the question as outside the site's scope and uses the content to point to the right person to contact. It is not allowed to invent an answer.
  • Drafts, not surprises. Editors can connect their own AI assistant. Asked to update every page that mentions a newly promoted professor, the assistant finds 10 pages and drafts the changes, but publishes nothing. Every draft waits for a human to review and publish.
  • Stay accountable. AI guardrails, one source of truth and every interaction logged.

Did you know?

Aidan Foster also used the demo site in the presentation "Encoding Expertise: How UX Research Powers Human-First AI" to show how AI guidelines can help review a site's content.

Image: Drupal Association (DriesNote, DrupalCon Rotterdam 2026)

What this means for you: for agencies and site owners, this is the quickest way to see Drupal AI on a real site before planning a project. The guardrails matter as much as the features: the AI flags, drafts and cites, and people decide what gets published.

Building Drupal Canvas components with AI

Dries showed AI-assisted development for Drupal Canvas. Given a prompt such as "Build a content template for my articles," the AI assistant checks its work against Canvas Workbench, ESLint and the Canvas CLI. The result is a set of simple template files, pushed to the site with the Canvas CLI.

What this means for you: front-end developers can let an AI assistant write the first draft while Canvas' own tooling validates the result.

Image: Drupal Association (DriesNote, DrupalCon Rotterdam 2026)

Connecting Drupal to AI assistants

Today, exposing a Drupal module's features to AI assistants via MCP takes around 1,000 lines of code. Dries showed a prototype that brings this down to around 20 PHP attributes, using a recipe that combines the Simple OAuth, MCP Server and Tool API modules. The principle is "describe once, use in multiple places": one description of a capability serves AI assistants, workflow tools and JavaScript components alike.

In the demo, a FindImages tool lets an AI assistant look up images on the site, with FlowDrop connecting the pieces.

What this means for you: this is a prototype, not a release. For module maintainers, it points to a future where one description makes a module usable by AI assistants.

Image: Drupal Association (DriesNote, DrupalCon Rotterdam 2026)

On the roadmap: the Rosetta Sprint

The next step is the Rosetta Sprint: a four-day sprint with key maintainers to describe Drupal's capabilities once, in a form that AI agents, other systems and humans can all read. The goal is to make Drupal's data and capabilities easier to expose to AI agents, orchestration tools, frontends and more. The date and location are still to be announced.

Did you know?

Kristen Pol used the Drupal AI Demo to record the demo clips for her session "Context Control Center: Bringing AI Context to Drupal CMS." Curious how Drupal gives AI the right context? Take a look.

Talk louder about Drupal

Dries closed with a clear request: "Here is my ask: Talk louder about Drupal." Try the demo, share what you build with Drupal AI and join the Drupal Advocacy Program.

Image: Karl Hepworth (DriesNote, DrupalCon Rotterdam 2026)

Thank you, Drupal AI Partners

During the keynote, Dries thanked the Drupal AI Partners, the organizations that back the Drupal AI Initiative. Want your organization to join them? Become a partner.

Image: Drupal Association (DriesNote, DrupalCon Rotterdam 2026)

File attachments:  02b-university-demo-stay-accountable.png

Talking Drupal: Talking Drupal #572 - The PHP Foundation

Drupal Planet -

Today we are talking about PHP, Open Source, and Sustainability with guest Elizabeth Barron. We'll also cover AI Image Classification as our module of the week.

For show notes visit: https://www.talkingDrupal.com/572

Topics
  • What is the PHP Foundation
  • Language Health Challenges
  • Paid Core Developers
  • Release Infrastructure
  • Foundation Role and Perception
  • Docs and Onboarding
  • Elizabeth Open Source Journey
  • Future of PHP Ecosystem
  • Listener Elephant Question
  • Ecosystem Security Hub
  • Advisory Board Limits
  • Modernizing Mailing Lists
  • Foundation Awareness Push
  • PHP Ambassadors Strategy
  • State of PHP Survey
  • Five Year Vision
  • Community Hour Podcast
  • php.net Design Refresh
Resources Guests

Elizabeth Barron - thephp.foundation elizabethbarron

Hosts

Nic Laflin - nLighteneddevelopment.com nicxvan John Picozzi - epam.com johnpicozzi Tim Sharp - tea-sharp

MOTW Correspondent

Martin Anderson-Clutz - mandclu.com mandclu

  • Brief description:
    • Have you ever wanted the images in your Drupal media library to be automatically given alt text, a rich description, and a set of tags, using AI? There's a recipe for that.
  • Module name/project name:
  • Brief history
    • How old: created in Sep 2025 by Artem Dmitriiev (a.dmitriiev) of 1xINTERNET
    • Versions available: 1.1.1, which requires Drupal 11.2 or newer
  • Maintainership
    • Actively maintained, latest release and commit just two weeks ago
    • Security coverage
    • Number of open issues: 9 open issues, 4 of which are bugs
  • Usage stats:
    • No usage data reported
  • Module features and usage
    • This recipe applies core's image media type recipe, then adds a description field and a tags field to image media, with tags in a new "Image Classification" vocabulary
    • Editors get a "Generate Alt Text" button right on the image field, using the Field Widget Actions module, with a prompt written like an accessibility expert: under 100 characters, no "image of", flag logos and graphics
    • On save, a vision model writes a description of up to eight sentences: colours, photo versus illustration, people, mood, and key objects, using the media name for context
    • Tagging is chained off that description rather than the image itself, picking or creating up to five short, general terms, and reusing similar existing tags where it can
    • It also adds bulk actions to the media admin view, so you can run description and tagging across an existing library, not just new uploads
    • Description and tag filters are added to the media library, including the widget, so editors can search for "sunny summer day" right in the image picker
    • The stated bigger goal is making images discoverable by RAG and other AI search, so good descriptions become a foundation for future AI features. In fact, this recipe is a dependency for the Canvas AI Image Search recipe, which is still a work in progress
    • Under the hood, images get scaled to 400px wide and converted to PNG before they're sent to the model, which keeps things faster and cheaper
    • One caveat: your site needs an AI provider with a default "chat with image vision" model, and the recipe checks for that when it's applied
    • Also worth a look: the description prompt asks the model to describe people's age, gender, and ethnicity, and even name them if it can, so you may want to review that prompt for your privacy policies, and adjust accordingly
    • Like any recipe, it provides a robust starting point for some compelling features, and every prompt and setting can be tweaked after you apply it
    • Lastly, I wanted to mention that in today's Driesnote in here in Rotterdam, Dries demoed being able to use MCP to search images on his own site. A recipe like this could help you make sure the images in your media library have sufficient metadata to make that work reliably

Nuvole: Cutting Drupal's site:install time from 20 minutes to 90 seconds with an AI coding agent

Drupal Planet -

A large multilingual Drupal site took almost 20 minutes to self-install, which made every CI run painfully slow. Here's how a PHP profiler and an AI coding agent got it down to 90 seconds.

“We’ll add the tests later” only works if the tests are fast enough that nobody is tempted to skip them. On one of our large multilingual Drupal projects, they weren’t.

The site has content in 100 languages, around 200 modules, 400+ configured fields, and up to 5,000 config files once translations are counted in. Running drush site:install against that configuration took close to 20 minutes. Add Docker startup and the actual end-to-end test run on top, and a single CI pipeline run could easily take an hour. Copying the production database into CI wasn’t an option, so a full config-driven install was the only realistic way to get a clean site to test against for every change.

An install that slow doesn’t just cost CI minutes, it costs feedback loops. So we set out to find out exactly where the 20 minutes were going, fix what we could, and see how AI could shorten the loop of measuring, fixing and re-measuring.

Setting up a profiler

The first step was getting visibility into what Drupal was actually doing during install. We used SPX, a lightweight PHP profiler that’s easy to drop into a Docker-based PHP image alongside xdebug or blackfire alternatives, without much of the performance overhead those carry.

Once enabled, SPX gives you a web UI to browse individual profiles and see wall time, memory and call counts per function:

And for any profiled request, a flame-graph-style view of the whole call stack, with a sortable table of the most expensive functions underneath:

That’s already useful for a single page load. The interesting part is what happens when you point the same tooling at an AI coding agent.

Giving the coding agent access to the profiler

SPX ships an MCP server extension, SPX-MCP, which exposes recorded profiles through a query-like interface instead of a browser UI. Wiring it into an agent’s MCP configuration means the agent can list profiles, drill into a specific request, and pull out the functions responsible for the most time, without a human first opening a flame graph and squinting at it.

In practice, that turns “let me go look at a profile and tell you what’s slow” into a two-line prompt:

The agent found the three most recent profiles, correctly noticed they were regular page requests rather than the site:install run we actually cared about, and then, once pointed at the right report, broke a 1.44s homepage request down into HTML rendering, Twig compilation, class loading, cache reads and database time, each with concrete function names attached. That’s the same triage a developer would do manually, just a lot faster to get to.

The problem with profiling a 20-minute install

Profiling a single page request is straightforward. Profiling a 20-minute drush site:install is a different story: turning SPX on for the whole run produced one profile with almost 590 million calls, weighing about 8GB on disk. That’s too large to open in the web UI, and too large for an agent to reason about as a single blob.

The fix was to split it into one profile per install stage instead of one profile for the whole run. Drupal’s installer runs through a fixed sequence of tasks (install_select_language, install_config_import_batch, install_import_translations, and so on), and there’s a single place in core, install_run_tasks(), where each task starts and finishes. A small patch there starts and stops an SPX profile around each task and tags it with the task name as metadata:

--- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ function install_run_tasks(&$install_state, ?callable $callback = NULL) { $task = array_shift($tasks_to_perform); $install_state['active_task'] = $task_name; $original_parameters = $install_state['parameters']; + if (function_exists('spx_profiler_start')) { + spx_profiler_start(); + spx_profiler_full_report_set_custom_metadata_str(json_encode(['task' => $task_name])); + } $output = install_run_task($task, $install_state); ... + if (function_exists('spx_profiler_stop')) { + spx_profiler_stop(); + } } while (!$finished);

That turned one unmanageable profile into a dozen small ones, each scoped to a single install task, each cheap enough for the agent (or a human) to load and query directly. For the rare case of a profile that’s still too big, there’s also SPXQ, a small command-line viewer for browsing multi-gigabyte SPX reports without loading the whole thing into memory or a browser tab.

Finding the bottlenecks

With per-task profiles available, the workflow became a loop: profile a task, find the most expensive function, patch it, install again, and check the diff in timing. Doing that by hand, task by task, function by function, is tedious, exactly the kind of repetitive, well-defined work an AI coding agent is good at once it has direct access to the profiling data instead of having to be told what’s in it.

One of the clearest examples was the install_config_import_batch task, which turned out to spend the majority of its time in EntityStorageBase::doPostSave():

Digging into that call chain showed that saving a single field config was re-triggering hooks and cache invalidation for every entity type’s base field definitions, even when only one bundle had actually changed, and it was doing that for every field, of which there were hundreds. After each fix, the agent could re-run the install, pull the new profile, and confirm the improvement against the previous run.

What actually moved the needle

After several rounds of this profile-fix-reprofile loop, here’s what made the biggest difference:

  1. Cache collection names. StorageComparer::getAllCollectionNames() was rescanning the sync directory to find language collections on every one of ~2,800 config items during import, even though the answer never changes. Computing it once per import and reusing it cut that step by 27.6%.

  2. Cache translatable default config. LocaleConfigManager::getTranslatableDefaultConfig() rebuilt a typed-config wrapper once per language, even though the shipped default config is identical across languages. Caching it by config name cut this by 53.5%.

  3. Cache isSupported(). The sibling of the fix above, doing two redundant config reads per language for an answer that doesn’t depend on the language. Caching it removed another 5.4%.

  4. Scan the translation directory once. The same, usually-empty translation folder was being scanned for every project/language pair, up to 1,580 times. Listing it once and matching filenames against that list brought the whole step down to about 6ms.

  5. Skip no-op config saves. LocaleConfigManager::updateConfigTranslations() was saving configuration even when nothing had actually been translated, reloading language override objects for all languages on every save. A simple !empty($processed) guard removed 237 unnecessary saves.

  6. Stop force-rebuilding a cold field map. After every container rebuild, FieldDefinitionListener::onFieldDefinitionCreate() was forcing a full field map rebuild for every single field created during install. Skipping that while the map is still cold cut getBaseFieldDefinitions() calls by 76%, with no change to the resulting field map.

  7. Narrow the cache clear on field save. This was the single biggest win. Saving one field config was wiping every entity type’s base field definitions and triggering a full plugin rediscovery. Clearing only the affected bundle’s field definitions during install cut this step by 18%, verified as producing byte-identical definitions across 37 entity/bundle combinations.

  8. No-op the translation status key/value store during install. A small wrapper turns locale.translation_status lookups into an in-memory no-op during install (and passes through normally afterwards), avoiding repeated database hits for a value that’s meaningless mid-install.

  9. Disable remote translation lookups for CI installs. During an automated test install there’s no reason to reach out to the localization server, so translation.import_enabled and related settings are simply turned off for that environment. This one is a CI-only optimization, not something you’d want in production.

  10. Skip irrelevant entity hooks during install. Some entity_update/entity_insert hooks have no meaning during install or fixture loading. Guarding them behind $entity->isSyncing() avoided pointless work; for example, the Search API module’s _search_api_view_crud_event() handler.

None of these are exotic. Individually, most are the kind of “don’t redo work you already did” fix any Drupal developer would recognize once pointed at it. What changed was how quickly they could be found and verified: instead of manually reading flame graphs and re-running a 20-minute install to check each guess, the agent could query a profile, propose a targeted fix, and confirm the improvement against the previous measurement, over and over.

The result

After all of it: 1 minute 30 seconds, down from roughly 19 minutes 30 seconds. A 13x improvement on the number that mattered most for us, the total install time inside the CI pipeline.

Not every fix here is something we’d apply blindly to every project. Some, like skipping remote translation downloads, only make sense for a throwaway test install. Others touch Drupal core behaviour around cache invalidation and are being submitted as proper core patches with issues on drupal.org, since they need review and testing well beyond “it worked for us”.

Bonus

Both the SPXQ profile viewer and a reusable “profile, analyze, fix, validate” skill for coding agents are public:

  • SPXQ, a CLI profile viewer for large SPX reports.
  • A Claude/Codex skill that walks an agent through profiling, analyzing, fixing and validating performance issues on its own.
  • The core patches from this round of optimization are collected in this gist.

Tags: Drupal Planet, Drush, Performance, AI, Drupal, DrupalCon

Pages

Subscribe to www.hazelbecker.com aggregator - Drupal feeds