← Back to Blog

Self-Host PostgreSQL, MySQL, Redis and MongoDB on a Database VPS

Published · by RS Computers

PostgreSQL MySQL Redis MongoDB Databases

For most small and mid-sized projects, a database VPS beats a managed database. A database VPS is a virtual server whose main job is running PostgreSQL, MySQL, MariaDB, Redis or MongoDB. All its memory goes to your data, and nobody caps your connections by pricing tier. In exchange, the upkeep is yours: nobody else will patch it, watch its disk or schedule its database dumps.

Key points:

Self-hosted or managed database: who should run their own?

A managed database (DBaaS) is one where a provider runs the engine and you get a connection string, so installation and routine maintenance are off your hands. Testing restores stays your job either way, as an engineer who has run both managed and self-hosted clusters pointed out in a Hacker News thread on self-hosting Postgres, and a backup that will not restore is how data really gets lost. In 2017 GitLab.com lost about six hours of production data after an engineer deleted the primary database's files by mistake. Its postmortem also found that the daily pg_dump backups had been failing silently, because they ran PostgreSQL 9.2's pg_dump against a 9.6 database and the error emails were being rejected.

QuestionSelf-hosted on a VPSManaged database
ConnectionsYou set max_connections (PostgreSQL default: 100); PgBouncer, a connection pooler, serves more clients.Tied to RAM: DigitalOcean's managed PostgreSQL allows 22 at 1 GiB and 97 at 4 GiB.
Superuser and extensionsYours.Often no superuser; extensions from an approved list.
Upgrade timingYour call, within five years of support per PostgreSQL major version.The provider's calendar. Amazon RDS moves expired versions into paid Extended Support.
Data locationThe city you chose, on a server only you administer.The provider's region and jurisdiction.

Self-host if most of these are true:

Pay for managed if you need failover within seconds and nobody will run Patroni or repmgr, or if auditors expect a certified service. Managed does not automatically mean stronger guarantees, though. In 2025 Jepsen tested Amazon RDS for PostgreSQL Multi-AZ clusters and found isolation anomalies it had not seen in single-node PostgreSQL.

Which database for a VPS: PostgreSQL, MySQL, MariaDB, Redis or MongoDB?

PostgreSQL, unless your application says otherwise. It was the most used database in the 2025 Stack Overflow Developer Survey at 55.6%, ahead of MySQL (40.5%), Redis (28%), MongoDB (24%) and MariaDB (22.5%). Often the app has decided already: WordPress wants MySQL or MariaDB (our guide to hosting WordPress on a VPS covers that stack), while self-managed GitLab supports only PostgreSQL, plus Redis or Valkey.

MySQL or MariaDB in 2026?

They are no longer drop-in replacements: MariaDB stores JSON as text, and its replication GTIDs differ from MySQL's. On Debian 13 the easy choice is MariaDB 11.8 LTS, straight from the Debian archive and maintained until June 2028. MariaDB 12.3, the next LTS (May 2026, supported until June 2029), comes from MariaDB's own repository and switches innodb_snapshot_isolation on by default, so test transaction-heavy apps before you move. When the app needs real MySQL, take it from Oracle's repository: MySQL 9.7.0, released on 21 April 2026, is the first LTS series since 8.4 and brings several features that used to be Enterprise-only, replication and Group Replication metrics among them, to the free Community edition. 8.4 LTS stays supported, but start nothing new on 8.0: its support ended in April 2026.

Is Redis still open source? Redis vs Valkey

Yes, again. Redis is an in-memory key-value store, used mostly for caches, sessions and job queues. Redis 8 (May 2025) added the OSI-approved AGPLv3 as a licence option next to RSALv2 and SSPLv1, which had applied since Redis 7.4 in 2024. Valkey is the Linux Foundation's BSD-licensed fork of Redis 7.2.4, launched in March 2024. It speaks the same protocol, so client libraries work unchanged.

For a cache behind your own app, the licence does not matter; it bites if you resell Redis as a service. Debian 13 ships both, and Fedora 41 switched to Valkey. Valkey loads data files only from Redis 7.2 and older.

Is MongoDB free to self-host?

Yes. MongoDB is a document database that stores JSON-like records instead of table rows, and its Community Server uses the SSPL, whose conditions apply when you offer MongoDB itself as a service. The catches are technical: the CPU must support AVX, and on Debian 13 only MongoDB 9.0 has packages. The quick start below covers both.

