Schedule icon
Get icon
Aggregate icon
Script icon
Process icon
Set icon
If icon
Log icon
SlackIncomingWebhook icon
Pause icon
Loop icon
Delete icon
Fail icon

MongoDB GridFS Orphaned Chunk and Dangling File Reclamation Guard

Audit MongoDB GridFS buckets for orphaned binary chunks, pause for operator approval, purge confirmed orphans, and verify zero residual chunks.

Categories
DataInfrastructure

In MongoDB, GridFS partitions large files exceeding the 16 MB BSON document limit into binary chunks stored in fs.chunks, linked back to file metadata records in fs.files via the files_id reference key. During production operations, microservice crashes, network timeouts mid-stream, or naive administrative scripts that delete metadata records directly (db.fs.files.deleteOne()) instead of calling the native GridFS bucket driver API leave binary chunks stranded in fs.chunks. Because standard application queries only traverse fs.files, these unreferenced chunks remain completely invisible, consuming gigabytes or terabytes of WiredTiger storage and filesystem cache without serving live traffic.

This blueprint provides an automated, production-grade Day 2 operations guard for MongoDB GridFS buckets. It executes an index-assisted $lookup aggregation query joining fs.chunks against fs.files to identify unlinked chunk clusters, compares observations against historical execution state in Kestra KV store to protect active in-flight uploads within an upload grace period, pauses for operator verification before executing destructive mutations, purges confirmed orphans in safe sequential batches, and executes a post-remediation verification query to prove that zero residual orphaned chunks remain.

How it works

  1. daily_gridfs_hygiene (io.kestra.plugin.core.trigger.Schedule) triggers the audit on a recurring daily maintenance window, defaulting to dry-run mode for audit-only surveillance.
  2. load_previous_state (io.kestra.plugin.core.kv.Get) retrieves previous observation timestamps from Kestra KV store to enable differential age tracking.
  3. detect_orphaned_chunks (io.kestra.plugin.mongodb.Aggregate) executes an index-assisted server-side aggregation grouping fs.chunks by files_id, performing an anti-join $lookup against fs.files, and isolating chunk clusters with no parent metadata document.
  4. classify_and_diff (io.kestra.plugin.scripts.python.Script) cross-references detected orphaned IDs with KV history, categorizing items into confirmed aged orphans and in-flight uploads spared by the grace period threshold (min_orphan_age_hours), while generating pre-computed BSON Extended JSON batch filters.
  5. persist_state_kv (io.kestra.plugin.core.kv.Set) records the updated observation snapshot into Kestra KV store for sequential tracking.
  6. gate_orphaned_chunks (io.kestra.plugin.core.flow.If) branches based on whether confirmed orphans were detected. If present, alert_slack_orphans posts an incident alert to Slack detailing leaked chunk counts and reclaimable megabytes.
  7. check_remediation_active (io.kestra.plugin.core.flow.If) evaluates if auto_remediate is enabled and dry_run is false. When authorized, pause_for_operator_approval (io.kestra.plugin.core.flow.Pause) halts execution until a database administrator confirms the purge.
  8. purge_orphaned_chunks (io.kestra.plugin.core.flow.Loop) iterates sequentially over batch filters, dispatching delete_chunk_batch (io.kestra.plugin.mongodb.Delete, DELETE_MANY) against fs.chunks.
  9. verify_post_remediation (io.kestra.plugin.mongodb.Aggregate) re-queries fs.chunks across the targeted files_id keys, and fail_verification (io.kestra.plugin.core.execution.Fail) fails the execution if any targeted chunk survived.

What you get

  • Automated Storage Reclamation: Reclaims unreferenced disk space and RAM cache in WiredTiger storage engines caused by interrupted uploads or incomplete deletions.
  • In-Flight Upload Safety: Multi-run KV differential state tracking ensures that large active streaming uploads are spared within the configurable grace period.
  • Two-Phase Human Approval Gate: Requires deliberate operator sign-off via interactive UI pause before modifying live database collections.
  • Post-Remediation Verification: Asserts zero residual orphaned chunks on the exact targeted keys post-deletion, preventing silent partial write failures.
  • Batch-Throttled Mutations: Deletes chunks in controlled sequential batches to avoid replication lag spikes and WiredTiger ticket exhaustion.

Who it's for

  • Database Administrators (DBAs): Managing MongoDB clusters running GridFS document or media management workloads.
  • Platform & SRE Engineers: Enforcing storage capacity hygiene and preventing runaway database disk growth.
  • Data Platform Teams: Operating document ingestion pipelines, ML model artifact stores, or customer asset repositories.

Why orchestrate this with Kestra

Raw cron scripts or manual shell commands to clean GridFS lack cross-run state tracking, risking catastrophic data loss by deleting chunks belonging to active in-flight uploads. Furthermore, ad-hoc scripts provide no audit trail, no human approval gates, and no automated post-remediation verification. Kestra orchestrates this lifecycle declaratively: maintaining persistent KV state across executions, managing interactive pause approval gates, isolating failure alerts in Slack, and providing an immutable audit trail of all purged storage.

Prerequisites

  • A running MongoDB replica set or standalone instance (v4.4+) with network reachability from the Kestra worker.
  • A database user with readWrite privileges on the target database (to execute $lookup and DELETE_MANY on GridFS collections).
  • A Slack incoming webhook URL for operational notifications.

Secrets

  • MONGODB_URI: Complete MongoDB connection URI (e.g. mongodb+srv://kestra_admin:secret@cluster0.mongodb.net/admin?retryWrites=true&w=majority).
  • SLACK_WEBHOOK_URL: Slack Incoming Webhook URL to receive storage leak alerts and execution status reports.

Quick start

  1. Configure MONGODB_URI and SLACK_WEBHOOK_URL in your Kestra namespace secrets catalog.
  2. Run a manual execution with dry_run: true and auto_remediate: false to audit your GridFS bucket without modifying data.
  3. Review the execution log and Slack summary to inspect confirmed orphaned chunk counts and estimated reclaimable storage.
  4. To remediate, execute with auto_remediate: true and dry_run: false, review the proposed purge plan, and approve the interactive pause_for_operator_approval task in the Kestra UI.
  5. Enable daily_gridfs_hygiene schedule to automate ongoing storage hygiene.

How to extend

  • Corrupted File Metadata Sweep: Add an inverse probe checking fs.files for zero-chunk files (fs.chunks count is 0) to purge ghost metadata entries.
  • Object Storage Archival: Chain an io.kestra.plugin.minio.Upload or S3 task to archive orphaned binary payloads to cold object storage before deletion for compliance.
  • Multi-Bucket Fan-Out: Wrap the workflow in an outer ForEach loop iterating over all GridFS buckets (fs, avatars, reports) across multiple tenant databases.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.