A scheduled query is SQL plus a cron schedule. On each tick Canner runs the SQL for you in Montreal and records the result. The SQL is free-form: it can SELECT, or CREATE TABLE, INSERT, UPDATE, MERGE — whatever the job needs. This is the SQL counterpart to a scheduled job, which instead calls a webhook in your app.
Reference your databases by name
A scheduled query can reach any project database your account owns, referenced by its project slug — project.schema.table (the schema is usually public). There is no dropdown and no "attach" step: name a database in the SQL and Canner connects you to it, for reads and writes. Because you can name more than one, a single query can join or move data across projects. (A hyphen in a slug becomes an underscore in the name — project my-shop is my_shop.public.table.)
Where results go
Nothing is materialised for you — the SQL decides. Qualify a table with a project and it lands in that project's real Postgres database, where your app can read it:
-- Nightly rollup written into your project's own Postgres.
CREATE OR REPLACE TABLE shop.public.daily_sales AS
SELECT date_trunc('day', created_at) AS day,
count(*) AS orders,
sum(amount) AS revenue
FROM shop.public.orders
GROUP BY 1;A cross-project example — join two databases you own and append to a third:
-- Join two projects you own and append the result to a third. INSERT INTO warehouse.public.customer_orders SELECT o.id, o.amount, c.segment FROM shop.public.orders o JOIN crm.public.customers c ON c.id = o.customer_id WHERE o.created_at >= now() - interval '1 day';
A plain SELECTthat writes nothing is still valid; its result is logged as a small preview and then discarded. If a result isn't captured by the SQL, it's gone — like a query at a database prompt.
Create one
Go to Compute → Scheduled queries → New scheduled query and fill in three things: a name, the SQL, and a schedule. That's the whole form.
The schedule
Schedules use standard 5-field cron — minute hour day-of-month month day-of-week — and all times are UTC. The picker offers Simple (hourly / daily / weekly) or a raw cron expression.
0 5 * * * # every day at 05:00 UTC 0 * * * * # every hour, on the hour */30 * * * * # every 30 minutes 0 6 * * 1 # every Monday at 06:00 UTC
Runs, history & cancelling
Open a query to see its run history — each run is Succeeded, Failed, Timeout, or Cancelled. You can Run now to test without waiting for the next tick, Pause and resume a query, and cancel a run that is still queued or running. Each run is bounded by a timeout; a query that overruns is recorded as a timeout.
How a run is isolated
Each run executes in an isolated, in-memory SQL engine with a per-run memory cap and timeout, and with local filesystem access disabled — a query can reach your Postgres databases over the network but cannot read or write files on the host. It can only see databases your own account owns; another tenant's data is never reachable. Everything runs in Montreal; nothing about the query or its results leaves Canada.
Plans
Scheduled queries are available on every plan. Plans differ by execution priority — best-effort on Starter, prioritised on Live, dedicated capacity on Dedicated. See Plans & limits. To explore or transform uploaded files with SQL instead, see Data Workshop.