AgentifUI Single-Host High-Concurrency Deployment
1. Scope
This guide describes the recommended deployment shape when you want to run AgentifUI on a single Ubuntu host and still preserve reasonable concurrency and stability.
It supplements docs/QUICK-DEPLOYMENT.md. Use this document when:
- You deploy to one physical or virtual Ubuntu server.
- You want better concurrency than a single-process setup.
- You want a production shape that still matches this repository’s runtime architecture.
These are optional performance recommendations, not a second deployment procedure. The bundled ecosystem.prod.config.js uses one fork process per application; it does not enable the cluster topology below. Follow the production runbook for installation, upgrades and recovery.
2. Recommended Topology
Run these components on the same host:
Nginxas the public entrypoint on80/443Next.jsweb service managed by PM2 inclustermodeFastifyAPI service managed by PM2 inclustermodePgBouncerin front of PostgreSQLRedisfor shared cache and invalidationPostgreSQLfor application data and auth state
Recommended request flow:
- Browser traffic reaches
Nginx - Page requests go to
Next.js - Only Fastify-owned business API prefixes go directly to
Fastify; auth and all remaining routes go toNext.js - App services talk to
Redis,PgBouncer, andPostgreSQL
3. Why This Shape Fits This Repository
This project is not a static frontend. It combines:
Next.jsSSR web pages- a separate
FastifyAPI sidecar - authentication and database-backed state
- streaming and realtime endpoints
Because of that, the recommended single-host target is not a single next start process. The better shape is:
- reverse proxy in front
- web and API as separate services
- multiple Node.js worker processes
- controlled database fan-out
4. Core Deployment Rules
4.1 Use a Dedicated Production Checkout
Deploy the confirmed release tag and verified final main commit in a new version directory, not from a moving branch or the active development directory. Keep the previous release’s dependencies and builds available for recovery, as described in the production runbook.
Do not share these between dev and prod:
.nextnode_modulespm2logs- runtime temp files
4.2 Route Only Fastify-Owned API Prefixes Directly to Fastify
At the proxy layer:
- page requests,
/api/auth/better/*and all remaining routes should go toNext.js - only the business API prefixes owned by Fastify should go directly to
Fastify
Use DEFAULT_FASTIFY_PROXY_PREFIXES in next.config.ts as the public baseline, and review any FASTIFY_PROXY_PREFIXES override against the routes registered in apps/api/src/server.ts. Do not route all /api/* traffic to Fastify: it does not serve the Next.js authentication handlers or provide a catch-all proxy back to Next.js.
This avoids pushing high-volume API traffic through the Next.js rewrite layer.
If your public proxy is doing the split, the production environment should generally use:
FASTIFY_PROXY_ENABLED=0
This is a Web build setting. Rebuild after changing it, and set DEPLOY_WEB_BASE_URL to the public reverse-proxy entrypoint for acceptance, as required by the production runbook. If Next.js remains responsible for API rewrites, retain FASTIFY_PROXY_ENABLED=1 instead.
4.3 Run PM2 in Cluster Mode
Do not keep production on instances: 1 with fork mode if your goal is higher concurrency.
Recommended pattern:
Next.jsweb: PM2clusterFastifyAPI: PM2cluster
Suggested starting point:
8 CPU / 16 GB: web2, api316 CPU / 32 GB: web3-4, api4-6
Tune from there based on:
- CPU saturation
- memory pressure
- PostgreSQL load
- upstream Dify latency
4.4 Keep Realtime on db-outbox
For multi-process operation on one host, prefer:
REALTIME_SOURCE_MODE=db-outbox
This is the safer default for cross-process consistency.
4.5 Enable Shared Cache via Redis
This repository already supports local cache plus optional Redis L2 cache.
For multi-process production, enable Redis L2:
CACHE_L2_REDIS_ENABLED=1
Without Redis, each process keeps its own cache and invalidation becomes weaker.
4.6 Keep PostgreSQL Pool Sizes Conservative
Do not solve concurrency by setting very large per-process pool sizes.
Recommended approach:
- keep
PG_POOL_MAXconservative - use
PgBouncerto absorb connection pressure
Suggested starting point:
PG_POOL_MAX=5
PG_POOL_IDLE_MS=30000
PG_POOL_CONNECT_MS=5000
5. Nginx Requirements
Nginx should:
- terminate TLS
- proxy pages, auth and remaining routes to the web service
- proxy only Fastify-owned business API prefixes to the API service
- cache static assets where appropriate
For streaming endpoints such as realtime and Dify stream responses, disable proxy buffering:
proxy_buffering offproxy_request_buffering offproxy_read_timeout 3600
This is important for:
- server-sent events
- long-lived streaming responses
6. Production Environment Baseline
Suggested baseline values:
The FASTIFY_PROXY_ENABLED=0 example assumes the explicit reverse-proxy split in section 4.2; it is not the default production topology.
NODE_ENV=production
FASTIFY_PROXY_ENABLED=0
REALTIME_SOURCE_MODE=db-outbox
CACHE_L2_REDIS_ENABLED=1
PG_POOL_MAX=5
PG_POOL_IDLE_MS=30000
PG_POOL_CONNECT_MS=5000
You still need the normal production settings from docs/CONFIGURATION.md and docs/QUICK-DEPLOYMENT.md, including:
- app URLs
- auth secrets
- database credentials
- Redis URL
- object storage settings
7. Operating System Baseline
Before load testing or production launch, tune the host at least enough to avoid trivial bottlenecks:
- raise
nofile - use
worker_processes autoin Nginx - increase
worker_connections - keep prod and dev runtimes separated
8. Deployment Order
Use pnpm run deploy on the production server, following the production runbook. That procedure covers verified source in a new version directory, production configuration, stable external runtime content, explicit incremental migrations, build records, switching, acceptance and recovery. Do not replace it with a separate manual build/start sequence.
For this optional high-concurrency topology, additionally validate the reverse-proxy route split, PM2 worker configuration and database pool limits before switching. Preserve those settings for recovery, and complete login, chat, history and streaming checks before accepting the release.
9. Not Recommended
These shapes can work, but are not the recommended high-concurrency target for this repository:
- one
next startprocess only - one
pm2forkprocess for web and one for API - exposing the Node.js ports directly to the internet
- using large direct PostgreSQL pool sizes without
PgBouncer - mixing dev and prod inside the same working directory
10. Summary
For a single Ubuntu host, the recommended deployment shape is:
Nginx -> PM2 cluster (Next.js + Fastify) -> Redis + PgBouncer + PostgreSQL
That gives this repository a much better concurrency baseline than a single-process deployment while keeping the setup operationally simple.