Why NVMe matters: commit speed is flush speed

A PostgreSQL commit returns only after its WAL record (the write-ahead log every change goes to first) is flushed to stable storage. MySQL's redo log works the same way with its default settings, so for one session the drive's flush latency caps commits per second. A single MongoDB server is the exception: it acknowledges a write first and flushes its journal every 100 ms, unless the write asks for j: true. Tanel Poder measured this with pg_test_fsync: an enterprise Micron 7400 NVMe with power-loss protection did 42,004 synchronous writes per second, while a consumer Samsung 990 Pro, also NVMe, did 609. NVMe also lets a busy database work in parallel, with up to 65,535 queues of 65,536 commands against one queue of 32 on SATA's AHCI.

Measure your own disk instead of trusting adjectives, ours included. With PostgreSQL 18 installed (below), this runs its flush benchmark:

# as root
runuser -u postgres -- /usr/lib/postgresql/18/bin/pg_test_fsync -f /var/lib/postgresql/pgtestfsync.tmp

It takes under two minutes. The fdatasync line in the first group is roughly the most commits per second one session can make. If losing up to 600 ms of commits in a crash is acceptable (data is never corrupted), synchronous_commit = off lifts that ceiling.

How much RAM does a database VPS need?

Count in layers: the system, the database cache, connections, then everything else. Debian's installation guide asks for 512 MB of RAM at minimum and recommends 1 GB for a system without a desktop, so set aside roughly that much for the OS. The PostgreSQL documentation calls 25% of RAM a reasonable start for shared_buffers and says above 40% is unlikely to help, since PostgreSQL also uses the OS file cache. MySQL's innodb_dedicated_server rule gives InnoDB 50% of RAM on 1 to 4 GB machines and 75% above that. MongoDB's cache defaults to the larger of 50% of (RAM minus 1 GB) or 256 MB.

Connections cost extra. PostgreSQL's work_mem (4 MB by default) applies to each sort or hash step of a query, not to the connection, so one complex query can use several times that. Pooling connections through PgBouncer is cheaper than adding RAM. Redis and Valkey keep everything in memory and can briefly need twice their size while saving, so set maxmemory well below free RAM. Julia Evans once gave the PostgreSQL behind her Mess With DNS project a 256 MB machine, and the OOM killer stopped it almost every day. MongoDB's formula leaves 512 MB of cache on 2 GB, so treat 4 GB as its floor. Since version 9.0 it also stops any single query that needs more than 1 GB or 20% of RAM, whichever is larger, so a runaway aggregation fails with ExceededMemoryLimit instead of starving the server.

Which RS Computers plan suits your database?

RS Computers runs KVM virtual servers in Amsterdam, Prishtina and Dublin. The plans page has the same plans and prices in all three cities. Each server has its own kernel, so settings like vm.overcommit_memory are yours. Every plan has NVMe storage, unmetered traffic on a 1 Gb/s (VPS) or 10 Gb/s (VDS) port, its own IPv4 and IPv6, and free weekly backups restorable from the client area, where you can also upgrade. Choose a Linux distribution when ordering; Windows Server is available on VPS Mini and all VDS plans.

vCPUs are shared, so watch steal time (st in top), the share of time your vCPU waited for a physical CPU; if it climbs while queries slow down, add vCPUs or split app and database. The memory values below assume the database has the server to itself, except on VPS Micro, where the app shares it.

PlanSized for
VPS Nano (1 vCPU, 1 GB, 20 GB NVMe, 1 Gb/s)A Valkey cache (maxmemory 256 MB), or a small PostgreSQL or MariaDB for staging (shared_buffers 256 MB). A good spare for restore drills.
VPS Micro (2 vCPU, 2 GB, 40 GB NVMe, 1 Gb/s)An app plus its database: WordPress with MariaDB and Valkey, or Django on PostgreSQL (shared_buffers 512 MB). Not MongoDB.
VPS Mini (4 vCPU, 4 GB, 80 GB NVMe, 1 Gb/s)The smallest plan for MongoDB (1.5 GB cache), or a database server for several small apps (shared_buffers 1 GB, InnoDB 2 GB).
VDS Small (4 vCPU, 8 GB, 240 GB NVMe, 10 Gb/s)A production database alone: shared_buffers 2 GB, InnoDB 6 GB or MongoDB 3.5 GB, with disk for pgBackRest.
VDS Medium (8 vCPU, 16 GB, 480 GB NVMe, 10 Gb/s)PostgreSQL and Redis together for Mastodon or GitLab, or heavier databases: shared_buffers 4 GB, InnoDB 12 GB, MongoDB 7.5 GB.
VDS Large (16 vCPU, 32 GB, 960 GB NVMe, 10 Gb/s)Working sets that must stay in memory: shared_buffers 8 GB, InnoDB 24 GB, MongoDB 15.5 GB.

