How to Reduce Your SaaS Bill with Self-Hosted Alternatives
What You’ll Need
- n8n Cloud or self-hosted n8n for workflow automation
- Hetzner VPS or Contabo VPS for hosting your self-hosted stack
- Namecheap if you need a custom domain for your applications
- DigitalOcean as an alternative hosting option
- Basic familiarity with Docker and command-line interfaces
- Around 30 minutes to set up your first stack
Table of Contents
- The Real Cost of SaaS Bloat
- Where Self-Hosted Wins
- Building Your First Self-Hosted Stack
- Migration Strategy: Moving Off Expensive Tools
- Security and Maintenance
- Getting Started
The Real Cost of SaaS Bloat
I used to have 14 active SaaS subscriptions. Slack at $8/user, GitHub at $4/user, Zapier for automation, Make for backup, text-to-speech services, image processing tools, video editing APIs—the list went on. At the end of every month, I’d watch roughly $2,400 disappear from my company’s account.
The problem isn’t that these tools are bad. They’re excellent. But when you’re running a small team or bootstrapped startup, that money could be reinvested in actual product development or hiring. I decided to audit which tools were actually worth their cost and which ones I could replace.
Here’s what I discovered: about 70% of what I was paying for could be handled by self-hosted open-source alternatives running on a $10-30/month VPS. The remaining 30% were genuinely specialized services worth keeping (like Stripe for payments—there’s no good self-hosted alternative).
This shift didn’t happen overnight, but in 12 months, I cut my SaaS bill from $2,400 to under $400 monthly. More importantly, I gained complete control over my data and workflows.
Where Self-Hosted Wins
Not every SaaS should be replaced. But certain categories are ripe for disruption:
Workflow Automation: Tools like Zapier charge based on tasks or users. When you move to self-hosted n8n , you pay once for the server and can create unlimited workflows. If you’re trying to decide between cloud and self-hosted, our detailed comparison of self-hosted n8n vs n8n Cloud breaks down exactly when each makes sense.
Media Processing: APIs for text-to-speech, video transcoding, and image manipulation are absurdly expensive at scale. I replaced multiple services with Edge TTS, which is completely free and requires no API keys . For video work, ffmpeg is a beast —command-line based but incredibly powerful once you learn the syntax.
Internal Tools: Databases, documentation systems, project management dashboards—these don’t need the polish of SaaS alternatives when you’re the only one using them.
Data Processing: ETL pipelines, data warehousing, and analytics. Self-hosted solutions let you avoid per-query or per-gigabyte pricing.
Email Infrastructure: Postfix + Dovecot are ancient but rock-solid for managing your own mail server, though this one requires the most operational attention.
Building Your First Self-Hosted Stack
Let me walk you through setting up a practical stack that handles workflow automation, text-to-speech, and basic media processing on a single VPS.
Step 1: Choose and Configure Your VPS
I recommend Hetzner VPS for cost-effectiveness or Contabo VPS if you want more storage. For most workflows, a 4-core/8GB RAM instance is sufficient. Here’s what I deploy:
#!/bin/bash
# Run this as root after SSH into your fresh VPS
# Update system packages
apt update && apt upgrade -y
# Install Docker
apt install -y apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"
apt install -y docker-ce docker-ce-cli containerd.io
# Install Docker Compose
curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
# Create app directory
mkdir -p /opt/selfhosted
cd /opt/selfhosted
# Install Nginx as reverse proxy
apt install -y nginx
# Create Nginx config directory
mkdir -p /etc/nginx/sites-available
Step 2: Deploy n8n for Automation
n8n
is where the magic happens. Create a docker-compose.yml:
version: '3.8'
services:
n8n:
image: n8nio/n8n:latest
container_name: n8n
environment:
- N8N_HOST=workflow.yourdomain.com
- N8N_PORT=5678
- N8N_PROTOCOL=https
- NODE_ENV=production
- GENERIC_TIMEZONE=UTC
- DB_TYPE=postgres
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=your_secure_password_here
- N8N_SECURE_COOKIE=true
ports:
- "5678:5678"
volumes:
- n8n_data:/home/node/.n8n
depends_on:
- postgres
networks:
- n8n_network
restart: unless-stopped
postgres:
image: postgres:15-alpine
container_name: n8n_postgres
environment:
- POSTGRES_USER=n8n
- POSTGRES_PASSWORD=your_secure_password_here
- POSTGRES_DB=n8n
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- n8n_network
restart: unless-stopped
volumes:
n8n_data:
postgres_data:
networks:
n8n_network:
driver: bridge
Start the stack:
cd /opt/selfhosted
docker-compose up -d
💡 Fast-Track Your Project: Don’t want to configure this yourself? I build custom n8n pipelines and bots. Message me with code SYS3-HUGO.
Step 3: Add Text-to-Speech and Media Processing
Create a separate service for media utilities. Since we’re handling text-to-speech, here’s a simple Express app that wraps Edge TTS:
cd /opt/selfhosted
mkdir -p tts-service
cd tts-service
Create package.json:
{
"name": "tts-service",
"version": "1.0.0",
"description": "Self-hosted TTS and media service",
"main": "server.js",
"dependencies": {
"express": "^4.18.2",
"edge-tts": "^0.3.0",
"fluent-ffmpeg": "^2.1.2",
"multer": "^1.4.5-lts.1",
"dotenv": "^16.3.1"
},
"scripts": {
"start": "node server.js"
}
}
Create server.js:
const express = require('express');
const { execFile } = require('child_process');
const path = require('path');
const fs = require('fs');
const app = express();
const PORT = 3000;
app.use(express.json());
// TTS endpoint
app.post('/tts', async (req, res) => {
const { text, voice, outputFormat } = req.body;
if (!text) {
return res.status(400).json({ error: 'Text is required' });
}
const voiceChoice = voice || 'en-US-AriaNeural';
const format = outputFormat || 'mp3';
const outputFile = path.join('/tmp', `tts_${Date.now()}.${format}`);
try {
execFile('edge-tts', [
'--text', text,
'--voice', voiceChoice,
'--write-media', outputFile
], (error, stdout, stderr) => {
if (error) {
console.error('TTS Error:', error);
return res.status(500).json({ error: 'TTS generation failed' });
}
res.download(outputFile, `output.${format}`, (err) => {
if (err) console.error('Download error:', err);
fs.unlink(outputFile, (unlinkErr) => {
if (unlinkErr) console.error('Cleanup error:', unlinkErr);
});
});
});
} catch (err) {
console.error('Error:', err);
res.status(500).json({ error: 'Server error' });
}
});
// Health check
app.get('/health', (req, res) => {
res.json({ status: 'healthy' });
});
app.listen(PORT, () => {
console.log(`TTS Service running on port ${PORT}`);
});
Create a Dockerfile:
FROM node:18-alpine
RUN apk add --no-cache \
python3 \
ffmpeg \
curl \
git
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
RUN pip install edge-tts
COPY server.js .
EXPOSE 3000
CMD ["npm", "start"]
Add this service to your docker-compose.yml:
tts-service:
build: ./tts-service
container_name: tts_service
ports:
- "3000:3000"
networks:
- n8n_network
restart: unless-stopped
environment:
- NODE_ENV=production
Rebuild and restart:
docker-compose up -d --build
Step 4: Set Up Nginx Reverse Proxy
Create /etc/nginx/sites-available/selfhosted.conf:
upstream n8n {
server localhost:5678;
}
upstream tts {
server localhost:3000;
}
server {
listen 80;
server_name workflow.yourdomain.com tts.yourdomain.com;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
server_name workflow.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/workflow.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/workflow.yourdomain.com/privkey.pem;
ssl_protocols TLSv1.2 T
Want to automate this yourself?
Start with n8n Cloud (free tier available) or self-host on a Hetzner VPS for full control.
📬 Get Weekly Automation Tips
One email per week with tutorials, tools, and workflows. No spam, unsubscribe anytime.