Skip to main content

Timer Functions

Timer functions execute on a schedule you define. Use them for background jobs, cleanup tasks, report generation, and periodic syncs.

How It Works

  1. Set an interval (e.g., every 5 minutes, every 2 hours, daily)
  2. Configure a start time (UTC)
  3. Write JavaScript code or configure an external webhook
  4. Function runs automatically at each interval

Configuration

Schedule Settings

SettingDescription
IntervalNumber of time units between executions
FrequencyUnit of time: Minutes, Hours, or Days
Start Time (UTC)When the first execution should occur

Examples

IntervalFrequencyResult
5MinutesEvery 5 minutes
1HoursEvery hour
12HoursTwice daily
1DaysOnce daily
7DaysWeekly

Automatic Tracking

The system automatically tracks:

PropertyDescription
Last RunWhen the function last executed
Next RunCalculated from last run + interval

Execution Context

Timer functions receive limited context since they're not triggered by a request:

PropertyDescription
scheduledTimeWhen the execution was scheduled
userService account (if configured)

Token Options

OptionDescription
NoneNo authentication
Service AccountExecute with service account permissions
note

Timer functions typically use a service account since there's no "current user" triggering the execution.

Use Cases

Cleanup Jobs

Remove old or expired data:

// Delete sessions older than 24 hours
const cutoff = new Date();
cutoff.setHours(cutoff.getHours() - 24);

await fetch(`${apiUrl}/sessions?filter=createdAt lt "${cutoff.toISOString()}"`, {
method: 'DELETE',
headers: { 'Authorization': `Bearer ${token}` }
});

console.log('Cleaned up expired sessions');

Report Generation

Generate periodic reports:

// Daily sales summary
const today = new Date().toISOString().split('T')[0];

const response = await fetch(
`${apiUrl}/orders?filter=orderDate eq "${today}"`,
{ headers: { 'Authorization': `Bearer ${token}` } }
);
const orders = await response.json();

const totalSales = orders.reduce((sum, o) => sum + o.total, 0);
const orderCount = orders.length;

// Store the report
await fetch(`${apiUrl}/daily-reports`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
date: today,
totalSales,
orderCount,
averageOrder: orderCount > 0 ? totalSales / orderCount : 0
})
});

External Sync

Sync data with external systems periodically:

// Sync inventory from warehouse system every hour
const response = await fetch('https://warehouse.example.com/api/inventory', {
headers: { 'Authorization': `Bearer ${secrets.WAREHOUSE_API_KEY}` }
});
const inventory = await response.json();

for (const item of inventory) {
await fetch(`${apiUrl}/products/${item.sku}`, {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ stockLevel: item.quantity })
});
}

console.log(`Synced ${inventory.length} inventory items`);

Status Checks

Monitor external services or data conditions:

// Check for orders stuck in processing
const oneHourAgo = new Date();
oneHourAgo.setHours(oneHourAgo.getHours() - 1);

const response = await fetch(
`${apiUrl}/orders?filter=status eq "processing" and updatedAt lt "${oneHourAgo.toISOString()}"`,
{ headers: { 'Authorization': `Bearer ${token}` } }
);
const stuckOrders = await response.json();

if (stuckOrders.length > 0) {
// Alert operations team
await fetch('https://slack.webhook.url', {
method: 'POST',
body: JSON.stringify({
text: `⚠️ ${stuckOrders.length} orders stuck in processing for over 1 hour`
})
});
}

Data Aggregation

Pre-calculate aggregates for performance:

// Update category statistics every 15 minutes
const categories = await fetch(`${apiUrl}/categories`, {
headers: { 'Authorization': `Bearer ${token}` }
}).then(r => r.json());

for (const category of categories) {
const products = await fetch(
`${apiUrl}/products?filter=categoryId eq "${category.id}"&count=true`,
{ headers: { 'Authorization': `Bearer ${token}` } }
).then(r => r.json());

await fetch(`${apiUrl}/categories/${category.id}`, {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
productCount: products.meta.count,
lastUpdated: new Date().toISOString()
})
});
}

Best Practices

  • Use appropriate intervals — Don't run more frequently than needed
  • Handle failures gracefully — Timer functions will retry on next interval
  • Log execution details — Track what was processed for debugging
  • Use service accounts — Ensure consistent permissions
  • Consider time zones — Start times are in UTC
  • Monitor execution — Check logs for failures or long-running jobs