What Background Jobs Does Plane Support? A Complete Guide to Celery Tasks in Plane

Plane supports periodic Celery jobs, asynchronous on-demand tasks, and soft-delete utilities, all defined in apps/api/plane/celery.py and implemented in the apps/api/plane/bgtasks/ package.

The open-source project management platform Plane relies on Celery and django-celery-beat to power its background jobs infrastructure. These background jobs handle everything from email notifications and data cleanup to telemetry metrics and issue automation. Understanding the task system in the makeplane/plane repository helps developers customize schedules and extend functionality without blocking the main application thread.

Types of Background Jobs in Plane

Plane organizes its background workload into three distinct categories: periodic scheduled tasks, asynchronous on-demand operations, and data lifecycle utilities.

Periodic Scheduled Tasks

Plane runs a comprehensive set of cron-like jobs through Celery Beat. The scheduler configuration in apps/api/plane/celery.py registers tasks that execute at fixed intervals or specific UTC times:

  • Every 5 minutes: plane.bgtasks.email_notification_task.stack_email_notification aggregates pending email notifications and dispatches them to users.
  • Configurable interval (METRICS_PUSH_INTERVAL_MINUTES): plane.license.bgtasks.telemetry_metrics.push_instance_metrics transmits usage data to the licensing server.
  • Daily at UTC 00:00: plane.bgtasks.deletion_task.hard_delete permanently removes objects that have been soft-deleted past the retention period.
  • Daily at UTC 01:00: plane.bgtasks.issue_automation_task.archive_and_close_old_issues auto-archives stale issues.
  • Daily at UTC 01:30: plane.bgtasks.exporter_expired_task.delete_old_s3_link purges expired export files from S3 storage.
  • Daily at UTC 02:00: plane.bgtasks.file_asset_task.delete_unuploaded_file_asset cleans up file-asset records that never received uploads.
  • Daily at UTC 02:30: plane.bgtasks.cleanup_task.delete_api_logs purges old API request logs.
  • Daily at UTC 02:45: plane.bgtasks.cleanup_task.delete_email_notification_logs removes stale email notification entries.
  • Daily at UTC 03:00: plane.bgtasks.cleanup_task.delete_page_versions deletes historic page version records.
  • Daily at UTC 03:15: plane.bgtasks.cleanup_task.delete_issue_description_versions cleans up issue description snapshots.
  • Daily at UTC 03:30: plane.bgtasks.cleanup_task.delete_webhook_logs clears old webhook request logs.
  • Daily at UTC 03:45: A duplicate delete_old_s3_link entry ensures expired exports are cleared.

Asynchronous On-Demand Tasks

Various @shared_task functions throughout the bgtasks/ directory handle discrete operations triggered by user actions or system events. These include workspace_seed_task for initializing workspaces, workspace_invitation_task for sending invitations, webhook_task for processing webhook deliveries, user_activation_email_task, issue_automation_task, notification_task, and event_tracking_task.

Data Lifecycle Utilities

The soft_delete_related_objects task in apps/api/plane/bgtasks/deletion_task.py recursively marks related objects as deleted when a parent instance is soft-deleted, maintaining referential integrity while preserving data for potential recovery.

Core Configuration and Scheduling

The Celery application and beat schedule are centralized in apps/api/plane/celery.py. This configuration file defines the beat_schedule dictionary that registers all periodic tasks with their execution frequencies. The django_celery_beat application is registered in apps/api/plane/settings/common.py, enabling database-backed scheduling that allows administrators to modify task intervals without redeploying code.

Implementing Custom Background Jobs

Developers can extend Plane's background job system by adding new periodic tasks or triggering asynchronous operations from views and services.

Adding a New Periodic Task

To run a custom task daily at 04:00 UTC, update the beat schedule in apps/api/plane/celery.py:


# apps/api/plane/celery.py

app.conf.beat_schedule.update({
    "my-daily-task": {
        "task": "plane.bgtasks.my_tasks.do_something",
        "schedule": crontab(hour=4, minute=0),  # UTC 04:00

    },
})

Then create the task implementation:


# apps/api/plane/bgtasks/my_tasks.py

from celery import shared_task

@shared_task
def do_something():
    # Insert business logic here

    print("Running my daily maintenance job")

Triggering Tasks Asynchronously

Enqueue background jobs from any part of the codebase using the delay() method:

from plane.bgtasks.email_notification_task import send_email_notification

# Queue the email notification for issue 42

send_email_notification.delay(
    issue_id=42,
    notification_data={...},
    receiver_id=7,
    email_notification_ids=[1, 2, 3],
)

This non-blocking call hands the work to Celery workers while the request thread continues processing.

Implementing Soft-Delete Workflows

When you need to soft-delete a model and its dependencies:

from plane.bgtasks.deletion_task import soft_delete_related_objects

soft_delete_related_objects.delay(
    app_label="projects",
    model_name="issue",
    instance_pk=123,
)

The helper walks every reverse relation, marks related rows as deleted, and finally marks the target instance.

Summary

  • Plane uses Celery and django-celery-beat for all background job processing, configured in apps/api/plane/celery.py.
  • Periodic tasks run at intervals ranging from every 5 minutes to daily UTC schedules for notifications, metrics, and cleanup.
  • On-demand tasks handle webhooks, workspace invitations, user activations, and event tracking via @shared_task decorators.
  • Data cleanup utilities include hard-delete operations, expired export removal, and log purging to maintain database hygiene.
  • Soft-delete helpers recursively mark related objects for deletion while preserving data integrity.
  • Custom tasks can be added by updating the beat schedule and creating task files in apps/api/plane/bgtasks/.

Frequently Asked Questions

What task queue does Plane use for background jobs?

Plane uses Celery with Redis as the message broker, configured in apps/api/plane/celery.py. The django-celery-beat extension provides database-backed periodic task scheduling, allowing dynamic schedule adjustments through the Django admin interface.

How often does Plane process email notifications?

The stack_email_notification task runs every 5 minutes to aggregate pending email notifications and dispatch them to users. This frequency balances timely delivery with system resource usage.

Can I customize the schedule for background jobs in Plane?

Yes. You can modify the beat_schedule dictionary in apps/api/plane/celery.py for code-based changes, or use the Django admin interface provided by django-celery-beat to adjust intervals and enable/disable tasks without redeploying the application.

How does Plane handle data retention and deletion?

Plane implements a two-phase deletion strategy. The soft_delete_related_objects task marks objects and their dependencies as deleted while preserving data. The hard_delete task runs daily at UTC 00:00 to permanently remove objects that have exceeded the configured retention period. Additional cleanup tasks remove expired exports, orphaned file assets, and stale logs throughout the early morning hours.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →