EntwicklerVerwaltete Datenbanken

Verwaltete Datenbanken

Verwaltete Datenbanken laufen auf Hostwolf-Datenbankservern, getrennt von deinen App-Servern. Deine Apps erreichen sie per TLS, sodass jede Kopie einer App, auf jedem Server und in jeder Stadt, dieselben Daten nutzt. Genau das erlaubt es der App-Ebene, horizontal zu skalieren.

  • Engines: PostgreSQL, MariaDB (MySQL-kompatibel) und Redis.
  • Sicherheit: TLS ist Pflicht, und eine Datenbank nimmt nur Verbindungen von den Servern deines Teams an.
  • Connection Pooling: PostgreSQL und MariaDB haben einen Pooler, sodass sich Tausende App-Verbindungen wenige Datenbankverbindungen teilen.
  • Speicher: wächst von selbst; Speicher über dem Tarif wird pro GB berechnet.
  • Backups: jede Nacht, 7 Tage aufbewahrt, extern gespeichert. PostgreSQL hat außerdem Point-in-Time-Recovery für die letzten 7 Tage.
  • Löschen: Die Abrechnung endet sofort; der Support kann eine gelöschte Datenbank 7 Tage lang wiederherstellen.
  • Abrechnung: stündlich (Monatspreis ÷ 730), auf deiner nächsten Serverrechnung. Du brauchst zuerst ein aktives Server-Abo.

Tarife und Preise#

hw $API/managed-databases/catalog | jq
TarifArbeitsspeicherSpeicherApp-Verbindungen (gepoolt)Direkte VerbindungenServer
small256 MB5 GB1,00010geteilt
medium512 MB10 GB2,00040geteilt
large4 GB80 GB5,000100dediziert
xlarge12 GB200 GB10,000200dediziert, 8 vCPU

Der Katalog listet die Regionen (zum Beispiel vultr:ams für Amsterdam) mit dem Monats- und Stundenpreis jedes Tarifs in USD und die obigen Limits (pooled_clients, direct_connections, pool_size). Wähle die Region, die deinen App-Servern am nächsten liegt. Preise am 11. Oktober 2026:

TarifAmsterdam (vultr:ams)Newark (vultr:ewr)
small3,88 $/Monat3,88 $/Monat
medium7,74 $/Monat7,74 $/Monat
large62,13 $/Monat62,13 $/Monat
xlarge229,24 $/Monatnicht im Angebot

Erstellen und verbinden#

DB=$(hw -X POST $API/managed-databases \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"engine": "postgres", "plan": "small", "region": "vultr:ams"}' | jq -r .uuid)

# A few minutes later: status goes creating → ready
hw $API/managed-databases/$DB | jq -r .status

# Save the connection URLs on an app, then redeploy it
hw -X POST $API/managed-databases/$DB/attach -d "{\"application_uuid\": \"$APP\"}"
hw -X POST $API/applications/$APP/start
  • attach speichert die gepoolte URL als DATABASE_URL und die direkte URL als DATABASE_DIRECT_URL in der App (Redis: REDIS_URL). Die URLs laufen nie durch dein Skript.
  • attach ersetzt nie stillschweigend eine Variable. Hat die App DATABASE_URL (oder REDIS_URL) schon mit einem anderen Wert, wird nichts gespeichert, und die Antwort ist 409 mit conflicts und einem freien suggested_env_key. Sende "env_key": "DATABASE_URL_2", um unter diesem Namen zu speichern (die direkte URL wird zu DATABASE_DIRECT_URL_2), oder "overwrite": true, um sie zu ersetzen.
  • Der Header Idempotency-Key (eine UUID) macht den Aufruf sicher wiederholbar: Derselbe Schlüssel legt nie eine zweite Datenbank an. Ein erneut genutzter Schlüssel mit anderen Einstellungen ergibt 409.
  • Datenbank-Aktionen sind auf 10 pro Minute begrenzt.

Gepoolte und direkte URLs#

Jede PostgreSQL- und MariaDB-Datenbank hat zwei URLs zu denselben Daten:

Gepoolt (url, DATABASE_URL)Direkt (direct_url, DATABASE_DIRECT_URL)
PostgreSQLPort 6432, PgBouncer im TransaktionsmodusPort 5432
MariaDBPort 6033, ProxySQLPort 3306
Verbindungenbis zum gepoolten Limit des Tarifs; über dem Pool warten sie (bis zu 120 s), statt fehlzuschlagendas Direkt-Limit des Tarifs (10 bei small)
Nutze sie fürdeine App: Web-Anfragen, Worker, jede Kopie der AppMigrationen, LISTEN/NOTIFY, Session-Einstellungen (SET), Advisory Locks, temporäre Tabellen und lange Transaktionen

Nutze in deiner App die gepoolte URL. Mit der direkten URL halte den Pool der App innerhalb des Direkt-Limits des Tarifs, und zähle dabei jede Kopie der App mit. Prepared Statements funktionieren über den Pooler. Führe Migrationen mit der direkten URL aus, zum Beispiel DATABASE_URL=$DATABASE_DIRECT_URL npx prisma migrate deploy als Befehl nach der Bereitstellung (App-Einstellungen, Bereitstellungslebenszyklus). Der Befehl vor der Bereitstellung läuft in der Kopie, die noch läuft, bevor der neue Build startet: Er würde die Migrationen der vorherigen Version ausführen und wird bei der ersten Bereitstellung übersprungen.

Um die URLs selbst zu lesen, braucht das Token Sensible Daten lesen:

