Configuring your Database
Deploio supports a variety of databases, including MySQL, MariaDB and PostgreSQL. You can find more information on the different databases available here and information about pricing here.
Protecting Database Access
To access the database, you must set up SSH key authentication. You will need to pass the public key to the --ssh-keys
flag when creating the database and use the private key to gain access.
You also need to add your IP address to the --allowed-cidrs
flag. If you wish to allow all IP addresses, you can set this to 0.0.0.0/0
.
Common database creation settings
There are a number of configurations we can apply when creating our database. You can see more information on these arguments by running -h
for the desired database. For example nctl create mysql -h
for MySQL.
Below, we note a few important configuration options.
Name
The name of the instance can be freely chosen, but must be unique. Once created, the name cannot be changed.
Location
Depending on available resources, instances can be created in two locations within the "ColoZüri" data center or the "NTT" data center in Rümlang. The location cannot be changed later.
This can be set by the --location
flag and the default is cz41
.
Machine type
We recommend nine-db-s
or larger sizings for production workloads.
Machine Type | Virtual CPU (VCPU) | RAM | Storage Space | Monthly Fees |
---|---|---|---|---|
nine-db-xs | 2 | 4 GB | 20 GB | CHF 65 |
nine-db-s | 4 | 8 GB | 20 GB | CHF 97 |
nine-db-m | 4 | 12 GB | 20 GB | CHF 117 |
nine-db-l | 6 | 16 GB | 20 GB | CHF 149 |
nine-db-xl | 8 | 24 GB | 20 GB | CHF 201 |
nine-db-xxl | 10 | 32 GB | 20 GB | CHF 253 |
Additional storage space per 10 GB: CHF 1.50 per month.
Machine types can be changed after creation. After an adjustment, the database instance will be restarted and will be unavailable for a few minutes.
Allowed IP addresses
IPv4 addresses and address ranges from which connections to the service can be established. Access from our Kubernetes products NKE (Nine Kubernetes Engine) and GKE (Google's Kubernetes Engine), as well as from deplo.io, is already enabled.
The access restriction can be adjusted at any time. Adjustments are made non-disruptively moments after the form is submitted.
We can set the allowed CIDRs by passing the --allowed-cidrs={CIDR}
flag.
Backup Retention Policy
The backup retention period in days can be selected between 0 and 365 days by passing the --keep-daily-backups={X}
flag.
If 0 days is selected, the backup routine will be disabled and all existing backups will be deleted. The default retention period is 10 days.
Please note that the storage space requirement increases if the local retention period is long. This may result in higher instance costs.
For more information about backing up your databases on a daily basis, accessing the backups, and how to create your own backups if needed, see the section about backups.
SSH Public Keys
Configure the public keys to access the database backups via SSH. The keys can be adjusted at any time.
These can be set via the --ssh-keys
flag or the --ssh-keys-file
flag.
Version
You can select your desired version when creating the database instance. The version cannot be adjusted after the instance is created.
You can view the available versions below for your desired database.
Database specific creation settings
- PostgreSQL
- MySQL
Versions available
In the following table you can find the support period of each PostgreSQL version:
PostgreSQL Version | Support End |
---|---|
16 | November 09, 2028 |
15 | November 11, 2027 |
14 | November 12, 2026 |
13 | November 13, 2025 |
Extensions
Nine provides a variety of extensions that you can activate as needed. The following extensions are available:
Extensions
- address_standardizer
- address_standardizer_data_us
- btree_gin
- btree_gist
- citext
- cube
- dict_int
- earthdistance
- fuzzystrmatch
- hstore
- intarray
- isn
- lo
- ltree
- pg_prewarm
- pg_stat_statements
- pg_trgm
- pgcrypto
- plpgsql
- postgis
- postgis_tiger_geocoder
- postgis_topology
- seg
- tablefunc
- tcn
- tsm_system_time
- tsm_system_rows
- unaccent
- uuid-ossp
Creating the Database
Considering the creation settings above, we run the following command to create the database server:
nctl create postgres {DATABASE_NAME} \
--postgres-version={X} \
--machine-type=nine-db-s \
--allowed-cidrs={IP_ADDRESS}/0 \
--ssh-keys={PUBLIC_KEY}
Please adjust the flags as you need.
We can now access the server using the FQDN and generated user and password. We can find this information as follows:
- FQDN: Run
nctl get postgres {DATABASE_NAME}
- User: Run
nctl get postgres {DATABASE_NAME} --print-user
- Password: Run
nctl get postgres {DATABASE_NAME} --print-password
Now we want to create the database on the server. We can run the following command:
createdb -U dbadmin -h {FQDN} {DATABASE_NAME}
You will be prompted to enter the password.
We can check that this database was created by entering the server using psql -U dbadmin -h {FQDN} -d postgres
and then running the command \l
to list the databases on the server.
Interacting with databases
Connecting
The connection information (FQDN, user, and password) for your instance can be found in Cockpit under Access Information. The database servers are accessible via their standard ports.
The instance will only accept TLS connections. Depending on the client or library, you may need to explicitly enable TLS.
psql -h FQDN -d postgres -U dbadmin
# at first you can use the default database 'postgres' to be able to connect.
Basic commands
Creating a new database named app_prod
:
postgres=> CREATE DATABASE app_prod;
Creating a new user named app_prod
:
postgres=> CREATE USER app_prod WITH PASSWORD 'strongpassword';
Granting the user app_prod
privileges to the database app_prod
:
postgres=> GRANT ALL ON app_prod TO app_prod;
For granting more specified privileges, find the details in the official postgres documentation: DDL privileges.
Changing the user app_prod
's password:
postgres=> ALTER USER app_prod WITH PASSWORD 'newstrongpassword';
Deleting the database app_prod
:
postgres=> DROP DATABASE app_prod;
Deleting the user app_prod
:
postgres=> DROP USER app_prod;
Use the official Postgres documentation for additional info about user and database management.
Versions available
Nine currently provides On-Demand MySQL environments with MySQL 8 only.
Long Query Time
The "Long Query Time" specifies the time in seconds after which the MySQL service considers the execution of a query to be slow and logs the query.
Min Word Length
This value configures the minimum length of a word that MySQL will use for full text search.
Nine sets the value chosen here for both ft_min_word_len
(MyISAM Storage Engine, Legacy) and innodb_ft_min_token_size
(InnoDB Storage Engine).
Character Set
The charset is customizable. From experience, the default values utf8mb4_unicode_ci
/ utf8mb4
cover most needs.
Before considering customizing these values, please consult the MySQL documentation: Character Sets and Collations in MySQL.
Transaction Isolation
Nine recommends not making any adjustment to the selected default value unless absolutely necessary due to application requirements.
Be sure to consult the MySQL documentation in advance and familiarize yourself with the related implications: Transaction Isolation Levels.
SQL Modes
The SQL Mode should also only be adjusted if the application absolutely requires it. Nine uses the default values set by Oracle for MySQL 8.
Oracle provides documentation and FAQ about SQL Modes in the following articles:
Extensions
MySQL does not support extensions in the same way as PostgreSQL (via CREATE EXTENSION
). However, many advanced features are either built into the core engine or available via optional server plugins.
You don’t need to enable these manually — they are either available by default or configurable at runtime (via SQL or server settings).
To inspect available plugins on your instance, you can run:
SHOW PLUGINS;
Let us know if you need help enabling specific capabilities or configuring advanced features in your MySQL setup.
Creating the Database
Considering the creation settings above, we run the following command to create the database server:
nctl create mysql {DATABASE_NAME} \
--mysql-version={X} \
--machine-type=nine-db-s \
--allowed-cidrs={IP_ADDRESS}/0 \
--ssh-keys={PUBLIC_KEY}
Please adjust the flags as you need.
We can now access the server using the FQDN and generated user and password. We can find this information as follows:
- FQDN: Run
nctl get mysql {DATABASE_NAME}
- User: This is always set to
dbadmin
but you can check by runningnctl get mysql {DATABASE_NAME} --print-user
- Password: Run
nctl get mysql {DATABASE_NAME} --print-password
Now we want to create the database on the server. We can run the following commands:
-
Connect to the server:
mysql -h {FQDN} -u dbadmin -p
You will be prompted to enter the password.
-
Create a new database from the MySQL prompt:
CREATE DATABASE my_app_db;
-
List all databases to confirm:
SHOW DATABASES;
Interacting with databases
Connecting
The connection information (FQDN, user, and password) for your instance can be found in Cockpit under Access Information. The database servers are accessible via their standard ports.
The instance will only accept TLS connections. Depending on the client or library, you may need to explicitly enable TLS.
The TLS certificate in use is self-signed. In addition to enabling TLS transport encryption, you might need to disable certificate validation.
psql -h FQDN -d postgres -U dbadmin
# at first you can use the default database 'postgres' to be able to connect.
Basic commands
Connecting to your Database:
mysql -h FQDN -u dbadmin -p
Creating a new database named app_prod:
mysql> CREATE DATABASE app_prod;
Creating a new user named app_prod
:
mysql> CREATE USER 'app_prod' IDENTIFIED BY 'strongpassword';
Granting the user app_prod
privileges to the database app_prod
:
mysql> GRANT ALL ON app_prod.* TO 'app_prod'@'%';
For granting more specified privileges, find the details in the official MySQL documentation: Summary of Available Privileges.
Changing the user app_prod
's password:
mysql> ALTER USER app_prod IDENTIFIED BY 'newstrongpassword';
Deleting the database app_prod
:
mysql> DROP DATABASE app_prod;
Deleting the user app_prod
:
mysql> DROP USER app_prod;
Use the official MySQL documentation for additional info about user and database management.
Monitoring for health and performance
Deploio database instances run on Nine’s managed infrastructure. Nine monitors basic infrastructure-level availability, however you are responsible for observing database-level performance and load.
You can view the current status of the system here.
Nine monitors the instance with a monitoring system 24x7. In the event of a malfunction, an (on-call) technician from Nine is automatically alerted and restores proper operation as quickly as possible.
You can also view the current status of a database via the Cockpit, as well as information such as version, backup retention policy and "Allowed IP Addresses". This information can help when trying to assess and connection issues.
⚠️ Resource saturation (e.g., full CPU/memory/disk) is not considered a malfunction. You are responsible for monitoring performance and scaling your instance as needed.
What is Monitored by Nine
Nine monitors the availability and infrastructure health of the database node, such as:
- Instance accessibility (e.g. FQDN ping)
- Hardware failures
- Backup completion status
- Disk thresholds (for automatic storage expansion)
However, application-level metrics like query latency, connection count, or CPU load are not exposed via Cockpit today. This feature is currently WIP and will be available soon.
What You Can Monitor Yourself
- PostgreSQL
- MySQL
To monitor your PostgreSQL database performance, you can connect via psql
and use built-in extensions:
pg_stat_statements
– View expensive queries by total timepg_stat_activity
– List active sessions and queriespg_stat_bgwriter
– Monitor I/O activity and checkpoint behavior
Example to get top slow queries:
SELECT * FROM pg_stat_statements
ORDER BY total_time DESC
LIMIT 5;
To monitor connections:
SELECT * FROM pg_stat_activity;
Best Practices for PostgreSQL
- Enable
pg_stat_statements
at instance creation or shortly after - Use tools like
psql
, pgAdmin, or DBeaver for live inspection - Log slow queries from your app for long-term insights
- Regularly check backup status and instance disk growth
- Scale machine type via
nctl update
if your app outgrows the current size
To monitor your MySQL database performance, you can connect via mysql
and run:
mysql -u dbadmin -p -h {FQDN}
Useful commands:
-
View active queries:
SHOW PROCESSLIST;
-
View general performance stats:
SHOW GLOBAL STATUS;
-
Check uptime, queries per second, open connections:
SHOW STATUS LIKE 'Uptime';
SHOW STATUS LIKE 'Threads_connected';
SHOW STATUS LIKE 'Questions';
Best Practices for MySQL
- Enable slow query logging at the application level
- Use tools like
mysql
, pgAdmin, or DBeaver for live inspection - Log slow queries from your app for long-term insights
- Regularly check backup status and instance disk growth
- Scale machine type via
nctl update
if your app outgrows the current size
Backup and Restore
See Backup Retention Policy section for configuration options.
Nine backs up the databases daily between 01:00 and 02:00. These backups are kept locally for 10 days (configurable) and on a remote backup system for seven days.
Backups are stored in the /home/dbadmin/backup directory
. All backups are versioned in directories with the following time scheme (example, exact timestamp will vary): 2022-11-18-0134
.
/home/dbadmin/backup/latest
always points to the latest backup.
Backups are stored in the customer
directory. The database schema can be found in the structure
directory.
Create additional backups
Additional backups can be created by running:
- PostgreSQL
- MySQL
dbadmin@managedvirtualmachine-xxxxxxx:~ $ sudo nine-postgresql-backup
2022-11-18T09:54:19+01:00 Dumped and compressed database 'frontend_production' in 53 seconds
2022-11-18T09:55:04+01:00 Dumped and compressed database 'frontend_staging' in 45 seconds
dbadmin@managedvirtualmachine-xxxxxxx:~ $ sudo nine-mysql-backup
2022-11-18T09:54:19+01:00 Dumped and compressed database 'frontend_production' in 53 seconds
2022-11-18T09:55:04+01:00 Dumped and compressed database 'frontend_staging' in 45 seconds
Storage requirements of the backups
The backup routine creates compressed backups. Depending on the size of the database, this may still result in backups that require a lot of disk space.
To ensure that sufficient disk space is always available, the On Demand database environments have a mechanism that automatically monitors and performs a disk space expansion if required.
Number of backups kept
The number of backups kept can be adjusted via Cockpit. The duration of the retention period can be freely selected between one and 365 days.
Please note that a long retention period requires more storage space, which may result in additional costs.
Disabling backups
To disable backups, the retention time can be adjusted to 0
.
In this case, the creation of further backups is deactivated. All backups already created will be deleted shortly after the adjustment.
Access to the created backups
Using the system user dbadmin
you can access the created backups via an SSH connection.
SSH access for the user is controlled by storing an SSH key in Cockpit.
Restoring and working with the created backups
The backup routine used is the same as the one we use for our managed servers. We have described how to work with the backups as well as more information about restoring backups in the following support articles:
Automatic storage space expansion
To provide the most robust environment possible, the available storage space is monitored at 5 minute intervals. If our monitoring detects that the available storage space falls below a threshold, an expansion of the storage quota is automatically performed.
Thresholds
For a total storage size below 50 GB, the threshold is 5 GB of free storage space.
For a total storage size above 50 GB, the threshold is 10% free storage space.
Expansion of the storage space
The expansion of the storage space is done automatically in steps of 25 GB.
Reduction of storage space
It is not currently possible to reduce the disk size of database instances. The only way to reduce disk usage is to download a backup of the current instance and restore it to a new instance.
Billing of the storage space expansion
The additional storage space is charged automatically.