VendoVendo Docs
Deploy & publishOperate

Teardown

Destroying a deployment — what disappears, what's irreversible, and when this is actually the right move.

Teardown is the destructive operation. The Railway project is deleted, the Neon branch is dropped, the R2 bucket is emptied, the Cloudflare Worker Custom Domain is removed, KV mappings are wiped, and the deployment row is marked destroyed. Tenants lose every piece of data the tool produced. There is no undo.

This is rarely the right answer while debugging a problem. Suspend instead, fix the issue, and resume. Reach for teardown when the deployment is genuinely meant to end.

Teardown is irreversible. There is no soft-delete, no recovery window, no backups outside what your tool's storage providers retain by their own policy. Tell tenants exactly what disappears before they confirm.

What teardown destroys

ResourceDestroyed by teardown
Railway project (compute, services, volumes)Yes
Neon Postgres branch (schema + data)Yes
R2 bucket and contentsYes
Cloudflare Worker Custom DomainYes
KV mapping deploy:{subdomain}Yes
vendo_api_key (proxy key)Yes (revoked + KV key wiped)
app_connection_bindings for this deploymentYes
deployment_env_varsYes
deployment_credentialsYes
deploy_logsYes
deployments rowNo — flipped to status='destroyed', retained for audit
apps rowNo — retained, but disconnected_at is set to now() by the disconnect_authorization phase
usage_eventsNo — retained for billing history

What survives

  • Audit datadeployments, apps, usage_events rows are retained. This is for billing and support, not for recovery.
  • Other deployments of the same tool. Teardown is scoped to one deployment row. The same tenant deploying the same tool again is a fresh row with fresh state.
  • The tool's catalog entry. Tearing down a tenant's instance has zero effect on the catalog.

Who can trigger it

  • Tenant — dashboard "Destroy" button. Confirmation dialog with a typed-confirmation field.
  • Suspension reaper — automatic after 90 days suspended (see Suspend & resume).
  • Internal teardown via support — for stuck deployments where the workflow can't recover.

Tool authors don't tear down tenant deployments. Even with admin access on the catalog entry, teardown is a tenant action.

The workflow

TeardownWorkflow (cloudflare/deploy-worker/src/workflows/teardown.ts) runs idempotent phases:

  1. fetch_deployment — load the row, short-circuit if already destroyed.
  2. teardown_computeprojectDelete on Railway (or equivalent on other providers).
  3. teardown_databases — drop the Neon branch (and any other database providers attached).
  4. remove_dns — remove the Cloudflare Worker Custom Domain / DNS record.
  5. revoke_proxy_keys — invalidate vendo_api_key (and any other proxy keys bound to the deployment).
  6. delete_r2_bucket — empty and delete the deployment's R2 bucket.
  7. wipe_credentials — null out deployment_credentials and deployment_env_vars rows.
  8. disconnect_authorization — set apps.disconnected_at = now() on the linked apps row so the catalog UI knows this binding is soft-detached.
  9. finalizestatus='destroyed', destroyed_at=now().

Each phase checks current state before acting — re-running the workflow on a partially-destroyed deployment is safe.

teardown_compute is the phase that matters most for cost — orphaned Railway projects keep accruing charges. If teardown fails at this step, verify the Railway project still exists, delete it manually, and retry the teardown (POST /api/deployments/[id]/destroy).

Edge cases

  • Teardown on a failed deploy that never recorded a projectId. The workflow short-circuits cleanly because deploy_compute guards against projectDelete(undefined). No manual cleanup needed.
  • Teardown on suspended. Works the same way. The compute is already paused, but the workflow still calls projectDelete to fully release resources.
  • Teardown during an in-flight upgrade. The upgrade is preempted. If the image swap completed but the readiness check was still polling, the teardown drops the now-running new revision along with everything else.

What tenants see

After teardown:

  • The deployment URL — {tenant_slug}-{deployment_slug}.vendo.run for new deployments (single-level format), or the legacy {deployment_slug}.{tenant_slug}.vendo.run for older ones — returns NXDOMAIN within minutes (CF DNS propagation).
  • The deployment row hides from the dashboard's default Apps view (filter status != 'destroyed').
  • The dashboard's history view still shows the row with a "Destroyed" badge for audit.

When teardown is the right move

  • The tenant is decommissioning the workload permanently.
  • They want to re-deploy from scratch with a different deployment_slug.
  • A failed deployment can't be retried (rare — almost always retry first).
  • A resume_failed deployment is permanently broken (rare — retry first, escalate to support before tearing down).

In every other case, prefer suspend (free) or restart (cheap, lossless).

On this page