hw $API/managed-databases/$DB/connection | jq
# {"env_key": "DATABASE_URL", "url": "postgresql://…@db-….db.app.hostwolf.net:6432/…?sslmode=require",
#  "direct_url": "postgresql://…@db-….db.app.hostwolf.net:5432/…?sslmode=require", "direct_connections": 10}
EngineURL-Format
PostgreSQLpostgresql://user:password@host:port/db?sslmode=require
MariaDBmysql://user:password@host:port/db?ssl-mode=REQUIRED
Redisrediss://user:password@host:port/0

Der Hostname (db-<id>.db.app.hostwolf.net) bleibt bei Tarif-Upgrades und Umzügen gleich. Die Zertifikate sind öffentlich (Let's Encrypt), du brauchst also keine CA-Datei: sslmode=verify-full und ssl-mode=VERIFY_IDENTITY funktionieren mit dem Zertifikatsspeicher deines Systems, auf dem gepoolten und dem direkten Port. Verbindungen von außerhalb der Server deines Teams, auch von deinem eigenen Computer, werden abgelehnt. Um Daten anzusehen, nutze eine Shell auf einem deiner Server (das Terminal der Konsole) oder ein Tool, das in einer deiner Apps läuft.

Speicher, der mitwächst#

Die Disk des Datenbankservers wächst von selbst, bevor sie voll ist, ohne Neustart. Dein Tarif enthält seinen Speicher (5, 10, 80 oder 200 GB). Darüber hinaus wird jedes volle GB stündlich abgerechnet: 0,13 $ im Monat für 1 GB, 1,24 $ für 10 GB, 12,38 $ für 100 GB. extra_storage an der Datenbank zeigt die aktuellen zusätzlichen GB und den Preis, und metrics zeigt ihre Größe.

Einen Tarif upgraden#

Wenn eine Datenbank in 3 von 4 Stunden stärker ausgelastet ist, als ihr Tarif hergibt (CPU, Verbindungen oder ein volles Redis), sagt advice, welcher Tarif passt, und die Team-Admins bekommen eine E-Mail. Nichts ändert sich, bis du upgradest. upgrades listet die Tarife, auf die sie jetzt wechseln kann:

hw $API/managed-databases/$DB | jq '.upgrades, .advice'
# [{"plan": "medium", "how": "in_place"}, {"plan": "large", "how": "move"}]

hw -X POST $API/managed-databases/$DB/upgrade -d '{"plan": "large"}'
# 422 {"message": "The large plan costs $62.13/month (now $3.88), billed hourly from the change. … Send \"confirm\": true to go ahead.", "confirm_required": true, "quote": {…}}

hw -X POST $API/managed-databases/$DB/upgrade -d '{"plan": "large", "confirm": true}'   # 202
  • in_place: small → medium läuft weiter. large → xlarge verschiebt die Disk auf einen größeren Server, mit etwa einer Minute Ausfallzeit.
  • move: Die Datenbank wird auf einen anderen Server kopiert. Während des Kopierens ist sie nicht erreichbar (etwa 20 Sekunden für 200.000 Zeilen), danach zeigt der Hostname auf den neuen Server.
  • Der neue Preis gilt ab der Änderung. Tarife werden nie herabgestuft.

Redis-Speicher#

Eine Redis-Datenbank fasst höchstens den Speicher ihres Tarifs (256 MB, 512 MB, 4 GB oder 12 GB). Die Eviction-Policy legt fest, was passiert, wenn sie voll ist:

PolicyWenn der Speicher voll istNutze sie für
allkeys-lruEntfernt die am längsten nicht genutzten KeysCaches
noeviction (Standard)Lehnt Schreibvorgänge mit einem Fehler ab; Lesen funktioniert weiterQueues, Sessions, Daten, die nicht verschwinden dürfen
volatile-lru, allkeys-lfu, volatile-lfu, allkeys-random, volatile-random, volatile-ttlDie anderen Redis-PoliciesSonderfälle

Wähle sie beim Erstellen der Datenbank ("eviction_policy": "allkeys-lru") oder ändere sie jederzeit; sie gilt sofort, ohne Neustart:

hw -X PATCH $API/managed-databases/$DB -d '{"eviction_policy": "allkeys-lru"}'

metrics zeigt den belegten Speicher, das Maximum und die bisher verdrängten Keys.

Backups#

hw -X POST $API/managed-databases/$DB/backups   # an extra backup now (202)

Die nächtlichen Backups laufen trotzdem. In der Konsole zeigt Wiederherstellungspunkte bei der Datenbank sie an.

PostgreSQL lässt sich in der Konsole auf jede Minute der letzten 7 Tage wiederherstellen: Die Wiederherstellung erstellt eine neue Datenbank mit dem Stand von diesem Moment, mit eigener URL und wie jede Datenbank abgerechnet. Die aktuelle Datenbank läuft weiter. Um ein MariaDB- oder Redis-Backup wiederherzustellen, schreib dem Support mit der uuid der Datenbank und der Uhrzeit.

Löschen#

hw -X DELETE $API/managed-databases/$DB

Die Abrechnung endet sofort. Apps, die sie genutzt haben, behalten die alte DATABASE_URL, bis du sie änderst.

Fehler, die dir begegnen können#

StatusBedeutung
403Bestätige zuerst deine E-Mail-Adresse in der Konsole, oder dem Token fehlt eine Berechtigung.
409Die Datenbank ist noch nicht bereit, oder der Idempotency-Key wurde für eine andere Datenbank verwendet.
422Unbekannte Engine, unbekannter Tarif oder unbekannte Region, kein aktives Server-Abo, ein Upgrade, das gerade nicht möglich ist, oder fehlendes confirm.
503Verwaltete Datenbanken sind kurz nicht erreichbar. Es wurde nichts geändert; versuch es noch einmal.
Kommst du nicht weiter, oder fehlt ein Endpunkt? Sag es uns unter app.hostwolf.net/contact oder [email protected].