Set up a database VPS on Debian 13

Each block names the user that runs it. Log in as root (or type sudo -i); runuser -u postgres -- runs one command as the postgres system user. The names appuser and appdb are examples. If SSH and systemctl are still new to you, give our 30-day Linux practice plan a few evenings before you trust this server with real data.

Prepare the server

Update Debian and turn on the firewall, allowing SSH first so you cannot lock yourself out.

# as root
apt update && apt full-upgrade -y
apt install -y curl ca-certificates gnupg ufw
ufw allow 22/tcp
ufw --force enable
ufw status verbose

You should see Status: active and 22/tcp ALLOW IN Anywhere plus a (v6) line, and no database port. Ubuntu uses the same commands. Ubuntu 24.04 ships older engines (PostgreSQL 16, MariaDB 10.11, Redis 7.0), while Ubuntu 26.04 LTS has PostgreSQL 18, MariaDB 11.8 and Valkey 9.0; the MongoDB steps below are for Debian 13.

The firewall still leaves port 22 open, and whoever logs in as root over SSH can open every database on this server without a database password, since root reaches MariaDB through its Unix socket and PostgreSQL through runuser. Our Debian 13 image accepts root's password over SSH, and on a fresh test server we booted, the first password guess came less than six minutes after boot. Put your SSH key in place and set PasswordAuthentication no before any real data arrives; week 2 of the Linux lab guide walks through it.

PostgreSQL 18 from the official PGDG repository

Step 1. Debian 13 ships PostgreSQL 17, so this adds the project's own APT repository (PGDG) with its setup script and installs PostgreSQL 18.

# as root
apt install -y postgresql-common
/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y
apt install -y postgresql-18
pg_lsclusters

The script names the suite trixie-pgdg (noble-pgdg on Ubuntu), and pg_lsclusters shows 18, main, 5432, online. If it says 5433, Debian's PostgreSQL 17 already holds 5432; point your app at 5433.

Step 2. Next, an app role and its database; the last line logs in over TCP with the password, the way your app will.

# as root
runuser -u postgres -- createuser --pwprompt appuser
runuser -u postgres -- createdb -O appuser appdb
psql -h 127.0.0.1 -U appuser -d appdb -c 'SELECT current_user;'

You type the password three times (twice for the new role, once to log in) and get a one-row table showing appuser. If you see Peer authentication failed, you left out -h 127.0.0.1. Never "fix" it by setting pg_hba.conf to trust.

Step 3. Set shared_buffers from the plan table (1GB on VPS Mini) and log statements slower than 500 ms.

# as root
runuser -u postgres -- psql -c "ALTER SYSTEM SET shared_buffers = '1GB';" -c "ALTER SYSTEM SET log_min_duration_statement = '500ms';"
systemctl restart postgresql@18-main
runuser -u postgres -- psql -c 'SHOW shared_buffers;'

It prints 1GB. Slow statements now land in /var/log/postgresql/postgresql-18-main.log.

MariaDB 11.8 (or MySQL 9.7)

Step 1. MariaDB comes straight from Debian. Install it, then create a database and a user that can only connect locally.

# as root
apt install -y mariadb-server mariadb-backup
mariadb <<'SQL'
CREATE DATABASE appdb CHARACTER SET utf8mb4;
CREATE USER 'appuser'@'localhost' IDENTIFIED BY 'YOUR_APP_PASSWORD';
GRANT ALL PRIVILEGES ON appdb.* TO 'appuser'@'localhost';
SQL
mariadb -u appuser -p appdb -e 'SELECT DATABASE();'

