DDEV Blog: Mutagen in DDEV: Functionality, Issues, and Debugging

Force an explicit sync:

When Mutagen is enabled, DDEV:
Copilot was used to create an initial draft for this blog, and for subsequent reviews.

The benefits far outweigh the caveats for most projects, especially with the new diagnostic tools that identify and help resolve common issues automatically.
ddev config --performance-mode=none && ddev restart

  • Watch real-time sync activity:

    Current file: vendor/bin/large-binary (306 MB/5.2 GB)
    Current file: vendor/bin/large-binary (687 MB/5.2 GB)
    Current file: vendor/bin/large-binary (1.1 GB/5.2 GB)

    Frontend build tools create massive node_modules directories that slow Mutagen sync significantly. Solution: Add node_modules to upload_dirs:

    Mostly for PHP

    If you’re here because you just need to debug a Mutagen problem, this will probably help:

    Webserving Performance Improvement

    ddev mutagen reset # Start from scratch
    ddev start

    If your project has non-standard locations, override defaults by setting upload_dirs in .ddev/config.yaml.

    Mutagen is an asynchronous file synchronization tool that decouples in-container reads and writes from reads and writes on the host machine. Each filesystem enjoys near-native speed because neither is stuck waiting on the other.

    1. Mounts a Docker volume onto /var/www inside the web container
    2. A Linux Mutagen daemon is installed inside the web container
    3. A host-side Mutagen daemon is started by DDEV
    4. The two daemons keep each other up-to-date with changes on either side

    Lifecycle

    • ddev start: Starts the Mutagen daemon on the host if not running, creates or resumes sync session
    • ddev stop: Flushes sync session to ensure consistency, then pauses it
    • ddev composer: Triggers synchronous flush after completion to sync massive filesystem changes
    • ddev mutagen reset: Removes the Docker volume and the sync session will then be recreated from scratch (from the host-side contents) on ddev start.

    Upload Directories

    The first-time Mutagen sync takes 5-60 seconds depending on project size. A Magento 2 site with sample data might take 48 seconds initially, 12 seconds on subsequent starts. If sync takes longer than a minute, you’re likely syncing large files or directories unnecessarily.

    • Drupal: sites/default/files
    • WordPress: wp-content/uploads
    • TYPO3: fileadmin, uploads

    Use --all flag to analyze all Mutagen volumes system-wide:
    Mutagen increases disk usage because project code exists both on your computer and inside a Docker volume. The upload_dirs directories are excluded to mitigate this.

    Initial Sync Time

    ddev mutagen reset
    ddev restart

  • ddev mutagen sync

    ddev mutagen logs

  • # Backup customizations first
    mv .ddev/mutagen/mutagen.yml .ddev/mutagen/mutagen.yml.bak
    ddev restart
  • ddev mutagen monitor

    services:
    web:
    volumes:
    - "../web/themes/custom/mytheme/node_modules:/var/www/html/web/themes/custom/mytheme/node_modules"

    Watch for volumes larger than 5GB (warning) or 10GB (critical). Use ddev utility mutagen-diagnose --all to check all projects.

    • Do Git operations on the host, not in the container
    • Use ddev composer for most composer operations
    • Run ddev mutagen sync after major Git branch changes
    • Run ddev mutagen sync after manual Composer operations done inside the container

    Disk Space Considerations

    DDEV now includes a diagnostic tool that automatically checks for common issues:
    Mutagen has been a part of DDEV for years, providing dramatic performance improvements for macOS and traditional Windows users. It’s enabled by default on these platforms, but understanding how it works, what can go wrong, and how to debug issues is key to getting the most out of DDEV.

    The New ddev utility mutagen-diagnose Command

    ddev mutagen status

    For more information, see the DDEV Performance Documentation and the Mutagen documentation.

    • Volume sizes: Warns if >5GB, critical if >10GB
    • Upload directories configuration: Checks if properly configured for your CMS
    • Sync session status: Reports problems with the sync session
    • Large directories: Identifies node_modules and other large directories being synced
    • Ignore patterns: Validates Mutagen exclusion configuration

    Best practices:
    Disable per-project:
    while true; do ddev mutagen st -l | grep "^Current"; sleep 1; done

    #!/usr/bin/env bash
    ddev mutagen sync || true

    ddev utility mutagen-diagnose

    This blog is based on the Mutagen Fundamentals and Troubleshooting Contributor Training held on January 22, 2026.

    Monitoring Sync Activity

    ddev utility mutagen-diagnose

  • If you change files (checking out branches, running git pull, deleting files) while DDEV is stopped, Mutagen has no awareness of these changes. When you start again, it may restore old files from the volume.

    Manual Sync Control

    Disable Mutagen if:
    The primary target of Mutagen syncing is PHP files. These were the fundamental problem with Docker as the number of files in a Docker-hosted PHP website grew into the Composer generation with tens of thousands of files, so php-fpm had to open so very many of them all at once. Now with DDEV on macOS using Mutagen, php-fpm is opening files that are just on its local Linux filesystem, not opening ten thousand files that all have to be verified on the host.
    ddev utility mutagen-diagnose

    ddev utility mutagen-diagnose --all

    DDEV_DEBUG=true ddev start

  • ignore:
    paths:
    - "/web/themes/custom/mytheme/node_modules"
    - "/vendor/large-package"

    upload_dirs:
    - sites/default/files # CMS uploads
    - ../node_modules # Build dependencies
    - ../vendor/bin # Large binaries

    ddev config global --performance-mode=none

    Traditional Docker bind-mounts check every file access against the file on the host. On macOS and Windows, Docker’s implementation of these checks is not performant. Mutagen solves this by maintaining a cached copy of your project files in a Docker volume, syncing changes between host and container asynchronously.
    Mutagen supports filesystem notifications (inotify/fsnotify), so file-watchers on both the host and inside the container are notified when changes occur. This is a significant advantage for development tools that would otherwise need to poll for changes.
    Solution: Run ddev mutagen reset before restarting if you’ve made significant changes while stopped. That removes the volume so everything comes first from the host side in a fresh sync.
    Most people don’t have to change this anyway; macOS and traditional Windows default to performance_mode: mutagen and Linux/WSL default to performance_mode: none.
    Add .git/hooks/post-checkout and make it executable:
    Access Mutagen directly:

    Git Hooks for Automatic Sync

    See the slides for the training video.
    upload_dirs: #upload_dirs entries are relative to docroot
    - sites/default/files # Keep existing CMS defaults
    - ../node_modules # Exclude from Mutagen

    ddev mutagen status -l

    Troubleshooting Steps

    1. DDEV automatically excludes user-generated files in upload_dirs from Mutagen syncing, using bind-mounts instead. For most CMS types, this is configured automatically, for example:

      • You’re on Linux or WSL2 (already has native performance)
      • Filesystem consistency is more critical than webserving performance
      • You’re troubleshooting other DDEV issues

      Mutagen has delighted many developers with its web-serving performance. One dev said “the first time I tried it I cried.”
      ⚠ 3 node_modules directories exist but are not excluded from sync (can cause slow sync)
      → Add to .ddev/config.yaml:
      upload_dirs:
      - sites/default/files
      - web/themes/custom/mytheme/node_modules
      - web/themes/contrib/bootstrap/node_modules
      - app/node_modules
      → Then run: ddev restart

      Debugging Long Startup Times

      ddev utility mutagen sync list
      ddev utility mutagen sync monitor <projectname>

      We do note that upload_dirs is not an adequate description for this behavior. It was originally intended for user-generated files, but now is used for heavy directories like node_modules, etc.
      ddev utility mutagen daemon stop
      ddev utility mutagen daemon start

    Excluding Directories from Sync

    Recommended approach: Use upload_dirs in .ddev/config.yaml:

  • Similar Posts