14. Scheduled Jobs

Alex needs to clean up expired sessions and send weekly reports automatically.

Scheduled jobs let you run SQL statements or database functions on a recurring schedule. No server needed — Eurobase executes them automatically in your project's database.

Creating a scheduled job

  1. Go to the Cron tab in your project
  2. Click New Job
  3. Give it a name (e.g. "Clean expired sessions")
  4. Choose a schedule preset or write a custom cron expression
  5. Select the action type: SQL (run a query) or RPC (call a function)
  6. Write the SQL or function name
  7. Click Create

Common examples

Clean up expired sessions (every hour)

Schedule: 0 * * * *

DELETE FROM sessions WHERE expires_at < now()

Send weekly digest (every Monday at 9am)

Schedule: 0 9 * * 1

SELECT send_weekly_digest()

Archive old records (daily at midnight)

Schedule: 0 0 * * *

INSERT INTO archive SELECT * FROM logs WHERE created_at < now() - interval '30 days'; DELETE FROM logs WHERE created_at < now() - interval '30 days';

Check pending orders (every 5 minutes)

Schedule: */5 * * * *

SELECT process_pending_orders()

Cron schedule reference

FieldValuesSpecial
Minute0-59* , */N
Hour0-23* , */N
Day of month1-31* , */N
Month1-12* , */N
Day of week0-6 (Sun=0)* , */N

Quick reference

* * * * * — every minute */5 * * * * — every 5 minutes 0 * * * * — every hour 0 0 * * * — daily at midnight 0 9 * * 1 — Monday 9am 0 0 1 * * — 1st of month

Plan limits: Free plan includes 2 scheduled jobs. Pro plan has unlimited jobs.

Jobs run SQL in your project's database schema with full access. They execute as the system user, not as an end-user — RLS policies are bypassed.

RPC Functions

RPC (Remote Procedure Call) functions are reusable PostgreSQL functions stored in your database. Unlike raw SQL cron actions, functions can contain complex logic (loops, conditionals, error handling) and can be called from both cron jobs and your app via the SDK.

RPC vs Cron Job vs DB Trigger vs Edge Function: Eurobase has four kinds of "server-side code" and the distinction matters. Quick gist: RPC = callable SQL (this section). Cron Job = scheduled SQL (above). DB Trigger = reactive SQL fired by row events on a table (managed in Database → Triggers). Edge Function = TypeScript in a Deno container, for external API calls and JS-ecosystem things. The full comparison table in the Edge Functions chapter has language, transactional semantics, and use cases side by side.

Creating a function

When creating a cron job, select "RPC Function" and click "Create New Function". Choose a name, language, return type, and write the function body.

Example: Clean up expired sessions (void — for cron)

Language: PL/pgSQL · Returns: void

BEGIN
  DELETE FROM refresh_tokens WHERE expires_at < now();
  DELETE FROM email_tokens WHERE expires_at < now();
END;

Example: Get active user count (integer — for SDK)

Language: SQL · Returns: integer

SELECT count(*)::integer FROM users WHERE last_sign_in_at > now() - interval '30 days';

Example: Generate daily stats (jsonb — for SDK)

Language: PL/pgSQL · Returns: jsonb

DECLARE result jsonb;
BEGIN
  SELECT jsonb_build_object(
    'total_users', (SELECT count(*) FROM users),
    'active_today', (SELECT count(*) FROM users WHERE last_sign_in_at > now() - interval '1 day')
  ) INTO result;
  RETURN result;
END;

Return types explained

TypeWhen to useSDK result
voidCron jobs, cleanup tasks, side effects onlynull
textReturn a message or formatted string"hello world"
integerReturn a count or numeric value42
booleanReturn true/false checkstrue
jsonbReturn structured data (objects, arrays){'key': 'value'}

Calling functions from the SDK

Functions with a return type (not void) can be called from your app. The return value is sent back as JSON.

// Call an RPC function from the SDK
const { data, error } = await eb.db.rpc('get_active_user_count')
console.log(data) // 42

// Call a function that returns JSON
const { data: stats } = await eb.db.rpc('generate_daily_stats')
console.log(stats) // { total_users: 150, active_today: 23 }

Cron + SDK tip: Create a function that returns void for cron (e.g. cleanup tasks), and separate functions that return data for your SDK calls (e.g. stats, reports). A function can do both — perform side effects and return a result.