The last line asks for YOUR_APP_PASSWORD and prints appdb. Debian's MariaDB is locked down from the start: root logs in only through the Unix socket, so it needs no password, and there are no anonymous users or test database. Skip the old mariadb-secure-installation script; on Debian 13 it says itself that running it is useless. If mariadb -u root -p from a normal user account gives ERROR 1698 (28000), that is expected: use sudo mariadb for admin work.

Step 2. Now size the buffer pool (2G on VPS Mini) and log queries slower than one second. Debian 13 does not create /var/log/mysql, so the first line makes it; without it MariaDB quietly turns the slow log off.

# as root
install -d -o mysql -g adm -m 2750 /var/log/mysql
cat > /etc/mysql/mariadb.conf.d/90-local.cnf <<'EOF'
[mysqld]
innodb_buffer_pool_size = 2G
slow_query_log = 1
log_slow_query_file = /var/log/mysql/mariadb-slow.log
log_slow_query_time = 1
EOF
systemctl restart mariadb
mariadb -e 'SELECT @@innodb_buffer_pool_size DIV 1048576 AS buffer_pool_mb;'

It prints 2048, and slow queries land in /var/log/mysql/mariadb-slow.log. If MariaDB fails to restart, or that file never appears, journalctl -u mariadb names the problem.

For MySQL, install Oracle's mysql-apt-config package, pick mysql-9.7-lts (or mysql-8.4-lts) and run apt install mysql-server; in our Debian 13 test that installed MySQL 9.7.2. It listens on all interfaces (ports 3306 and 33060), so add bind-address = 127.0.0.1 and mysqlx-bind-address = 127.0.0.1 to /etc/mysql/mysql.conf.d/mysqld.cnf and run systemctl restart mysql. If an app fails with ERROR 1524 (Plugin 'mysql_native_password' is not loaded), its account still uses the old password plugin, usually one carried over from 8.0: 8.4 switches that plugin off by default, and 9.x no longer has it. Switch it from sudo mysql with ALTER USER 'appuser'@'localhost' IDENTIFIED WITH caching_sha2_password BY 'YOUR_APP_PASSWORD'; and update any client library too old to speak that plugin.

Valkey (or Redis)

Step 1. Valkey needs memory overcommit for its background saves, so set that right after installing it, then generate a password.

# as root
apt install -y valkey-server
echo 'vm.overcommit_memory = 1' > /etc/sysctl.d/90-valkey.conf
sysctl --system
valkey-cli ping
valkey-cli ACL GENPASS

You get PONG and a 64-character string; copy it. If the log later shows WARNING Memory overcommit must be enabled!, run sysctl --system again and check the file name.

Step 2. Put that password (in place of YOUR_GENERATED_PASSWORD) and a memory cap at the end of the config file, then restart Valkey.

# as root
cat >> /etc/valkey/valkey.conf <<'EOF'
requirepass YOUR_GENERATED_PASSWORD
maxmemory 256mb
maxmemory-policy allkeys-lru
EOF
systemctl restart valkey-server
valkey-cli --askpass ping

It asks for the password and answers PONG; without it, Valkey says NOAUTH Authentication required. allkeys-lru suits a pure cache; for sessions or job queues keep the default, noeviction. For Redis, apt install redis-server gives 8.0.2; the same steps apply to /etc/redis/redis.conf and redis-cli. Upstream has moved on to Valkey 9.1 and Redis 8.8, both from May 2026, but Debian backports security fixes into the versions it ships (it patched Valkey in April 2026 and Redis in May), so plain apt upgrade keeps a cache safe.

MongoDB 9.0 Community on Debian 13

MongoDB 9.0, released at the end of September 2026, is the first version MongoDB builds for Debian 13; on Debian and Ubuntu, MongoDB's platform list offers 8.x only for Debian 12 and Ubuntu 20.04 to 24.04. So MongoDB now runs on the same Debian 13 server as the other engines. Stay on 8.0, which is supported until October 2029, only if your driver or app is not ready for 9.0, and then on Ubuntu 24.04. Before you upgrade an existing 8.0 database, read the 9.0 compatibility notes: queries that compare a dotted path through an array with null can now match different documents.

Step 1. First check for AVX; MongoDB 5.0 and later will not run without it.

# as root
grep -o -w avx /proc/cpuinfo | sort -u

It must print avx. If it prints nothing, stop: mongod would die with Illegal instruction.

