Writing about Drupal internals, PHP, and making things observable.

Long-form notes on the parts of Drupal you only meet when something is slow, broken, or newly possible, in chronological order.

Domain logic on entities, without touching the entity

Entity Adapter attaches domain-specific behaviour to entities, and to any other object, with a PHP attribute and an interface of your own. No bundle class, no entity class override, no helper functions in a .module file.

Drupal in a long-running process

Drupal spends a request filling static caches and then throws the whole process away. Keep the process alive, in a Symfony Messenger worker or a FrankenPHP worker, and every one of those caches becomes a lie that outlives the work it was computed for.

Profiling AI provider calls in Drupal

WebProfiler now collects every call the AI module makes to a provider, with timings, tokens, guardrail verdicts and tool exchanges. Here is what it records and how it stays out of the AI module's way.