Install / Scheduler

Cron Scheduler

Open Astra runs a built-in cron scheduler that manages 12 recurring maintenance jobs — from cost aggregation and token cleanup to memory decay and heartbeat monitoring. It also supports dynamic scheduled agents loaded from the database, allowing you to configure agents to run on any cron expression.

Built-in jobs

These jobs are registered automatically at gateway startup. All times are in the server's local timezone.

text
Schedule            Job                          What it does
──────────────────────────────────────────────────────────────────────────────
0 1 * * *           Cost snapshot                 Aggregate billing_usage → cost_snapshots
30 2 * * *          Memory retention purge        Per-workspace TTL-based data purge
0 3 * * *           Token cleanup                 Delete expired/revoked refresh_tokens
15 3 * * *          Revocation prune              Delete expired rows from revoked_tokens
30 3 * * *          Payload TTL                   Delete expired inference_payloads
0 4 * * *           Memory consolidation          Merge and compress daily_memory entries
15 4 * * *          Memory weight decay            Decay entries older than 7 days (0.12/day)
0 5 * * *           Memory summarization          Summarize for users active in last 2 days
30 4 * * 0          Graph reinforcement decay     Weekly knowledge graph edge decay
*/5 * * * *         Heartbeat monitor             Run due heartbeat checks
*/30 * * * *        Dream schedule check          Check user_dream_configs, emit dream.scheduled
*/30 * * * *        Research iteration            Advance planning/researching tasks

Memory weight decay

The daily memory decay job (4:15 AM) gradually reduces the weight of older memory entries, ensuring recent information is prioritized during retrieval. Entries lose 0.12 weight per day after a 7-day grace period, reaching zero (effectively archived) around day 16.

sql
-- Memory entry weight decay formula
-- Applied to daily_memory.entries JSONB array
-- Only entries older than 7 days are affected

-- For entries with an existing weight:
new_weight = GREATEST(0.0, existing_weight - 0.12)

-- For entries without a weight field (legacy):
new_weight = GREATEST(0.0, 1.0 - (days_past_7 * 0.12))

-- Examples:
-- Day 7:  weight = 1.0
-- Day 8:  weight = 0.88
-- Day 14: weight = 0.16
-- Day 16: weight = 0.0 (floor)
Not deleted. Decayed entries (weight = 0) are not removed from the database. They stop appearing in search results due to low weight, but remain available for explicit queries and Cold Store snapshots.

Dynamic scheduled agents

Beyond the built-in jobs, you can schedule any agent to run on a cron expression. Scheduled agents are stored in the scheduled_agents table and loaded at startup.

yaml
# In astra.yml or via API — schedule agents to run on a cron expression
# Table: scheduled_agents

id:              UUID
agent_id:        "researcher"
cron_expression: "0 9 * * 1-5"       # weekdays at 9 AM
input_message:   "Check for new papers on LLM safety"
surface:         "scheduled"
surface_id:      "weekly-papers"
enabled:         true
last_run_at:     2026-02-28T09:00:00Z
last_run_error:  null

Each scheduled agent runs the full agent loop with a synthetic user ID. Run status and errors are tracked per row.

text
// Dynamic scheduled agents use a synthetic UID:
uid = "scheduled:<id>"    // e.g., "scheduled:abc-123"

// After each run, the row is updated:
UPDATE scheduled_agents
SET last_run_at = NOW(),
    last_run_error = $error   -- null on success, error message on failure
WHERE id = $id
JobTable(s)Doc link
Cost snapshotbilling_usagecost_snapshotsDaily cost aggregation
Memory retentionsessions, daily_memory, user_profilesPer-workspace TTL purge
Token cleanuprefresh_tokensJWT & Tokens
Revocation prunerevoked_tokensJWT & Tokens
Payload TTLinference_payloadsPayload Audit
Consolidationdaily_memory5-Tier System
Weight decaydaily_memoryEntry Weight Decay
Summarizationdaily_memory, memory_summariesSummarization
Graph decaygraph_edgesRelation Decay
Heartbeatheartbeat_configs, heartbeat_runsHeartbeat Daemon
Dream checkuser_dream_configsDream Mode
Researchresearch_tasksDeep Research

Lifecycle

  • The scheduler starts after the gateway HTTP server is listening
  • Dynamic scheduled agents are loaded from the database at startup and when agents are updated via API
  • On shutdown, all tasks are stopped via stopScheduler()
  • Jobs that fail log errors but do not crash the scheduler — other jobs continue running