Step 2. With AVX confirmed, add MongoDB's signed repository for Debian 13 (trixie); the block installs 9.0, starts it and pings it.

# as root
curl -fsSL https://pgp.mongodb.com/server-9.asc | gpg -o /usr/share/keyrings/mongodb-server-9.gpg --dearmor
echo "deb [ signed-by=/usr/share/keyrings/mongodb-server-9.gpg ] https://repo.mongodb.org/apt/debian trixie/mongodb-org/9.0 main" > /etc/apt/sources.list.d/mongodb-org-9.0.list
apt-get update
apt-get install -y mongodb-org
systemctl enable --now mongod
sleep 5
mongosh --quiet --eval 'db.runCommand({ ping: 1 })'

Expect { ok: 1 }; in our test the packages were mongodb-org 9.0.2 and mongosh 2.13.0, a 226 MB download. The sleep gives mongod the second or two it needs before it accepts connections. If systemctl says Unit mongod.service not found, run systemctl daemon-reload and repeat that line. If mongosh still reports ECONNREFUSED, wait a few more seconds and run it again.

Step 3. MongoDB starts with authentication off. Create an admin user, then switch it on.

# as root
mongosh admin --quiet --eval 'db.createUser({ user: "admin", pwd: "YOUR_ADMIN_PASSWORD", roles: [ "userAdminAnyDatabase", "readWriteAnyDatabase" ] })'
printf 'security:\n  authorization: enabled\n' >> /etc/mongod.conf
systemctl restart mongod
mongosh -u admin -p --authenticationDatabase admin --quiet --eval 'db.runCommand({ ping: 1 })'

The last line asks for the password and prints { ok: 1 }.

Is it safe to expose port 5432? Secure remote access

No. As installed above, every engine listens only on the server itself, except Oracle's MySQL. Databases reach the internet when someone sets listen_addresses = '*' plus ufw allow 5432 for a desktop client, or runs docker run -p 5432:5432, which bypasses ufw (publish to 127.0.0.1:5432:5432; our guide to Docker on a VPS explains that trap). Scanners look for exactly these ports. In 2022 Shadowserver counted 3.6 million MySQL servers answering on port 3306, and MongoBleed (CVE-2025-14847), an unauthenticated memory leak fixed in MongoDB 8.0.17 and 8.2.3, was exploited in the wild and added to CISA's Known Exploited Vulnerabilities catalog on 29 December 2025.

For your own client, use an SSH tunnel. The command below forwards port 15432 on your computer to PostgreSQL on the server and stays in the foreground until you press Ctrl+C:

# as the local user on your own computer (not on the server)
ssh -N -L 15432:127.0.0.1:5432 YOUR_SSH_USER@SERVER_IP

It prints nothing while it runs. Point pgAdmin or DBeaver at 127.0.0.1, port 15432; the same works for 3306, 6379 and 27017.

An app on another server needs more: the port open to that server's IP alone, TLS required through a hostssl rule, and PostgreSQL listening on its public address (a restart, not a reload):

# as root
ufw allow from APP_SERVER_IP to any port 5432 proto tcp
echo 'hostssl appdb appuser APP_SERVER_IP/32 scram-sha-256' >> /etc/postgresql/18/main/pg_hba.conf
runuser -u postgres -- psql -c "ALTER SYSTEM SET listen_addresses = 'localhost,SERVER_IP';"
systemctl restart postgresql@18-main
ss -tlnp | grep 5432

