BunshipBunship
Integrations

Task Queue

Pluggable task queue supporting Trigger.dev and BullMQ — auto-detected via environment variables.

Bunship's AI generation pipeline uses a pluggable task queue with two backends. The system auto-detects which backend to use based on the environment variables you provide.

Backend Comparison

Trigger.devBullMQ
Tasks run onTheir cloudYour server
Vercel Hobby (10s)✅ Works❌ No persistent process
Vercel Pro (300s)✅ Works❌ No persistent process
Self-hosted (VPS)✅ Works✅ Works
Requires RedisNoYes
Stale recoveryScheduled task (cloud)setInterval

Auto-Detection

The adapter is selected by the first matching environment variable:

TRIGGER_SECRET_KEY  ->  Trigger.dev (highest priority)
(fallback)          ->  BullMQ

No code changes needed. Set the right env var for your deployment.

Best for Vercel deployments. Tasks run on Trigger.dev's cloud infrastructure.

Setup

  1. Create account at cloud.trigger.dev
  2. Create a project, note your Project ID and Secret Key
  3. Install the SDK:
bun add @trigger.dev/sdk
  1. Add environment variables:
TRIGGER_SECRET_KEY=sk_dev_your_key_here
TRIGGER_PROJECT_ID=your_project_id

Local Development

# Terminal 1: Start Trigger.dev local dev worker
cd apps/ship-api
npx trigger.dev@latest dev

# Terminal 2: Start your app
bun run dev

Deploy Tasks

Manual deploy:

cd apps/ship-api
npx trigger.dev@latest deploy

This registers ai-generate and the ai-stale-recovery schedule on Trigger.dev.

If your local shell has OTEL_* environment variables (e.g. from Shelltime or other monitoring tools), deploy will fail with cannot merge resource due to conflicting Schema URL. Either clear these variables before deploying or use the CI workflow below.

CI/CD Deploy (GitHub Actions)

A workflow at .github/workflows/deploy-trigger.yml automatically deploys tasks when you push changes to main.

Triggers:

  • Push to main that modifies apps/ship-api/src/services/ai/queue/** or trigger.config.ts
  • Manual dispatch from the Actions tab

Required GitHub Secrets:

SecretDescription
TRIGGER_ACCESS_TOKENPersonal Access Token (tr_pat_ prefix). Generate at cloud.trigger.dev/account/tokens
TRIGGER_PROJECT_IDYour Trigger.dev project ref (e.g. proj_xxx). Optional for the main repo if the default in trigger.config.ts is correct

For forked repos: Fork users set their own TRIGGER_ACCESS_TOKEN and TRIGGER_PROJECT_ID in their repo's Settings → Secrets. The workflow deploys to their own Trigger.dev project — no conflict with the upstream repo.

Production Env Vars (Trigger.dev)

After deployment, tasks run on Trigger.dev cloud. Configure these in Trigger.dev project Environment Variables for prod:

VariableRequiredPurpose
DATABASE_URLYesRead/write task, billing, and recovery data
TRIGGER_SECRET_KEYYesTrigger adapter and SDK auth
S3_ENDPOINTYesObject storage endpoint
S3_REGIONYesObject storage region
S3_ACCESS_KEYYesObject storage key
S3_SECRET_KEYYesObject storage secret
S3_BUCKETYesOutput bucket
NEXT_PUBLIC_S3_URL_BASEYesPublic output URL base
TRIGGER_PROJECT_IDOptionalProject routing (config has fallback)

Provider-specific vars (only for enabled providers):

VariableNeeded when
FAL_API_KEYUsing fal provider
REPLICATE_API_TOKENUsing replicate provider
KIE_API_KEYUsing kie provider
KIE_API_BASE_URLOptional override for kie API base URL

Optional tuning vars:

VariableDefaultPurpose
AI_STALE_QUEUE_FAILOVER_MS900000Base stale timeout
AI_STALE_QUEUE_FAILOVER_GRACE_MS120000Extra grace after queue timeout
AI_STALE_QUEUE_SCAN_LIMIT50Recovery scan batch size

Option B: BullMQ

Best for self-hosted deployments with a persistent server (Railway, Fly.io, VPS).

Requirements

  • Redis instance (Upstash, Railway Redis, or self-hosted)
  • Persistent process (not serverless)

Setup

  1. Ensure REDIS_URL is set and no TRIGGER_SECRET_KEY is present:
REDIS_URL=redis://your-redis-url:6379
  1. Deploy ship-api as a standalone server:
cd apps/ship-api
bun run src/index.ts

The BullMQ worker starts automatically with admission control, retries, and stale-task scanning.

Stale Task Recovery

Regardless of backend, Bunship includes a safety net that automatically fails stuck tasks and refunds credits.

BackendRecovery Mechanism
Trigger.devai-stale-recovery scheduled task (every 5 min, cloud)
BullMQsetInterval in persistent worker process

Code Map

apps/ship-api/src/services/ai/queue/
├── types.ts              # TaskQueueAdapter interface
├── processor.ts          # Shared execution logic
├── adapter-bullmq.ts     # BullMQ implementation
├── adapter-trigger.ts    # Trigger.dev implementation
└── index.ts              # Auto-detection + adapter export

Next Steps