# Plugin Cleaner

**URL:** https://meta.discourse.org/t/plugin-cleaner/399505
**Category:** Plugin
**Created:** [March 29, 2026, 2:10am UTC](https://meta.discourse.org/t/plugin-cleaner/399505 "2026-03-29T02:10:32Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![canbekcan](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/canbekcan/32/544186_2.png) [@canbekcan](https://meta.discourse.org/u/canbekcan)
#### Post date: [March 29, 2026, 2:10am UTC](https://meta.discourse.org/t/plugin-cleaner/399505/1 "2026-03-29T02:10:32Z")

</div>

| | | |
| --- | --- | --- |
| ℹ | **Summary** | Safely scans, audits, and cleans orphaned database residue left behind by uninstalled plugins. |
| 🛠 | **Repository Link** | [GitHub - canbekcan/discourse-plugin-cleaner · GitHub](https://github.com/canbekcan/discourse-plugin-cleaner) |
| 📖 | **Install Guide** | [How to install plugins in Discourse](https://meta.discourse.org/t/install-plugins-in-discourse/19157) |
| 💻 | **Coding** | Vibe Coding - Gemini |

  

### Features

When you uninstall a Discourse plugin, it often leaves behind hidden data in your database. Over time, this “residue” can clutter your database and complicate site maintenance. **Discourse Plugin Cleaner** is a comprehensive administrative tool designed to safely identify and remove this orphaned data.

**Major Features Include:**

- **Deep Scanning:** Scans multiple database tables including Custom Fields (User, Topic, Post, Category, Group), Plugin Settings, Themes, Badges, API Keys, Webhooks, Tag Groups, and Uploads.
- **Safe Audit Mode (Zero Auto-Delete):** The plugin operates strictly as an auditing tool until you take action. It will never automatically delete data. You must manually select and confirm the items you wish to remove.
- **Risk Assessment:** Automatically assigns a “Risk Level” (Critical, High, Medium, Low, OK) to detected items to help administrators make informed decisions about what is safe to delete.
- **Version History Tracking:** Takes snapshots of your installed plugins on boot. If a plugin is removed, it logs the state change, creating a historical record of what was uninstalled and when.
- **Modern Admin Interface:** Provides a sleek, intuitive dashboard built with Ember strict-mode components for seamless integration into the Discourse Admin interface.

### Configuration

The plugin works out of the box with sensible defaults. To use the plugin:

1. **Access the Dashboard:** Navigate to your Discourse Admin dashboard. In the sidebar, under the **Plugins** section, click on **Plugin Cleaner**.
2. **Run a Scan:** Click the **“Run Deep Scan”** button. The system will query your database and generate a real-time report of all orphaned data it finds.
3. **Review Issues:** Browse through the categorized tabs (Custom Fields, Plugin Settings, etc.). Pay close attention to the `Risk` and `Status` columns.
4. **Select and Clean:** Check the boxes next to the orphaned items you wish to remove.
5. **Confirm Deletion:** Click **“Delete Selected”**. You will be prompted with a final confirmation warning before the data is permanently erased. All deletions are automatically logged in the Discourse Staff Action Logs for security auditing.

_(Note for Uploads: If orphaned uploads are found, the plugin will instruct you to run `rake uploads:clean` from your server console to physically reclaim disk space)._

### Settings

You can customize the strictness of the scanner via your site settings.

| Name | Description |
| --- | --- |
| `plugin_cleaner_orphan_threshold` | The maximum number of records a custom field can have to be considered “orphaned”. If a custom field has fewer records than this threshold, it will be flagged for review. (Default: `5`, Min: `1`, Max: `100`) |
| `plugin_cleaner_stale_api_key_days` | The number of days an API key must go unused before the scanner flags it as stale/orphaned. (Default: `90` days, Min: `7`, Max: `365`) |
| `plugin_cleaner_stale_upload_days` | The number of days an unlinked upload can exist before it is flagged as orphaned. (Default: `30` days, Min: `1`, Max: `365`) |

_(Note: This is the project to understand how Discourse plugins work)_

---

<div class="post-metadata">

### Author: ![merefield](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/merefield/32/176214_2.png) [@merefield](https://meta.discourse.org/u/merefield)
#### Post date: [March 29, 2026, 7:24am UTC](https://meta.discourse.org/t/plugin-cleaner/399505/2 "2026-03-29T07:24:32Z")

</div>

Nice intent.

A few challenges:

- Many good plugins create and manage their own tables. Looking at your code, I’m not sure you’ve taken account of that yet?

- I don’t see a way your plugin protects the user from deleting the custom fields outside of a specific plugin they might want to “cleanse” - you are relying on the user to identify them? Just blocks deleting custom fields that are in core?

And on that note:

> <https://github.com/canbekcan/discourse-plugin-cleaner/blob/65e7f7eb2b11badf0de31046601e729c84c8dc2f/lib/plugin_cleaner/scanner.rb#L6>

That looks a little risky. What if a core upgrade adds new ones that you don’t catalogue - are you going to risk deleting new core fields that you are not explicitly listing?

In any case I wish you luck with development, it’s definitely an interesting addition.

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [March 29, 2026, 6:37pm UTC](https://meta.discourse.org/t/plugin-cleaner/399505/3 "2026-03-29T18:37:50Z")

</div>

The likelihood that such a plugin will delete something needed and leave the database in a broken state is greater than zero. I don’t remember a case where having tables left by an uninstalled plugin caused a problem.

---

<div class="post-metadata">

### Author: ![elmuerte](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/elmuerte/32/456517_2.png) [@elmuerte](https://meta.discourse.org/u/elmuerte)
#### Post date: [March 29, 2026, 7:20pm UTC](https://meta.discourse.org/t/plugin-cleaner/399505/4 "2026-03-29T19:20:26Z")

</div>

Unless those tables have foreign keys to core discourse tables, which can prevent deletion of data in those tables.

But that problem is not something which can be reliably detected by an other tool. The plugin making those relations should either not create foreign keys, or Discourse needs to provide a way for plugins to register a way to “disarm” them when they disappear from the installation.
