Thanks to visit codestin.com
Credit goes to deepwiki.com

Menu

Web Application

Relevant source files

Purpose and Scope

This page introduces the Trigger.dev webapp, a Remix 2.1.0 application running on Express that serves as the central control plane for the entire system. The webapp provides the dashboard UI, hosts API endpoints for task triggering and management, handles real-time updates, and orchestrates task execution across the infrastructure.

For detailed information on specific subsystems:

Overview

The webapp is the primary interface between developers and the Trigger.dev platform. It serves multiple critical roles:

  1. Dashboard UI: Provides a web interface for monitoring task runs, managing projects, viewing logs, and configuring environments
  2. API Server: Exposes REST and real-time APIs for triggering tasks, managing deployments, and streaming execution data
  3. Coordination Hub: Orchestrates communication between workers, infrastructure providers, and the queue system via Socket.IO
  4. Background Job Processor: Runs internal background jobs using graphile-worker and the custom ZodWorker system
  5. Data Access Layer: Manages all database operations through Prisma ORM with read replica support

The application is designed to run both as a single-instance development server and as a horizontally-scaled production deployment with clustering support.

Sources: apps/webapp/package.json1-289 server.ts1-269

Technology Stack

Key Dependencies

CategoryPackageVersionPurpose
Framework@remix-run/react2.1.0Full-stack React framework with server-side rendering
Serverexpress4.20.0HTTP server with middleware support
Database ORM@prisma/client6.14.0Type-safe PostgreSQL queries with read replica support
Caching/Locksioredis5.3.2Redis client for distributed state
Real-timesocket.io4.7.4WebSocket communication with fallbacks
Background Jobsgraphile-worker0.16.6PostgreSQL-based job queue
Validationzod3.25.76Runtime type validation
Authremix-auth3.6.0Authentication framework
Observability@opentelemetry/*0.203.0 / 2.0.1Distributed tracing

Sources: apps/webapp/package.json32-216

System Integration

The webapp acts as the central nervous system connecting all Trigger.dev components:

High-Level Component Integration

Sources: server.ts91-268 app/root.tsx1-133 app/entry.server.tsx1-258 apps/webapp/app/components/navigation/SideMenu.tsx1-614 apps/webapp/app/utils/pathBuilder.ts1-504

Core Responsibilities

1. HTTP Request Handling

The Express server in server.ts91-179 configures the HTTP layer with:

  • Compression middleware server.ts93-95: Gzip/deflate via compression(), disabled if DISABLE_COMPRESSION=1
  • Static asset serving server.ts101-105:
    • /build artifacts: immutable: true, maxAge: "1y"
    • /public assets: maxAge: "1h"
  • Request logging server.ts107: Morgan HTTP logger with "tiny" format
  • Request ID generation server.ts147-148: Unique nanoid() assigned per request
  • HTTP context tracking server.ts149-152: runWithHttpContext({ requestId, path, host, method }, next) with AsyncLocalStorage
  • Rate limiting server.ts169-170:
    • apiRateLimiter from build.entry.module.apiRateLimiter
    • engineRateLimiter from build.entry.module.engineRateLimiter
  • Security headers server.ts127-133:
    • Strict-Transport-Security: max-age=3153600000
    • X-Robots-Tag: noindex, nofollow (except on cloud.trigger.dev)

2. Clustering and High Availability

The server supports horizontal scaling via Node.js cluster module server.ts15-89:

Configuration server.ts18-21:

Primary Process Responsibilities server.ts23-89:

Worker Process server.ts91-268:

  • Handles HTTP requests via Express independently
  • Sets process title: node webapp-worker-{id} or node webapp-server server.ts109-111
  • Exits with code 0 after closeServer() on graceful shutdown server.ts209-220

3. Real-time Communication Upgrades

The server handles WebSocket upgrades for two protocols server.ts228-263:

Socket.IO Upgrade server.ts238-244:

Used for bidirectional communication with:

  • Coordinator service (apps/coordinator)
  • Infrastructure providers (Kubernetes, Docker)
  • Task worker containers

WebSocket Upgrade server.ts246-263:

Used for development mode real-time task execution streaming

4. Database Access

The webapp uses Prisma Client with two connection types app/db.server.ts:

  • Primary client: Write operations to main PostgreSQL instance
  • Replica client: Read operations to read replica (when DATABASE_READ_REPLICA_URL configured)
  • Transaction wrapper: $transaction utility with OpenTelemetry tracing

Configuration from app/env.server.ts31-46:

5. Environment Variable Management

All environment variables are centrally managed and validated using Zod schemas in app/env.server.ts28-683 Categories include:

  • Database: Connection URLs, pool sizes, timeouts
  • Redis: Multiple Redis instances for different purposes (cache, rate limiting, pubsub, realtime streams)
  • Security: Secrets for sessions, magic links, encryption, provider/coordinator auth
  • Deployment: Container registry configuration, image platform, timeouts
  • OTEL: Trace/log/metric exporters, batch processing settings, attribute limits
  • MARQS: Queue system configuration, concurrency limits, polling intervals
  • Run Engine: Worker counts, timeout values, lock settings

Sources: app/env.server.ts1-683 server.ts91-268

Application Structure

Directory Layout

apps/webapp/
├── app/                          # Remix application code
│   ├── routes/                   # Route handlers
│   │   ├── api.*.ts             # REST API endpoints
│   │   ├── realtime.*.ts        # SSE streaming endpoints
│   │   ├── otel.*.ts            # OpenTelemetry ingestion
│   │   └── $orgSlug.*/          # Dashboard UI routes
│   ├── components/               # React components
│   │   ├── primitives/          # Base UI components
│   │   ├── layout/              # Layout components
│   │   └── runs/                # Run visualization
│   ├── services/                 # Business logic services
│   ├── presenters/               # Data aggregation for loaders
│   ├── v3/                       # V3 task system code
│   │   ├── services/            # Task management services
│   │   ├── marqs/               # MARQS queue implementation
│   │   └── handleSocketIo.server.ts  # Socket.IO setup
│   ├── db.server.ts             # Prisma client configuration
│   ├── env.server.ts            # Environment variable schema
│   ├── root.tsx                 # Root layout component
│   ├── entry.server.tsx         # Server-side entry point
│   └── entry.client.tsx         # Client-side hydration
├── prisma/                       # Database utilities
│   ├── seed.ts                  # Database seeding
│   └── populate.ts              # Test data generation
├── public/                       # Static assets
├── build/                        # Compiled output
├── server.ts                     # Express server entry
└── package.json                  # Dependencies and scripts

