Verify Your Install

Run this after a first install, after an upgrade, and after a restore. Each step exercises a different subsystem, so a failure tells you exactly where to look.

Checklist

#Do thisProvesIf it fails
1Open your Sim URL and create an accountApp, database, TLS, migrationskubectl logs deploy/sim-app — and check the migrations init container
2Sign out and sign back inSession handling, BETTER_AUTH_SECRET, BETTER_AUTH_URLURLs must match your real origin exactly
3Open a workflow and drag two blocks onto the canvasRealtime websocket connectionBrowser console for socket errors; see Networking
4Open the same workflow in a second browser window and editCross-replica collaborationWith >1 replica this needs Redis
5Paste a model API key in settings and run a two-block workflowExecution engine, credential encryption, outbound networkApp logs; check ENCRYPTION_KEY is set and outbound egress is allowed
6Upload a small file in FilesFile storage end to endWith object storage configured: presigned URL + bucket CORS. On local disk: the upload proxies through the app
7Upload a file larger than 50 MBMultipart upload path (object storage only)Confirm ETag is in the bucket's CORS exposed headers
8Create a knowledge base and upload a PDFDocument parsing, embeddings, pgvectorNeeds a hosted embedding provider — see below
9Invite a teammate from workspace settingsEmail deliveryApp logs for the mailer; see Email
10Connect an integration accountOAuth configurationRedirect URI mismatch → see Integrations & OAuth
11Create a workflow with a Schedule trigger set to every minute, deploy it, wait 2 minutesBackground jobsCheck the scheduler's logs — see Background Jobs
12Trigger a workflow via the API with an API keyPublic API and API-key authCheck the key was created successfully in settings

Step 11 is the one most people skip and most often discover broken weeks later. Scheduled workflows and every polling trigger depend on the scheduler, and a wrong or missing CRON_SECRET makes it fail silently from the app's side.

Infrastructure checks

Before the UI walkthrough, confirm the deployment itself is healthy.

# Everything running?
kubectl get pods -n simstudio

# Migrations completed
kubectl logs -n simstudio deploy/sim-app -c migrations --tail=50

# Health endpoints
curl -fsS https://sim.yourdomain.com/api/health

# Background jobs scheduled
kubectl get cronjobs -n simstudio

# Redis configured (multi-replica deployments) — confirms the variable is set,
# not that Redis answers. Steps 3 and 4 below are the real reachability test.
kubectl exec -n simstudio deploy/sim-app -- printenv REDIS_URL
# Docker Compose
docker compose -f docker-compose.prod.yml ps
docker compose -f docker-compose.prod.yml logs migrations
curl -fsS http://localhost:3000/api/health

All six should be present on Compose: simstudio, realtime, db, redis, cron, and a completed migrations.

Reading the failures

Step 1 fails — app will not load. Almost always migrations or database connectivity. Check the migrations init container first; a failed migration deliberately blocks the rollout.

Step 2 fails — login loops or rejects. NEXT_PUBLIC_APP_URL or BETTER_AUTH_URL does not match the origin you are browsing. Both must be the exact public URL, with scheme and no trailing slash.

Step 3 fails — no live updates. The reverse proxy is not passing websocket upgrades, or /socket.io is not routed to the realtime service. If realtime is on a separate hostname, NEXT_PUBLIC_SOCKET_URL must point at it and realtime's ALLOWED_ORIGINS must include the app origin.

Step 4 fails — edits do not sync between windows. With more than one replica, this is Redis. Confirm REDIS_URL is present on both pods.

Step 5 fails — execution errors. Check outbound connectivity to the model provider, then the app logs. If the error is about decrypting a credential, ENCRYPTION_KEY differs from the one that encrypted it.

Step 6 or 7 fails. With object storage configured, a CORS error in the browser console means the bucket policy does not allow your Sim origin; step 7 failing while step 6 passes specifically means ETag is missing from the exposed headers. On local-disk storage there is no CORS involved — uploads proxy through the app, so look at the app logs and the proxy body-size limit instead.

Step 8 fails — knowledge base upload errors. Knowledge bases need a hosted embedding provider — OpenAI, Azure OpenAI, or Gemini. There is no local embedding backend. If a key is set, check pgvector is installed on the database.

Step 9 fails — no email arrives. With no provider configured, emails are written to the app logs instead of sent — check there first to confirm the message was generated, then debug the provider.

Step 11 fails — schedule never fires. Read the scheduler's logs (docker compose logs cron, or kubectl get cronjobs -n simstudio). A 401 there means the app and the scheduler disagree on CRON_SECRET.

After an upgrade

Re-run steps 1, 3, 5, 6, and 11 at minimum. Those cover the app, realtime, execution, storage, and background jobs — the five things a bad upgrade breaks.

After a restore

Run the whole list, and pay special attention to step 5 with an OAuth-backed integration. That is what proves ENCRYPTION_KEY matches the backup. An app that loads and logs in but cannot decrypt credentials looks healthy right up until someone runs a real workflow.

Common Questions

About ten minutes, most of it waiting for step 11's scheduled run. Run the infrastructure checks first — they take seconds and catch the majority of failed installs before you open a browser.
No. Steps 1, 3, 5, 6, and 11 cover the app, realtime, execution, storage, and background jobs. Run the full list after a restore or a significant infrastructure change.

On this page