Pakistani software houses, IT export agencies, digital marketing consultancies, and commercial real estate brokerages face an ongoing operational challenge: scaling customer acquisition and account management without bleeding foreign exchange reserves on multi-tenant US SaaS platforms. For years, platforms like Salesforce, HubSpot, and Pipedrive have served as industry defaults. However, their aggressive per-seat pricing models—often starting at $50 to $150 per user per month for functional automation and reporting tiers—create an unsustainable financial drain on Pakistani businesses operating under currency exchange restrictions and regulatory scrutiny.
Self-hosting Twenty CRM on a high-speed Linux KVM VPS provides Pakistani sales teams and IT exporters with an enterprise-grade, modern open-source customer relationship management platform. Twenty CRM delivers an intuitive spreadsheet-style interface, customizable Kanban deal boards, real-time bi-directional email tracking, extensible custom objects, and fully open GraphQL and REST APIs. Most importantly, self-hosting eliminates perpetual US-dollar software liabilities and ensures complete data sovereignty over proprietary client records, deal valuations, and communication histories.
This architectural runbook details the macroeconomic justification for ditching US-dollar SaaS subscriptions, breaks down the internal architecture of Twenty CRM, and provides a production-grade deployment guide on Ubuntu Linux, complete with Docker Compose, Nginx reverse proxying, corporate SMTP/IMAP integration, PostgreSQL 16 tuning, and automated off-site disaster recovery.
Macroeconomic Reality: Why US-Dollar CRM Subscriptions Drain Pakistani Agencies
Operating an agency or B2B sales floor in Karachi, Lahore, Islamabad, or Faisalabad requires careful control of foreign currency expenditures. Multi-tenant US SaaS platforms penalize scaling firms through compounding per-user fees and local regulatory overhead.
+-----------------------------------------------------------------------------------------+
| ECONOMIC COMPARISON: US SAAS CRM VS. SELF-HOSTED TWENTY |
+-----------------------------------------------------------------------------------------+
| |
| PROPRIETARY US SAAS (HUBSPOT / SALESFORCE) SELF-HOSTED TWENTY CRM ON VPS |
| - $50 to $120 per user / month (USD) - Fixed PKR infrastructure cost |
| - 25 Sales Reps = $2,250 USD/mo (~630,000 PKR/mo) - Single KVM VPS (~8,000 PKR/mo) |
| - Plus 10% SBP / FBR advance withholding tax - Zero currency conversion risk |
| - Corporate card spending caps & transaction declines - Full data sovereignty |
| - Proprietary lock-in & export limitations - Direct PostgreSQL access |
| |
+-----------------------------------------------------------------------------------------+
1. The Compounding Trap of Per-Seat Licensing
Proprietary CRM platforms utilize per-user licensing tiers that punish business growth. Consider an expanding Pakistani software export agency or real estate firm with 25 active account executives, business development representatives (BDRs), and project managers:
- Base Subscription: 25 seats on HubSpot Sales Hub Professional ($90/seat/month) or Salesforce Enterprise ($165/seat/month) costs between $2,250 and $4,125 USD monthly.
- Rupee Conversion: At an exchange rate of 280 PKR per USD, this amounts to 700,000 to 1,155,000 PKR every month—an annual operational overhead exceeding 8.4 to 13.8 million PKR solely for customer record management.
- Rupee Depreciation Exposure: Any sudden devaluation of the Pakistani Rupee immediately inflates recurring SaaS overhead, squeezing operational profit margins without adding any new capability.
2. State Bank of Pakistan (SBP) Quotas and FBR Withholding Taxes
Transacting cross-border software subscriptions through Pakistani banking channels introduces persistent compliance friction:
- Corporate Card Limits: Commercial banks enforce strict central bank foreign currency caps on corporate debit and credit cards. Monthly automated renewals for large SaaS sums routinely fail credit checks or trip fraud scoring algorithms, locking sales teams out of active pipelines during critical negotiation cycles.
- FBR Advance Withholding Taxes: Cross-border digital software purchases trigger advance withholding taxes under Section 152 and Section 236Y of the Income Tax Ordinance. Active filers on the Federal Board of Revenue (FBR) Active Taxpayer List (ATL) face a 10% withholding tax surcharge, while non-filers face penalties up to 20%.
- Regulatory Remittance Friction: Processing formal banking remittances via Form A2 or direct SWIFT transfers requires audited vendor invoices, commercial tax residency certificates, and bank processing fees, adding bureaucratic drag to simple software access.
3. Pipeline Data Sovereignty and NDA Enforceability
Customer relationship systems house the most sensitive intellectual property an organization owns:
- Enterprise Client Contracts: Quoted hourly billing rates, project scope documents, and signed contract values.
- Proprietary Lead Contact Lists: Private direct-dial numbers, personal email addresses, and LinkedIn profiles of North American, European, and Gulf enterprise buyers.
- Confidential Communication Logs: Unencrypted email exchanges, meeting transcripts, and negotiation notes.
Hosting proprietary business development data within US multi-tenant clouds exposes Pakistani firms to unilateral account suspensions, jurisdiction-wide terms-of-service modifications, and complex compliance challenges under non-disclosure agreements (NDAs) that mandate strict data residency. Self-hosting on an isolated virtual private server guarantees that only your organization holds the encryption keys and database access credentials.
Architectural Breakdown: Twenty CRM Stack Components
Twenty CRM is not a monolithic legacy application. It is engineered from the ground up using modern web standards, modular micro-components, and scalable backend services.
+-----------------------------------------------------------------------------------------+
| TWENTY CRM ARCHITECTURE |
+-----------------------------------------------------------------------------------------+
| |
| [ Inbound Traffic: HTTPS / WSS via Port 443 ] |
| | |
| v |
| +---------------------------------------------+ |
| | Nginx Reverse Proxy & SSL Term | |
| +---------------------------------------------+ |
| | |
| v |
| +---------------------------------------------+ |
| | Twenty Server (Port 3000) | |
| | - NestJS REST & GraphQL APIs | |
| | - React / Next.js Single Page Interface | |
| +---------------------------------------------+ |
| | | |
| v v |
| +-------------------+ +-------------------+ |
| | Twenty Worker | | Redis 7 | |
| | - BullMQ Jobs |<--->| - Cache Layer | |
| | - Email Sync | | - Queue Storage | |
| +-------------------+ +-------------------+ |
| | |
| v |
| +---------------------------------------------+ |
| | PostgreSQL 16 Engine | |
| | - Relational Core & Metadata Engine | |
| | - Custom Field Schemas & pgvector | |
| +---------------------------------------------+ |
| |
+-----------------------------------------------------------------------------------------+
1. NestJS & TypeScript Core Backend
The backend engine is constructed with NestJS, an enterprise-grade TypeScript framework running on Node.js. It delivers:
- Unified GraphQL and REST APIs: Enables rapid querying of complex relational entities (Companies, People, Opportunities, Tasks) with minimal network payloads.
- Dynamic Schema Engine: Allows sales administrators to create custom fields and custom objects on the fly without running manual database migrations. Twenty translates custom object definitions into underlying PostgreSQL structures automatically.
- WebSocket Gateway: Pushes real-time collaborative updates to all active browser sessions, ensuring that when an account rep moves a deal across the Kanban board, other reps see the update instantly without page reloads.
2. React & Next.js Frontend
Twenty provides a modern, responsive user experience inspired by tools like Notion and Airtable:
- Virtual Scrolling Tables: Efficiently renders tens of thousands of customer records and interaction logs without browser lag.
- Configurable Views: Allows users to toggle between Kanban boards, spreadsheet tables, calendar timelines, and detail cards.
- Keyboard-First Navigation: Features universal command palettes (
Ctrl+K/Cmd+K) for rapid navigation and record creation.
3. Worker Node and BullMQ Task Orchestration
Background jobs, such as bi-directional email polling via IMAP, transactional notification dispatches, and third-party webhook processing, are decoupled from the main HTTP server process. Twenty runs a dedicated worker service powered by BullMQ on Redis 7, ensuring heavy processing tasks never block API responsiveness.
4. PostgreSQL 16 Database
All customer metadata, user accounts, audit trails, and custom entity relations reside within a dedicated PostgreSQL 16 instance. Twenty leverages PostgreSQL features including JSONB querying, transactional integrity, relational foreign key constraints, and full-text indexing for cross-record searches.
Infrastructure Sizing: Choosing the Right VPS Specification
Before deploying, size your virtual private server based on your team’s concurrent usage, database size, and email synchronization volume.
| Operational Tier | Team Size | Active Records | Minimum vCPUs | Dedicated RAM | NVMe SSD Storage | Recommended Plan |
|---|---|---|---|---|---|---|
| Startup / Agency | 1 – 10 Reps | Up to 25,000 | 2 vCPUs | 4 GB | 60 GB NVMe | Nextgen KVM Standard |
| Growth B2B Studio | 10 – 35 Reps | 25,000 – 100,000 | 4 vCPUs | 8 GB | 120 GB NVMe | Nextgen KVM Pro |
| Enterprise Exporter | 35 – 75 Reps | 100,000 – 500,000 | 8 vCPUs | 16 GB | 250 GB NVMe | Nextgen KVM Enterprise |
Production Deployment on Ubuntu 24.04 / 22.04 LTS
Follow this battle-tested implementation procedure to deploy Twenty CRM in an isolated, secure production environment.
Step 1: System Baseline, Security Hardening, and Docker Installation
Connect to your freshly provisioned Ubuntu server via SSH and update the operating system packages:
# Update local package indices and upgrade packages
sudo apt update && sudo apt full-upgrade -y
# Install essential operational tools
sudo apt install -y curl wget git unzip htop ufw fail2ban ca-certificates gnupg lsb-release
# Configure the Uncomplicated Firewall (UFW)
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp comment 'SSH Administration'
sudo ufw allow 80/tcp comment 'HTTP Let’s Encrypt Verification'
sudo ufw allow 443/tcp comment 'HTTPS Secure Traffic'
sudo ufw enable
Next, install official Docker Engine and Docker Compose plugins:
# Add Docker official GPG key
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Set up the Docker repository
echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install Docker packages
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# Enable Docker daemon on boot
sudo systemctl enable --now docker
Create a dedicated non-root service user and working directory:
# Create service group and user
sudo useradd -m -s /bin/bash -G docker crmadmin
# Create application directory tree
sudo mkdir -p /opt/twenty-crm/{data,storage,postgres_data,redis_data}
sudo chown -R crmadmin:crmadmin /opt/twenty-crm
Step 2: Cryptographic Secrets and Environment Configuration
Switch to the crmadmin user and navigate to /opt/twenty-crm:
sudo su - crmadmin
cd /opt/twenty-crm
Generate high-entropy cryptographic strings using openssl:
# Generate 32-byte hexadecimal secrets
DB_PASS=$(openssl rand -hex 24)
ENCRYPT_KEY=$(openssl rand -base64 32)
APP_SECRET=$(openssl rand -base64 32)
REDIS_PASS=$(openssl rand -hex 24)
Create the .env production configuration file:
cat <<EOF > /opt/twenty-crm/.env
# ==============================================================================
# TWENTY CRM PRODUCTION CONFIGURATION
# ==============================================================================
TAG=latest
PORT=3000
SERVER_URL=https://crm.yourdomain.pk
# Database Configuration
PG_DATABASE_HOST=twenty-postgres
PG_DATABASE_PORT=5432
PG_DATABASE_NAME=twenty
PG_DATABASE_USER=twenty
PG_DATABASE_PASSWORD=${DB_PASS}
PG_DATABASE_URL=postgres://twenty:${DB_PASS}@twenty-postgres:5432/twenty
# Redis Cache and Queue Configuration
REDIS_URL=redis://:${REDIS_PASS}@twenty-redis:6379
REDIS_CACHE_PREFIX=twenty_cache:
# Application Security & Token Encryption
ENCRYPTION_KEY=${ENCRYPT_KEY}
APP_SECRET=${APP_SECRET}
SIGN_IN_PREFILLED=false
# Local Storage Driver Configuration
STORAGE_TYPE=local
STORAGE_LOCAL_PATH=/app/packages/twenty-server/.local-storage
# Operational Flags
DISABLE_DB_MIGRATIONS=false
DISABLE_CRON_JOBS_REGISTRATION=false
EOF
# Lock down file permissions
chmod 600 /opt/twenty-crm/.env
Step 3: Production Docker Compose Specification
Create the docker-compose.yml file defining the core server, background queue worker, PostgreSQL 16 database, and Redis cache:
cat <<'EOF' > /opt/twenty-crm/docker-compose.yml
name: twenty
services:
twenty-server:
image: twentycrm/twenty:${TAG:-latest}
container_name: twenty-server
restart: always
depends_on:
twenty-postgres:
condition: service_healthy
twenty-redis:
condition: service_healthy
env_file:
- .env
volumes:
- ./storage:/app/packages/twenty-server/.local-storage
ports:
- "127.0.0.1:3000:3000"
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:3000/healthz || exit 1"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
networks:
- twenty-network
twenty-worker:
image: twentycrm/twenty:${TAG:-latest}
container_name: twenty-worker
restart: always
command: ["yarn", "worker:prod"]
depends_on:
twenty-postgres:
condition: service_healthy
twenty-redis:
condition: service_healthy
env_file:
- .env
volumes:
- ./storage:/app/packages/twenty-server/.local-storage
networks:
- twenty-network
twenty-postgres:
image: postgres:16-alpine
container_name: twenty-postgres
restart: always
environment:
POSTGRES_DB: ${PG_DATABASE_NAME}
POSTGRES_USER: ${PG_DATABASE_USER}
POSTGRES_PASSWORD: ${PG_DATABASE_PASSWORD}
volumes:
- ./postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${PG_DATABASE_USER} -d ${PG_DATABASE_NAME}"]
interval: 10s
timeout: 5s
retries: 5
networks:
- twenty-network
twenty-redis:
image: redis:7-alpine
container_name: twenty-redis
restart: always
command: ["redis-server", "--requirepass", "${REDIS_PASS}"]
volumes:
- ./redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "-a", "${REDIS_PASS}", "ping"]
interval: 10s
timeout: 5s
retries: 5
networks:
- twenty-network
networks:
twenty-network:
driver: bridge
EOF
Launch the stack to run database migrations and initialize tables:
docker compose up -d
Monitor container boot stages and log output:
docker compose logs -f twenty-server
Nginx Reverse Proxy, Let’s Encrypt SSL, and WebSocket Configuration
Twenty CRM relies on WebSockets for live data synchronization across active deal boards. The Nginx reverse proxy must be configured to support HTTP/1.1 protocol upgrades, long-lived connections, and large document attachments (such as PDF proposals and client contracts).
Exit back to your root user with exit. Install Nginx and Certbot:
sudo apt install -y nginx certbot python3-certbot-nginx
Create an optimized Nginx server block at /etc/nginx/sites-available/crm.yourdomain.pk:
# Map connection upgrade headers for reliable WebSockets
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
listen [::]:80;
server_name crm.yourdomain.pk;
# Let's Encrypt validation endpoint
location /.well-known/acme-challenge/ {
root /var/www/html;
}
# Redirect all plain HTTP traffic to secure HTTPS
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name crm.yourdomain.pk;
# SSL Certificate Paths (Provisioned via Certbot)
ssl_certificate /etc/letsencrypt/live/crm.yourdomain.pk/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/crm.yourdomain.pk/privkey.pem;
# Modern TLS Security Parameters
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
# HSTS & Security Headers
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# File Upload Limits (Proposals, Pitch Decks, Contracts)
client_max_body_size 50M;
# Gzip Compression for Fast Data Tables
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
# WebSocket support
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# Standard Proxy Headers
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
# Timeouts for Long-Polling and Large Imports
proxy_connect_timeout 90s;
proxy_send_timeout 90s;
proxy_read_timeout 90s;
proxy_buffering off;
}
}
Enable the configuration and provision the SSL certificate:
# Symlink to sites-enabled
sudo ln -s /etc/nginx/sites-available/crm.yourdomain.pk /etc/nginx/sites-enabled/
# Test Nginx syntax
sudo nginx -t
# Issue SSL certificate via Certbot standalone or webroot
sudo certbot --nginx -d crm.yourdomain.pk --non-interactive --agree-tos -m [email protected]
# Reload Nginx service
sudo systemctl reload nginx
Email Synchronization & Messaging Integrations
A CRM provides little value without reliable email and message integration. For Pakistani teams, configuring corporate SMTP relays and bi-directional IMAP synchronization keeps all client correspondence tied to company records.
+-----------------------------------------------------------------------------------------+
| EMAIL & MESSAGING INTEGRATION FLOW |
+-----------------------------------------------------------------------------------------+
| |
| [ Inbound Client Reply ] ---> Corporate cPanel/Exim IMAP ---> Twenty Background Sync |
| | |
| v |
| [ Outbound Deal Proposal ] <-- Twenty Worker SMTP Relay <--- Logged to Contact Record |
| |
| [ Inbound WhatsApp Lead ] ---> WhatsApp Business API Webhook ---> Twenty GraphQL API |
| |
+-----------------------------------------------------------------------------------------+
1. Corporate SMTP Relay via cPanel / Exim
To prevent proposal notifications, welcome emails, and password reset dispatches from being flagged as spam, route outbound mail through your corporate domain’s authenticated mail server. Add the following parameters to /opt/twenty-crm/.env:
# Outbound Transactional Mail Settings
EMAIL_FROM_ADDRESS="[email protected]"
EMAIL_FROM_NAME="Nextgen Sales Engineering"
EMAIL_SMTP_HOST="mail.yourdomain.pk"
EMAIL_SMTP_PORT=465
EMAIL_SMTP_USER="[email protected]"
EMAIL_SMTP_PASSWORD="YourSecureEmailPassword"
EMAIL_SMTP_SECURE=true
Ensure your corporate domain’s DNS zone contains valid SPF, DKIM, and DMARC TXT records:
# SPF Record
v=spf1 mx a ip4:138.2.139.91 ~all
# DMARC Record
v=DMARC1; p=quarantine; pct=100; rua=mailto:[email protected]
2. Bi-Directional IMAP Email Tracking
Twenty CRM features automated background mailbox synchronization. When sales reps link their Google Workspace, Microsoft 365, or local cPanel IMAP accounts:
- Inbound client responses automatically attach to corresponding Contact and Deal timelines.
- Worker threads poll connected mailboxes every few minutes without freezing browser sessions.
- Sales leadership gains total visibility into client deal communications without asking reps to forward emails manually.
3. WhatsApp Business Cloud API Integration
In Pakistan, WhatsApp is the primary channel for qualifying real estate leads, software project inquiries, and B2B vendor consultations.
You can connect WhatsApp Business Cloud API webhooks directly to Twenty CRM’s GraphQL API using automation platforms like self-hosted n8n:
- Capture inbound WhatsApp messages via Meta Developer Webhooks.
- Search Twenty CRM for the sender’s phone number using the GraphQL endpoint:
query SearchPersonByPhone($phone: String!) { people(filter: { phone: { eq: $phone } }) { edges { node { id name company { id name } } } } } - If no matching record is found, trigger a mutation to create a new Lead record, assign it to an available sales rep, and send an automated response back through WhatsApp.
Database Tuning & High-Availability Optimization
Default PostgreSQL configurations are designed to run on systems with minimal RAM. On a dedicated production VPS, tune PostgreSQL 16 parameters to take full advantage of available CPU cores and NVMe caching.
Sizing PostgreSQL 16 for Twenty CRM
Connect to your database container or create a custom postgresql.conf configuration mount:
# /opt/twenty-crm/postgresql.conf
# Tuned for an 8 GB RAM / 4 vCPU Virtual Node
# Memory Allocation
shared_buffers = 2GB # 25% of total system RAM
effective_cache_size = 6GB # 75% of total system RAM
work_mem = 32MB # For complex pipeline aggregations
maintenance_work_mem = 512MB # Accelerates index rebuilds
# Checkpoint and Write-Ahead Logging
wal_buffers = 16MB
min_wal_size = 1GB
max_wal_size = 4GB
checkpoint_completion_target = 0.9
# Worker Threads & Concurrency
max_worker_processes = 4
max_parallel_workers_per_gather = 2
max_parallel_workers = 4
max_connections = 100
# SSD Storage Optimization
random_page_cost = 1.1 # Fast NVMe random lookups
effective_io_concurrency = 200
Mount this file into your docker-compose.yml under the twenty-postgres service:
volumes:
- ./postgres_data:/var/lib/postgresql/data
- ./postgresql.conf:/etc/postgresql/postgresql.conf
command: ["postgres", "-c", "config_file=/etc/postgresql/postgresql.conf"]
Restart the database container to apply the optimized memory profile:
docker compose restart twenty-postgres
Automated Backups and Off-Site Disaster Recovery Runbook
A customer relationship database holds irreplaceable pipeline data. Relying exclusively on local storage leaves your business vulnerable to disk corruption or accidental deletion.
+-----------------------------------------------------------------------------------------+
| AUTOMATED DISASTER RECOVERY PIPELINE |
+-----------------------------------------------------------------------------------------+
| |
| [ Daily Cron Trigger: 02:00 PKT ] |
| | |
| v |
| [ Non-Blocking pg_dump ] ===> Gzip Archive ===> Local /opt/twenty-crm/backups |
| | |
| v |
| [ Rclone Cloud Sync Engine ] |
| | |
| v |
| [ Cloudflare R2 / S3 Bucket ] |
| |
+-----------------------------------------------------------------------------------------+
1. Non-Blocking Database Snapshot Script
Create a production backup script at /opt/twenty-crm/scripts/backup.sh:
#!/usr/bin/env bash
set -eo pipefail
BACKUP_DIR="/opt/twenty-crm/backups"
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
FILENAME="twenty_db_backup_${TIMESTAMP}.sql.gz"
RETENTION_DAYS=14
mkdir -p "${BACKUP_DIR}"
echo "[*] Initializing non-blocking database dump for Twenty CRM..."
docker exec twenty-postgres pg_dump -U twenty -d twenty | gzip -9 > "${BACKUP_DIR}/${FILENAME}"
echo "[*] Creating archive of local file storage assets..."
tar -czf "${BACKUP_DIR}/twenty_storage_${TIMESTAMP}.tar.gz" -C /opt/twenty-crm storage
echo "[*] Purging local snapshots older than ${RETENTION_DAYS} days..."
find "${BACKUP_DIR}" -type f -name "*.gz" -mtime +${RETENTION_DAYS} -delete
# Off-site replication via rclone
if command -v rclone &> /dev/null; then
echo "[*] Uploading snapshot to off-site cloud storage..."
rclone copy "${BACKUP_DIR}/${FILENAME}" remote-r2:nextgen-crm-backups/database/
rclone copy "${BACKUP_DIR}/twenty_storage_${TIMESTAMP}.tar.gz" remote-r2:nextgen-crm-backups/storage/
fi
echo "[+] Twenty CRM backup routine completed successfully at $(date)"
Make the script executable:
chmod +x /opt/twenty-crm/scripts/backup.sh
2. Automated Daily Cron Job
Configure root’s crontab to run the backup routine every night at 02:00 PKT:
# Open crontab editor
sudo crontab -e
# Append the following schedule line:
0 2 * * * /opt/twenty-crm/scripts/backup.sh >> /var/log/twenty-backup.log 2>&1
Infrastructure Scaling Boundaries: VPS vs. Dedicated Bare-Metal
As your software house, agency, or sales force scales past initial operational milestones, your infrastructure demands will evolve:
+-----------------------------------------------------------------------------------------+
| INFRASTRUCTURE SCALING PATHWAY |
+-----------------------------------------------------------------------------------------+
| |
| TIER 1: High-Performance Linux KVM VPS |
| - Specs: 2 to 8 vCPUs | 4 to 16 GB RAM | Enterprise NVMe Storage |
| - Capacity: Up to 50 sales agents | 250,000 records | Standard IMAP polling |
| - Target: Software houses, digital agencies, regional brokerages, B2B exporters |
| |
| | |
| v |
| |
| TIER 2: Bare-Metal Dedicated Servers |
| - Specs: AMD EPYC / Intel Xeon | 64 to 256 GB ECC RAM | NVMe Hardware RAID |
| - Capacity: 50+ to 500+ agents | 1M+ customer records | High-frequency webhooks |
| - Target: Enterprise BPOs, multi-brand holding groups, high-volume call centers |
| |
+-----------------------------------------------------------------------------------------+
The Limits of Virtualized Environments
While high-performance KVM VPS nodes handle standard sales floors effortlessly, high-volume organizations face distinct scaling hurdles:
- Massive IMAP Syncing: When 75+ active sales reps synchronize hundreds of thousands of historical client emails simultaneously, background worker processes generate continuous I/O and memory pressure.
- High-Frequency Inbound Webhooks: E-commerce stores and high-volume digital ad campaigns streaming thousands of incoming leads per hour can cause hypervisor CPU contention and I/O wait latency.
- Complex Analytical Aggregations: Running real-time revenue forecasts, custom pipeline conversions, and multi-variable cohort reports across millions of rows strains virtualized memory channels.
When your sales operations outgrow virtualized boundaries, upgrading to bare-metal Dedicated Servers provides dedicated physical CPU cores, direct memory bus access, and pure hardware RAID NVMe throughput with zero hypervisor overhead.
For Pakistani enterprises, fintech services, and nationwide distribution platforms subject to strict domestic regulatory oversight or demanding ultra-fast response times across Karachi, Lahore, and Islamabad, deploying Dedicated Servers in Pakistan ensures direct local peering via the Pakistan Internet Exchange (PKIX). This architecture delivers sub-10ms latency to domestic sales reps and guarantees absolute physical control over organizational data assets.
Production Verification and Audit Checklist
Before onboarding your sales reps, account executives, and management onto your new Twenty CRM platform, complete this operational audit:
- Storage Mount Isolation: Confirm that
./postgres_data,./redis_data, and./storagepersist on the host filesystem and remain intact across container restarts. - WebSocket Protocol Verification: Inspect browser developer network tools on the Kanban deal board to ensure connections establish with an
HTTP 101 Switching Protocolsstatus code. - Encrypted Variables Audit: Verify that
ENCRYPTION_KEYandAPP_SECRETin/opt/twenty-crm/.envare populated with 32-byte high-entropy values and the file permissions are set tochmod 600. - Port Security Audit: Run
sudo ufw statusandss -tulpnto confirm that ports3000,5432, and6379are bound strictly to127.0.0.1and unreachable from the public internet. - SMTP Handshake Test: Trigger an outbound test email to confirm that your corporate cPanel or Exim SMTP relay authenticates without TLS handshake failures.
- Automated Backup Verification: Execute
/opt/twenty-crm/scripts/backup.shmanually to confirm that database dumps and file archives generate cleanly and upload to off-site object storage.
By self-hosting Twenty CRM on modern Linux VPS infrastructure, Pakistani software houses and sales teams can eliminate foreign currency SaaS overhead, take control of proprietary pipeline data, and equip their teams with a responsive, modern sales platform built for sustainable growth.
Deploy Enterprise Twenty CRM on NextGen High-Performance Linux VPS
Eliminate expensive dollar-denominated CRM licenses, bypass international credit card quotas, and keep your customer data under sovereign control. Deploy Twenty CRM on high-speed NVMe KVM VPS in Pakistan with dedicated IPv4, automated snapshots, and 24/7 expert infrastructure engineering support.