Key Files

FilePurpose
server.ts1-269Express server setup, clustering, WebSocket upgrades
app/root.tsx1-133Root Remix component with global context providers
app/entry.server.tsx1-258Server-side rendering, bot detection, error handling
app/entry.client.tsx1-16Client-side hydration with React context
app/db.server.tsPrisma client with read replica support
app/env.server.ts1-683Environment variable validation and configuration

Sources: server.ts1-269 app/root.tsx1-133 app/entry.server.tsx1-258

Request Flow Architecture

Typical Dashboard Request Flow

API Task Trigger Request Flow

Sources: server.ts91-179 app/entry.server.tsx122-172 apps/webapp/app/routes/api.v1.tasks.$taskId.trigger.ts

Build and Deployment

Docker Build Process

The webapp is containerized using a multi-stage Dockerfile docker/Dockerfile1-116:

Stage Breakdown

  1. goose_builder Dockerfile3-4: Compiles Goose binary for ClickHouse migrations
  2. pruner Dockerfile6-12: Uses Turbo's prune --scope=webapp --docker to extract minimal dependency tree
  3. base Dockerfile15-21: Installs OpenSSL and dumb-init, copies package manifests
  4. dev-deps Dockerfile24-29: Installs all dependencies including build tools
  5. production-deps Dockerfile32-41: Installs only production dependencies, generates Prisma client
  6. builder Dockerfile44-74:
    • Copies full source code
    • Runs pnpm run generate for Prisma and other codegen
    • Runs pnpm run build --filter=webapp... using Turbo
    • Uploads sourcemaps to Sentry
  7. runner Dockerfile77-115:
    • Copies only runtime dependencies and built artifacts
    • Includes Goose binary and ClickHouse schema files
    • Sets build metadata (version, git SHA, timestamp)
    • Configures entrypoint script

Entrypoint Script

The docker/scripts/entrypoint.sh1-51 script runs on container start:

  1. Wait for database: Uses wait-for-it.sh to ensure PostgreSQL is ready
  2. Run Prisma migrations: pnpm --filter @trigger.dev/database db:migrate:deploy
  3. Run ClickHouse migrations: Uses Goose to apply schema migrations if CLICKHOUSE_URL is set
  4. Copy Prisma files: Moves schema and engine binaries to webapp directory
  5. Start Node.js: Launches server with configurable heap size via NODE_MAX_OLD_SPACE_SIZE

