Why We Switched to SQLite
For our new SaaS, we ditched PostgreSQL for SQLite. Here is why it saved us money and headaches.
Deploying shouldn't feel like a gamble. It should be a reflex. Here is how we shaved three minutes off our build pipeline.
For the longest time, our deployment pipeline felt like a slow-motion game of Tetris. Every time we pushed to production, we were staring at a terminal, watching a progress bar inch forward, praying nothing would timeout. It wasn't just annoying; it was killing our flow state.
We knew that fast deploys correlate directly with developer happiness. If you have to wait 5 minutes to see if your latest change broke the login flow, you're less likely to make changes. You become risk-averse. You stop shipping.
So, we decided to fix it. We didn't just want to make it faster; we wanted to make it instant. Here is the technical journey of how we reduced our average deployment time from 3 minutes 12 seconds to 45 seconds.
Our original workflow was a classic "SSH into server, pull code, build, restart" loop. It worked, but it was inefficient.
The result? A 3-minute 12-second deployment cycle that felt like an eternity. We needed a strategy that leveraged modern container capabilities.
We switched to multi-stage builds to separate the build environment from the runtime environment. This drastically reduced the final image size and eliminated the need to install build tools on the production server.
# Old way: Single stage FROM node:18-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build # New way: Multi-stage FROM node:18-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . FROM node:18-alpine AS runner WORKDIR /app COPY --from=builder /app/dist ./dist CMD ["node", "dist/index.js"]
For our backend services written in Go, we stopped shipping source code. We switched to compiling static binaries. This removed the need for a runtime environment entirely on the server.
# Before: Copying source COPY . . RUN go build -o server # After: Static binary RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o server .
We measured the average deployment time over 50 consecutive runs.
Full image rebuild + network transfer
Binary copy + instant start
Getting from 3 minutes to 45 seconds wasn't magic; it was a series of small, deliberate engineering decisions. We stopped treating the server as a general-purpose computer and started treating it as a specialized execution environment.
The impact on our team has been immediate. We deploy multiple times a day now. We iterate faster. We break things less often because we can fix them instantly. If you're stuck in a slow deployment loop, I highly recommend looking at your Dockerfile and your build pipeline. You might be surprised at what you find.
What's next? We're currently experimenting with GitOps and Kubernetes to push that number even lower. Stay tuned.
For our new SaaS, we ditched PostgreSQL for SQLite. Here is why it saved us money and headaches.
A step-by-step guide to creating a public status page using Statusly's built-in tools.
How to deploy your static site to the edge without breaking the bank.
Join 12,000+ indie developers getting our weekly newsletter. No spam, just code.