Tasks
Run work automatically on a schedule — maintenance jobs, imports, billing runs, reports and automated reminders.
The Task Engine
The Task Engine runs scheduled jobs — anything that should happen automatically on a cadence rather than in response to a user action. Maintenance jobs, recurring imports, billing runs, cleanup, scheduled reports, monitoring checks, automated reminders. If you'd write a cron job for it on a traditional Unix system, you'd write a Task in ActiveManage.
How it runs
A cron job (or equivalent scheduled trigger) on the server calls the platform's task runner every minute. The runner:
- Queries the
.taskstable for tasks whose next-run time has been reached. - For each due task, executes its handler (a PHP function or built-in action).
- Records the run in the Task Log with start/end timestamps and any output.
- Computes the next-run time based on the task's schedule.
The system-level cron entry that triggers all this is typically * * * * * /usr/local/bin/php /home/site/activemanage/taskengine.php. It runs every minute; tasks scheduled less frequently than once-a-minute are handled by the Task Engine deciding which to actually run.
Where tasks live
Architect Panel → Automation → Tasks. Each task has:
- Name — internal name.
- Schedule — cron-style expression.
- Handler — the PHP function or built-in action to run.
- Parameters — JSON object passed to the handler.
- Enabled — toggle to disable temporarily.
- Last run / Next run — automatic, computed by the engine.
- Recent log entries — visible from the task detail page.
Three real-world tasks
Example 1: Nightly cleanup
Name: "Purge soft-deleted records". Schedule: 0 2 * * * (2am daily). Handler: a custom PHP function that hard-deletes rows where MSTisdeleted = 1 and they've been soft-deleted for more than 90 days. Keeps the database from growing unboundedly with soft-deleted records.
Example 2: Monthly billing run
Name: "Monthly subscription billing". Schedule: 0 3 1 * * (3am on the 1st of each month). Handler: iterates subscription packages, charges each active subscription via Stripe, records the transaction, sends invoice emails. Critical infrastructure for any SaaS install.
Example 3: Hourly status check
Name: "Health check external dependencies". Schedule: 0 * * * * (every hour on the hour). Handler: calls each configured external API, records response time and status, alerts if any are failing. Provides visibility into upstream health.
The Task Log
Every task execution is recorded. See the Task Log article in this section for details on what's captured and how to debug failed tasks.
Creating a Scheduled Task
From the Architect Panel → Tasks, click New. The configuration form asks you to define when the task should run and what it should do when it does.
Configuration
- Name — descriptive internal name.
- Schedule — cron-style expression. See the Cron-style Scheduling article for the syntax.
- Handler — pick a built-in action or specify a PHP function name. Built-in actions cover common patterns (purge records, send digest emails, sync external data). Custom PHP handlers handle anything else.
- Parameters — JSON object passed to the handler. The handler uses these to know what specifically to do (e.g. "which datastore to clean up", "which template to send", "what URL to ping").
- Enabled — toggle to disable temporarily without deleting the task.
- Timeout — maximum runtime in seconds before the task is killed (for tasks that might hang).
- Retry on failure — whether failed runs should retry, and how many times.
Schedule examples
Cron syntax is five fields: minute, hour, day-of-month, month, day-of-week. Common patterns:
* * * * *— every minute.*/5 * * * *— every 5 minutes.0 * * * *— top of every hour.0 2 * * *— 2am every day.0 9 * * 1-5— 9am Monday to Friday.0 0 1 * *— midnight on the 1st of each month.0 0 1 1 *— midnight on January 1st (annual).
One-off vs recurring
Most tasks are recurring — they fire on a schedule indefinitely until you disable or delete them. For one-off tasks ("run this once next Tuesday at 9am"):
- Set the schedule to match the desired time (e.g.
0 9 * * 2for 9am Tuesday). - Add logic to the handler that disables the task after successful execution (or use the platform's one-shot task feature if available).
Idempotency
Tasks should be idempotent — running the same task twice should produce the same end state as running it once. This matters because:
- Tasks can occasionally fire twice (e.g. if the cron entry overlaps a long-running task).
- Retries on failure mean a task that partially completed might be retried.
- Manual re-runs (via the Re-run action in the Task Log) should be safe.
Idempotency is typically achieved by:
- Checking before acting (don't insert a record if it already exists; don't send an email if it's already been sent).
- Using transactions to make changes all-or-nothing.
- Recording task progress so a re-run can pick up where it left off.
Three real-world task configurations
Example 1: Daily report email
Schedule: 0 8 * * 1-5 (8am weekdays). Handler: sendDailyReport. Parameters: {"template": "daily-summary", "recipients": ["team@acme.com"]}. Generates yesterday's metrics and emails the team.
Example 2: Sync customers from CRM
Schedule: */15 * * * * (every 15 minutes). Handler: syncCustomersFromCRM. Parameters: {"limit": 100, "since": "last_run"}. Pulls updates from the CRM since the last successful run; idempotent so duplicates are detected and skipped.
Example 3: One-off historical data backfill
Schedule: 0 22 31 12 * (set to a far-future date). Handler: backfillHistoricalOrders. Parameters: {"start_year": 2020, "end_year": 2024}. Self-disables after successful completion. Used once during a data migration and then disabled forever.