Write A Drush Command To Clear Specific Cache Bins
Drupal’s cache system divides stored data into separate bins, allowing render output, discovery data, configuration, and page responses to be managed independently. A full drush cr is useful when a module is installed or services change, but it can be excessive for a small operational task such as refreshing one application cache.
Writing a Drush command to clear specific cache bins gives developers and site administrators a controlled alternative. It is particularly useful on production websites where clearing every cache bin can create a burst of database queries and uncached page requests. This approach suits Drupal projects maintained by teams in Sydney, Melbourne, Brisbane, and other Australian locations where a short, targeted maintenance operation can be preferable during business hours.
Understand Drupal Cache Bins
A cache bin is a logical storage area managed through Drupal’s cache API. Common bins include render, dynamic_page_cache, page, config, discovery, data, default, and entity. Drupal modules can also define custom bins for API responses, calculated values, or integration data.
The bin name does not always describe a physical database table. Depending on the site’s configuration, a bin might be stored in the database, Redis, Memcache, or another backend. Your command should therefore use Drupal’s cache factory rather than accessing a database table directly. The cache backend knows how to remove entries correctly regardless of the storage system.
Clearing a bin also differs from invalidating cache tags. If a product changes, invalidating its tags is usually more precise than deleting an entire bin. A bin-clearing command is best for situations such as stale integration responses, a temporary development problem, or a known batch of cached values that cannot be identified with tags.
A full cache rebuild also performs work that targeted deletion does not. drush cr rebuilds Drupal’s service container, routing information, plugin discovery, configuration-related caches, and other system data. Use the narrower command when only application data is stale, rather than treating it as a replacement for every form of cache rebuild.
Prepare A Small Drupal Module
Create a custom module for operational commands instead of placing the code in a contributed module. For example, a module named ops_tools can contain commands used by developers and authorised site administrators.
The basic file structure is:
ops_tools/
├── ops_tools.info.yml
├── ops_tools.services.yml
└── src/
└── Commands/
└── OpsToolsCommands.php
The module definition can be minimal:
# ops_tools.info.yml
name: Operations Tools
type: module
description: Provides controlled maintenance commands for Drupal.
core_version_requirement: ^10 || ^11
package: Custom
Register the command class as a Drush service:
# ops_tools.services.yml
services:
ops_tools.commands:
class: Drupal\ops_tools\Commands\OpsToolsCommands
arguments:
- '@cache_factory'
tags:
- { name: drush.command }
After enabling the module, rebuild caches so Drush can discover the service:
drush en ops_tools -y
drush cr
On a hosted Australian production platform, the command must be available in the same release and document root as the Drupal site. A common deployment mistake is enabling the module on a local machine but forgetting to include its files in the build artefact used by a Sydney or Melbourne production environment.
Build The Targeted Command
The command below accepts a comma-separated list of cache bins, checks each name against an allow-list, and deletes all entries in the approved bins. The allow-list is important because it prevents a typo from silently becoming an unexpected operation and makes the command easier to audit.
<?php
namespace Drupal\ops_tools\Commands;
use Drupal\Core\Cache\CacheFactoryInterface;
use Drush\Attributes as CLI;
use Drush\Commands\DrushCommands;
final class OpsToolsCommands extends DrushCommands {
/**
* The bins that this command is permitted to clear.
*
* @var string[]
*/
private const ALLOWED_BINS = [
'data',
'default',
'discovery',
'dynamic_page_cache',
'entity',
'page',
'render',
];
public function __construct(
private readonly CacheFactoryInterface $cacheFactory,
) {
parent::__construct();
}
#[CLI\Command(
name: 'site:clear-bins',
aliases: ['scb'],
)]
#[CLI\Argument(
name: 'bins',
description: 'Comma-separated cache bins to clear.',
)]
#[CLI\Usage(
name: 'drush site:clear-bins render,dynamic_page_cache',
description: 'Clears selected page-related cache bins.',
)]
public function clearBins(string $bins = ''): int {
$requested = array_filter(
array_map('trim', explode(',', $bins))
);
if ($requested === []) {
$this->output()->writeln(
'<error>Provide at least one cache bin.</error>'
);
$this->output()->writeln(
'Allowed bins: ' . implode(', ', self::ALLOWED_BINS)
);
return self::EXIT_FAILURE;
}
$unknown = array_diff($requested, self::ALLOWED_BINS);
if ($unknown !== []) {
$this->output()->writeln(
'<error>Unknown bin(s): ' . implode(', ', $unknown) . '</error>'
);
return self::EXIT_FAILURE;
}
foreach ($requested as $bin) {
$this->cacheFactory->get($bin)->deleteAll();
$this->io()->success("Cleared cache bin: {$bin}");
}
return self::EXIT_SUCCESS;
}
}
The important operation is $this->cacheFactory->get($bin)->deleteAll(). cache_factory returns the configured backend for the requested bin, while deleteAll() removes every item from that bin. The command does not assume that the site uses the database backend, so it continues to work when a project moves to Redis or another cache service.
The command uses PHP attributes supported by current Drush releases. Drupal 10 and Drupal 11 projects should use a maintained Drush version that supports attribute-based command definitions. If an older project still uses annotations, the same class can be converted to Drush annotations, but the dependency injection and cache operation remain the same.
Run And Verify The Operation
Once the module is enabled and the container has been rebuilt, run the command with one or more comma-separated bins:
drush site:clear-bins render
drush site:clear-bins render,dynamic_page_cache
drush scb data
The command should report each cleared bin. Start with the narrowest useful target. For a stale rendered block, render may be sufficient. For a cached full-page response, page or dynamic_page_cache may be relevant. Clearing render will not necessarily remove a response already stored in the Dynamic Page Cache.
Test the behaviour on a non-production copy first. Enable verbose output when diagnosing the environment:
drush -vvv site:clear-bins render
Then load a page that uses the affected data and check Drupal’s logs, response headers, and application behaviour. A cache clear can make the first request slower because Drupal must rebuild the deleted entries. On a busy Brisbane ecommerce site, run the command during a low-traffic period if a large render or page bin is involved.
Remember that external caching sits outside Drupal’s cache bins. A reverse proxy, CDN, or hosting platform may continue serving an old response after the Drupal bin has been emptied. Australian retailers preparing for Boxing Day traffic, for example, may use Cloudflare or a managed edge cache in addition to Drupal. In that situation, clearing the Drupal bin does not automatically purge the external cache.
Add Safety Controls For Production
A useful operational command should fail safely. The allow-list in the example prevents arbitrary input, while the empty-argument check avoids accidentally clearing a default bin because no value was supplied. You can extend the same pattern with a --yes option, environment checks, or a confirmation prompt for high-impact bins.
Avoid placing secrets, customer data, or full cache contents in command output. Logging the bin names and execution time is generally enough for an audit trail. If the command is available to a deployment user, restrict shell and Drush access through the hosting platform rather than relying solely on the command’s validation.
You may also want to separate low-risk application bins from sensitive system bins. Clearing discovery or config can cause substantial work and may expose a configuration problem that should instead be handled with drush cr. A stricter version can use two allow-lists, or reject config and discovery entirely unless an explicit option is supplied.
Custom cache bins should be named deliberately. If a module stores third-party API responses in a bin such as partner_api, add that name to the allow-list only after confirming that the command’s users understand its scope. If the bin is essential to rate limiting or expensive synchronisation, clearing it could trigger many simultaneous requests to an external service.
Choose The Correct Clearing Method
The right operation depends on what has become stale and how broadly the data is shared. Cache tags are usually the most precise option for content changes, while a bin command is helpful when the application data has no reliable tag relationship.
| Situation | Preferred operation | Scope | Typical example |
|---|---|---|---|
| One node or media item changed | Invalidate cache tags | Very narrow | Refresh one article teaser |
| A custom API response is stale | Clear the custom bin | Module-specific | Remove weather or stock data |
| Rendered output is broadly stale | Clear render |
Medium | Rebuild cached blocks |
| Full-page responses are stale | Clear page or dynamic_page_cache |
Broad | Refresh authenticated or anonymous page output |
| Routes, plugins, or services changed | Run drush cr |
Site-wide | Enable a module or alter routing |
| Configuration was imported | Run the required configuration/cache rebuild | Site-wide | Apply a deployment configuration change |
A command that clears specific cache bins is especially valuable in deployment scripts. For example, a release might import content from an Australian product feed and then clear only data and a custom integration bin. That avoids deleting unrelated render caches and reduces the amount of work required on the first requests after deployment.
Do not use this technique to hide an invalidation design problem. If every product update requires clearing the entire render bin, review cache tags and the render cache metadata attached to the affected output. A targeted Drush command is a practical administration tool, while correct cacheability metadata is the durable Drupal solution.
Maintain The Command As Part Of The Project
Document the supported bin names beside the command and keep the list aligned with the project’s actual services. Drupal core and contributed modules can introduce custom bins, but adding every discovered bin automatically is less safe than reviewing each one. A deliberately maintained list gives a team confidence about what a production command can change.
Add automated tests for invalid input and successful clearing where the project’s testing setup permits it. At minimum, verify that an unknown bin returns a failure status and that a valid bin calls the backend’s deletion method. This protects the command when the module is updated or dependency injection is refactored.
A short runbook should state when to use site:clear-bins, when to use drush cr, and when an external CDN purge is required. Include the deployment timezone used by the team, especially when developers in Perth, Adelaide, and the eastern Australian cities coordinate maintenance across different local times. Clear operational boundaries make the command predictable during releases and incident response.