If you are deploying your own private instance of toorow, refer to the Self-Hosting Guide for infrastructure setup and configuration instructions.
1. Hosting Topology & Surface Separation
The showcase marketing site, application server, and technical documentation operate as separate surfaces with distinct runtimes, pipelines, and cost profiles:
All three surfaces operate under subdomains of
toorow.com, enabling shared analytics consent (toorow_consent, Domain=.toorow.com) across the platform.
2. Scale-to-Zero Cloud Run Configuration
To minimize idle costs, themcp-server Cloud Run service is explicitly configured to scale to zero instances during inactivity, while capping concurrency to prevent runaway billings:
Cold Start Trade-Off
Setting--min-instances=0 introduces a minor cold-start latency penalty on initial requests following idle periods. This is acceptable for agent-driven MCP workloads and guarantees €0 compute cost when unused.
3. Scheduled and Queued Work — Cloud Tasks, Pub/Sub, Cloud Scheduler
Scale-to-zero has a consequence that is easy to miss and expensive to discover: Cloud Run allocates CPU only while a request is in flight. Between requests an instance is throttled, and at--min-instances=0 there is no instance at all.
A background thread inside the server therefore does not run — it simply does not
get scheduled — and nothing records that it did not.
toorow’s execution substrate is built around that fact.
Three managed components, three distinct jobs:
QUEUE_BACKEND=cloud_tasks selects this substrate; the in-process worker,
scheduler and health-poller threads stand down when it is set. They remain the
default (local) for development, where a machine that stays awake makes them
the simplest thing that works.
Why this shape rather than an always-on instance
- Cost.
--min-instances=0is preserved: the CPU is allocated because the push is a request. Keeping threads alive would require--no-cpu-throttlingwith--min-instances=1, i.e. paying for a permanently running container. - Observability. A scheduled invocation leaves a status code, a log line and an alertable failure — including on the runs that fail. A sleeping thread that never fires leaves nothing.
- Retry that repairs. The raw zone is append-only and staging models
supersede by
pull_id, so re-running a window lands rows again and exactly one row per business key survives. A retry is the repair mechanism, not an accident to be tolerated. - Extensibility. A new consumer subscribes to a published fact without the producer being modified.
Postgres remains the ledger
A queue is transport, not a record: it has a retention policy and cannot be queried, joined or audited months later. Every unit of work is written to Postgres and committed before its task is created, so an operation exists because a row says so — never because a message is in flight. That ordering leaves one gap by construction: a row can commit while its task is never created. A reconciliation sweep re-dispatches anything left pending past a grace period. It re-dispatches only — it never executes the work itself, because an invocation carrying N jobs would give back exactly the unreadability this design removes.Scheduled endpoints
Cloud Tasks pushes each job to
/internal/worker/execute-pull/{job_id} or
/internal/worker/execute-activation/{job_id}. The HTTP status is a contract
rather than information: 200 terminal, 429 come back later (quota), 409 a
live claim, 503 transient.
These endpoints authenticate the platform calling itself through a single
deployment-wide shared secret (INTERNAL_ENDPOINTS_REQUIRE_HEADER, stored in
Secret Manager). It is not a per-user credential — user tokens live encrypted in
app.connection_ref or at Nango — and an OIDC token minted for the service would
replace it entirely.
Provisioning is scripted and idempotent:
app.datastream_executions has moved, because until it does, recurring
retrieval is unverified.
4. Deployment
Deployment is manual and deliberate. There is no automatic pipeline, and there is ONE environment: a single GCP project and a single Cloud Run service,mcp-server. No dev → prod promotion exists.
Server and console (infra/scripts/deploy.sh)
infra/docker/mcp-server/Dockerfile through Cloud Build, pushes
to Artifact Registry (europe-west1-docker.pkg.dev/<project>/connector), deploys
to Cloud Run, then builds and ships the console to Firebase Hosting.
The human gate is a local test run before deploying, not a pipeline approval.
A GitHub Actions deploy workflow existed until 2026-08-02 and was removed: it had
never authenticated once (its Workload Identity secrets were never set) and it was
gated on a CI that had been red since 2026-07-25, so every real deployment had
always been manual. .github/workflows/ci.yml remains, and runs checks only.
Vitrine Deployment (web/deploy.sh)
The showcase marketing site uses a developer-driven deployment script to build the Astro static site into web/dist and deploy directly to Firebase Hosting:
Next Steps & Cross-References
Self-Hosting Guide
Learn how to deploy toorow on your own cloud or container infrastructure.
Security & Constraints
Review host header guards, OAuth verification, and security invariants.
Environment Reference
Inspect required environment variables for Cloud Run deployment.
Prerequisites
Check GCP service permissions and IAM requirements.

