GUIDE, WITHOUT THE GUESSWORK

Why Coolify Deploys Are Slow (And How to Make Them Vercel-Fast)

Coolify deploys feel slow because the defaults favour simplicity over speed. Three causes — undersized VPS, no build cache, wrong build strategy — and the fixes.

Why Coolify Deploys Are Slow (And How to Make Them Vercel-Fast)

"My Coolify deploy takes 4 minutes; on Vercel the same app deployed in 30 seconds." This complaint is real, and the fix isn't switching back to Vercel. It's recognising that Coolify gives you the levers to be fast — they just aren't on by default.

Slow deploys on Coolify almost always trace to one of three causes: under-sized VPS, no build cache, or the wrong build strategy for the app. Here's how to diagnose and fix each.

First: measure where the time goes

Before optimising, find out where the seconds actually go. Coolify's deploy log shows phase timings. Typical breakdown for a slow deploy:

Pulling source from git              5s
Building Docker image               180s
Pushing image to local registry     20s
Pulling image on target server      8s
Stopping old container              5s
Starting new container              12s
Health check                        20s
─────────────────────────────────
Total                              250s

The build phase dominates. That's the lever to pull.

Cause 1: Under-sized VPS

Building Docker images is CPU-and-IO bound. A $5 VPS with 1 vCPU and 1 GB RAM will absolutely take 4+ minutes for a Next.js or Rails build.

The cheap test: watch CPU and memory during a deploy.

# Run during a deploy
top -b -n 1 | head -20
free -m
df -h /var/lib/docker

If CPU is pinned at 100% for the full build, your CPU is the bottleneck. If swap is being touched, RAM is the bottleneck.

For most modern web apps, the deploy-friendly sweet spot is:

Going from a $5 VPS to a $20 VPS often cuts deploy time by 60% — and you save more in your time than you spend on the bigger box.

Cause 2: No build cache

By default, Coolify rebuilds Docker images from scratch every deploy. If your Dockerfile starts with RUN npm install, every deploy re-downloads every package.

Three fixes:

Fix A: Better Dockerfile layering

Make sure dependencies are installed before you copy your source code. The lockfile rarely changes, so the dependency layer caches well:

# Bad — rebuilds deps on every code change
COPY . .
RUN npm install
RUN npm run build

# Good — deps cached separately from code
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build

This single change can take a 3-minute build down to 30 seconds when only your source code changed.

Fix B: BuildKit cache mounts

If you're on a recent Docker (BuildKit enabled), use cache mounts for package managers:

# syntax=docker/dockerfile:1.4
FROM node:20-alpine
WORKDIR /app
COPY package.json package-lock.json ./
RUN --mount=type=cache,target=/root/.npm npm ci
COPY . .
RUN npm run build

The --mount=type=cache line keeps npm's download cache on the host between builds. First build is normal speed; subsequent builds skip re-downloads even if the lockfile changed.

Same pattern works for pip, apt, cargo, go modules, and pnpm.

Fix C: Coolify's "Build Pack" cache

In Coolify → Service → Build, set "Build Pack" appropriately. The "Nixpacks" pack is usually slower than a hand-written Dockerfile because it does broader detection. If you have a working Dockerfile, set Build Pack to "Dockerfile" and point at it.

Cause 3: Wrong build strategy

Some apps don't need to be rebuilt every deploy.

Static sites — pre-build and ship

If your app is a Next.js export, an Astro build, a Hugo site, etc., the artifact is static. Build once locally or in CI, push to a registry, and have Coolify pull the prebuilt image. Coolify becomes a deployer, not a builder.

# docker-compose for Coolify
services:
  app:
    image: ghcr.io/yourorg/yourapp:v1.2.3
    # No build: section. Coolify just pulls.

Deploy time drops from "build + push + deploy" to "pull + deploy" — usually 20-30 seconds total.

Multi-stage builds

If your final image is small but your build needs heavy tooling (Webpack, Maven, Gradle, etc.), use multi-stage:

FROM node:20 AS builder
WORKDIR /app
COPY . .
RUN npm ci && npm run build

FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
CMD ["node", "dist/server.js"]

The runtime image is small, and Coolify pushes/pulls less data per deploy.

Skip rebuilds for CSS-only changes

If you're touching only CSS or templates and your tooling supports HMR or hot reload, you don't always need a full container rebuild. Set up a volume mount for the assets directory and docker compose restart the service instead of redeploying.

This is a development-mode optimisation; keep production deploys properly atomic.

The CI pipeline pattern

For teams shipping multiple times per day, the right pattern isn't "make Coolify build faster." It's:

  1. CI builds and pushes the image to a registry (GitHub Container Registry, Hetzner registry, etc.).
  2. Coolify pulls and deploys by image tag, no build phase at all.

Deploys become 20-30 second pull-and-restart events. CI can take its time and use bigger machines.

git push → GitHub Actions → docker build + push → webhook to Coolify → docker pull + restart

Coolify supports this via "Deploy from registry" mode plus a webhook trigger.

When the problem is the app, not Coolify

Some apps are slow to build no matter what. Java/Maven projects with hundreds of dependencies, Rails apps with asset pipeline compilation, large monorepos. For these, the answer isn't tuning Coolify — it's:

The deploy speed feedback loop in your dev workflow matters. A 4-minute deploy makes you batch changes; a 30-second deploy makes you ship as you go. The latter is almost always better for product velocity.

Internal links

Closing principle

Coolify deploy speed is a tuning problem, not a tool limitation. The default config favours simplicity over speed; the production-ready config is faster than most managed PaaS for everything except the very first deploy. Spend an hour on Dockerfile layering, build cache, and (if needed) a CI-to-registry pipeline, and you'll match Vercel-speed deploys on hardware you control.

From across the StoicSoft network

Hand-curated reads on the same topic from sister sites in the StoicSoft family.