Sources: docker/Dockerfile1-116 docker/scripts/entrypoint.sh1-51

Build Configuration

Turbo manages the build pipeline turbo.json1-147 The webapp build:

Build scripts from apps/webapp/package.json7-23:

Sources: turbo.json4-14 apps/webapp/package.json7-23 docker/Dockerfile66-74

Bootstrap and Initialization

On server startup, multiple initialization routines run app/entry.server.tsx190-257:

Singleton Initialization

Graphile Worker entry.server.tsx190-192:

Initializes the background job system from ~/services/worker.server. This starts the graphile-worker pool that processes background jobs like:

  • Deployment status updates
  • Alert notifications
  • Scheduled task triggers

Bootstrap entry.server.tsx194-196:

Runs environment setup from ~/bootstrap including:

  • Database connection validation
  • Redis connection tests
  • Initial system health checks

Run Engine Event Handlers entry.server.tsx230:

Registers event bus handlers from ~/v3/runEngineHandlers.server that react to:

  • RUN_CREATED: Initialize run tracking
  • RUN_STARTED: Update execution metadata
  • RUN_COMPLETED: Process completion hooks
  • RUN_FAILED: Trigger retry logic or alerts

Conditional Features

Event Loop Monitor entry.server.tsx245-247:

Monitors event loop lag to detect blocking operations. Logs warnings when the loop is blocked beyond threshold.

Resource Monitor entry.server.tsx255-257:

Tracks memory usage, CPU usage, and heap statistics at 1-second intervals.

Remote Builds entry.server.tsx249-253:

Determines whether to use Depot for remote Docker builds or local buildx based on DEPOT_TOKEN presence.

Global Error Handling

The server installs a process.on('uncaughtException') handler entry.server.tsx206-228 that:

  • Checks if error is Prisma.PrismaClientKnownRequestError or Prisma.PrismaClientUnknownRequestError
  • Logs Prisma errors with full metadata but does NOT exit process
  • For non-Prisma errors, logs with OpenTelemetry context and exits with code 1
  • Prevents cascading failures from database connection issues

Sources: app/entry.server.tsx190-258 server.ts1-269

Development vs Production Modes

The webapp adapts behavior based on NODE_ENV:

FeatureDevelopmentProduction
ClusteringDisabled (single worker)Optional via ENABLE_CLUSTER=1 server.ts18
Live ReloadEnabled via broadcastDevReady() server.ts194-198Disabled
Source MapsGeneratedGenerated + uploaded to Sentry apps/webapp/package.json23
Hot Module ReloadSupported by RemixN/A
Dev Queue ConsumerActive (if WORKER_ENABLED=true)Active
Broadcast Dev ReadyEnabledDisabled
Bot DetectionFull SSR (onAllReady) entry.server.tsx87-101Streaming SSR (onShellReady) entry.server.tsx139-153
Process Titlenode webapp-server server.ts109-111node webapp-server or node webapp-worker-{id}

Development Mode Initialization server.ts194-198

This triggers Remix's hot module reload (HMR) system to notify the client that the server is ready, enabling live reload on file changes.

Bot Detection and SSR Strategy entry.server.tsx46-68

Bots receive the complete HTML after all data fetching completes, while browsers receive streaming HTML for faster time-to-first-byte.

Sources: server.ts109-198 app/entry.server.tsx23-172

Environment Variable Organization

The app/env.server.ts1-683 file organizes configuration into logical groups:

Each variable is validated with Zod schemas that provide:

  • Type coercion (e.g., z.coerce.number())
  • Default values
  • Validation rules (e.g., regex patterns, min/max values)
  • Transformations (e.g., fallback to base Redis config)

Sources: app/env.server.ts1-683

Testing Strategy

The .cursor/rules/webapp.mdc file outlines testing best practices .cursor/rules/webapp.mdc14-21:

Ideally, the env.server.ts file would never be imported into a test file, either directly or indirectly. Tests should only imported classes and functions from a file matching app/**/*.ts of the webapp, and that file should not use environment variables, everything should be passed through as options instead.

This "service/configuration" separation pattern is demonstrated in:

  • Service: app/services/realtimeClient.server.ts (testable, accepts configuration)
  • Configuration: app/services/realtimeClientGlobal.server.ts (singleton with env vars)

Sources: .cursor/rules/webapp.mdc1-41