ss shows PostgreSQL on 127.0.0.1, [::1] and SERVER_IP. The app connects with sslmode=require (Debian's self-signed certificate encrypts but cannot be verified). If you see no pg_hba.conf entry for host, the client IP or its TLS setting does not match the rule. If a Redis client gets -DENIED Redis is running in protected mode, use the tunnel, never protected-mode no. The app itself belongs behind a reverse proxy with HTTPS; see our Caddy, Nginx and Traefik guide.

Database backups: dumps, WAL archiving and the restore test

The free weekly backup restores the whole server, which is right when the server itself is lost. For a database it falls short, because it is one copy of the whole machine per week. If a shop's database breaks five days after the last backup, restoring brings the server back as it was then, without five days of orders.

BackupRestoresYou can lose
Weekly server backupThe whole VPS, from the client areaUp to a week
Nightly pg_dump or mariadb-dumpOne database, even into a newer versionUp to a day
pgBackRest with WAL archivingPostgreSQL at any chosen momentAbout a minute
Hourly copy of the Redis RDB fileThe whole datasetUp to an hour

Nightly pg_dump, then a restore

The block below dumps appdb and the roles (pg_dump skips them) every night, keeps 14 days and takes a first dump right away. The first line makes sure cron is there; minimal Debian images leave it out, and then the schedule silently never runs.

# as root
apt install -y cron
install -d -o postgres -g postgres -m 700 /var/backups/pg
cat > /etc/cron.d/pg-backup <<'EOF'
15 3 * * * postgres pg_dump -Fc appdb > /var/backups/pg/appdb-$(date +\%F).dump
20 3 * * * postgres pg_dumpall --globals-only > /var/backups/pg/globals-$(date +\%F).sql
40 3 * * * postgres find /var/backups/pg -type f -mtime +14 -delete
EOF
runuser -u postgres -- pg_dump -Fc appdb > /var/backups/pg/appdb-test.dump
ls -lh /var/backups/pg

ls lists appdb-test.dump with a non-zero size. In cron, a percent sign must be written \%; without the backslash the job silently does nothing. Now the step GitLab never reached: restore the dump into a scratch database and list its tables.

# as root
runuser -u postgres -- createdb -T template0 appdb_restoretest
runuser -u postgres -- pg_restore -d appdb_restoretest /var/backups/pg/appdb-test.dump
runuser -u postgres -- psql -d appdb_restoretest -c '\dt'
runuser -u postgres -- dropdb appdb_restoretest

\dt lists your tables (a still empty database prints Did not find any tables.). Repeat monthly with the newest dump, and copy dumps off the server; our guide to off-site backups with restic or Borg sets that up.

Point-in-time recovery with pgBackRest

Point-in-time recovery restores PostgreSQL to a chosen moment, say one minute before a bad migration, from a base backup plus continuous WAL archiving. pgBackRest handles both. Debian 13 packages version 2.55, but with PGDG added, apt installs the project's current release instead (2.59.3 in our test). Here it gets a local repository, archives WAL at least every 60 seconds and takes a first full backup:

# as root
apt install -y pgbackrest
install -d -o postgres -g postgres -m 750 /var/lib/pgbackrest /var/log/pgbackrest
mkdir -p /etc/pgbackrest
cat > /etc/pgbackrest/pgbackrest.conf <<'EOF'
[global]
repo1-path=/var/lib/pgbackrest
repo1-retention-full=2
start-fast=y

[main]
pg1-path=/var/lib/postgresql/18/main
EOF
runuser -u postgres -- psql -c "ALTER SYSTEM SET archive_mode = 'on';" -c "ALTER SYSTEM SET archive_command = 'pgbackrest --stanza=main archive-push %p';" -c "ALTER SYSTEM SET archive_timeout = '60s';"
systemctl restart postgresql@18-main
runuser -u postgres -- pgbackrest --stanza=main stanza-create
runuser -u postgres -- pgbackrest --stanza=main check
runuser -u postgres -- pgbackrest --stanza=main --type=full backup
runuser -u postgres -- pgbackrest info

The stanza-create, check and backup commands print nothing when they succeed; pgbackrest info then shows status: ok and one full backup. If check prints an ERROR, fix archiving that day: unarchived WAL piles up in pg_wal until the disk is full. Schedule weekly full and daily --type=diff backups and add a repository off the server. Then rehearse a --type=time restore on a spare VPS.

If you read in April 2026 that pgBackRest was finished, that changed within weeks. Its sole maintainer stopped work on 27 April after failing to find funding, and on 18 May the project announced that a group of sponsors, among them AWS, Supabase and Percona, would keep it going. Release 2.59.3 (4 October 2026) fixes encryption keys that could be generated weakly, so update before you encrypt that off-site repository.

MariaDB, Valkey and MongoDB

mariadb-backup --backup takes a hot physical copy, which you --prepare before restoring with --copy-back. Valkey and Redis replace their RDB file atomically, so copying it while they run is safe; Redis suggests hourly copies and one a day off the machine. With AOF on and the default appendfsync everysec, a crash loses about a second. For small MongoDB deployments, run mongodump at night.

How do you update and upgrade a self-hosted database?

apt update && apt upgrade installs minor releases and restarts the service in seconds. PostgreSQL minors arrive at least every three months and never change the storage format, so install them, but read the notes. The 13 August 2026 release (18.6 and 17.11) fixed 28 security vulnerabilities, the worst rated CVSS 8.8, and asks some users to run ANALYZE on tables with GIN indexes or rebuild certain btree_gist and ltree indexes afterwards. Above all, watch disk space. In that Hacker News thread, one engineer said PostgreSQL had caused exactly one problem in six years of running a small production service, and it was a full disk. A monitor with Uptime Kuma or Prometheus on a second server warns you well before that happens. For slow queries, add pg_stat_statements on PostgreSQL; Redis has SLOWLOG GET 10, and MongoDB logs operations over 100 ms by default.

Major versions need a plan and a fresh dump. PostgreSQL 14 gets its last fixes on 12 November 2026, so move off it now. PostgreSQL 19 was still in beta on 5 October 2026 (Beta 4 came out on 24 September); let it reach its first minor release before production follows. On Debian, pg_upgradecluster upgrades by dump and restore (slow but safe) or with --method=upgrade or link, and keeps the old cluster on another port until you drop it. PostgreSQL 18 enables data checksums on new clusters, and pg_upgrade needs both sides to match. pg_upgradecluster copies the old cluster's setting for you; if you run pg_upgrade yourself on a cluster without checksums, create the new one with initdb --no-data-checksums. MySQL cannot skip an LTS series, so 8.0 goes to 8.4, and 8.4 to 9.7, once MySQL Shell's upgrade checker passes. MariaDB finishes with mariadb-upgrade; MongoDB moves one major version at a time.

Frequently asked questions

Which database is best for a VPS?

PostgreSQL when the choice is yours: five years of support per major version, and relational data and JSON in one engine. Use Valkey or Redis for caching and queues, and MongoDB only for document data on 4 GB or more.

Is it cheaper to self-host a database than to use a managed one?

Usually in money, not always in time. A VPS gives the database all its memory and disk without tier caps; in return you spend an afternoon on setup, then a short monthly routine of updates and a restore test. If nobody will keep it, pay for managed.

Why does MongoDB say "Illegal instruction" on my VPS?

MongoDB 5.0 and later need AVX, and your server's virtual CPU does not expose it. If grep -o -w avx /proc/cpuinfo prints nothing, the fix is a host CPU model that passes AVX through, not a MongoDB setting, so ask your provider. RS Computers vCPUs report AVX and AVX2.

Can I install MongoDB on Debian 13?

Yes, from MongoDB 9.0 on. MongoDB's repository has a trixie suite for 9.0, while 8.0 and older have no Debian 13 packages, so a Debian 13 server either runs 9.0 or runs 8.0 in Docker. On an older Debian 12 or Ubuntu 24.04 server, 8.0 remains supported until October 2029.

Is the free weekly backup enough for my database?

No. It restores the whole server from the client area, but a week is a long gap for orders. Keep it as the outer net and add nightly dumps or WAL archiving, copied off the server.

How do I connect to my VPS database from my own computer?

Use an SSH tunnel instead of opening the database port. Run ssh -N -L 15432:127.0.0.1:5432 YOUR_SSH_USER@SERVER_IP on your computer, leave it running and point pgAdmin or DBeaver at 127.0.0.1, port 15432, while the database port stays closed to the internet. For MariaDB, Valkey or MongoDB, swap 5432 for 3306, 6379 or 27017.

Before real data goes in

  1. Pick a plan from the table and the city nearest your users, with Debian 13 for every engine, MongoDB included.
  2. Run the preparation step and one quick start; ss -tlnp should show the database only on 127.0.0.1 (and [::1]).
  3. Move SSH to keys and turn password logins off.
  4. Set your plan's memory value and slow-query logging.
  5. Schedule the nightly dump and restore it once, so you know the whole chain works.

Then add a monthly "restore test" reminder to your calendar, and keep it. If you would rather have us install and size the database, message us on Telegram or email info@rscomputers-ks.com with the engine, the app and roughly how much data you have, and we will suggest a plan and quote the setup. Every plan in the table above is on the VPS and VDS plans page.

← All articles

Chat on Telegram