---
title: "First-Class Databases on Railway"
description: "A guide to features of a first-class database offering, and how to enable one on Railway."
date: 2026-09-10T13:43:22.932Z
authors: ["Will Raphaelson"]
category: "Guide"
url: https://blog.railway.com/p/first-class-databases-on-railway
---

# First-Class Databases on Railway

Most application data is stored in and retrieved from a database hosted somewhere on the cloud. And modern platforms have made it absurdly easy to get started: a couple of button clicks and any modern Platform as a Service (PaaS) or database Software as a Service (SaaS) tool will happily give you a connection string and send you on your way.

But database offerings come in many shapes and sizes, and picking the wrong one can mean huge headaches down the line:

- Splitting application and database hosting across vendors can fragment observability and administration, add latency and egress costs, and require additional work to keep database traffic off the public internet.
- Using a database vendor that’s easy to start with and hard to scale with just forces you into a costly and stressful migration scenario down the line. Many one-click providers will indeed spin up a Postgres database for you; few will allow you to convert them to high availability when resiliency becomes important, add on common extensions, and provide integrated observability as you scale.

In this piece, we’ll learn what makes a database offering first-class and show how Railway meets these criteria, whether you need high-availability options, unified observability, or native connection pooling and management.

# What makes a cloud database offering first-class

A first-class production database offering should provide:

- **High availability (HA) with automatic failover.** This is when multiple copies of your database (primaries and secondaries) are maintained in parallel, with secondary databases promoted to primary automatically when the primary fails.
- **Point-in-time recovery (PITR).** Rather than relying on scheduled backups, being able to recover to an arbitrary point in time \*\*\*\*is essential to prevent data loss in production systems. If you make a mistake or let in some bad data, you’ll need to revert your database to a prior state. As opposed to snapshots, which take periodic dumps of data to which you can restore, point-in-time recovery builds on the database’s native database transaction log to enable recovery back to an arbitrary timestamp within the recovery window. High availability protects you from infrastructure failure, whereas backups and PITR protect you from bad migrations, accidental deletes, and other failures.
- **Connection management.** Many databases have a connection limit, a hard cap of clients that are able to connect to the database at a given time. To manage around this limit, add-on modules like Pgbouncer manage connection state to avoid maxing out the connection limit.
- **Extensibility.** Extensions and plugins let you add capabilities beyond what the database ships with out of the box. \*\*\*\*The ability to add common extensions for AI work or geospatial work is essential.
- **Observability.** When things go wrong, you need a reliable and complete record of what happened for debugging and prevention. Deeper than infra-level metrics like CPU and RAM usage, database observability should be database-specific, including stats on connections, query latency, replication lag, and disk.
- **Testable backups.** Until you load a backup into a fresh database and verify it’s complete, your resiliency is hypothetical. It should be easy to restore, verify, and cut over to a recovered database in testing and in an emergency.
- **Easy upgrades.** A simple upgrade path \*\*\*\*with minimal data loss is surprisingly rare in the ecosystem. As new versions of your database of choice come out, you should have a clear path to adopting that new version and reaping the benefits of security patches, bug fixes, and enhanced functionality without losing data.
- **Network adjacency to compute.** It cannot be overstated: in the long run, you should not be hosting your database far from the rest of your application. This separation silos administration and observability, and often adds latency and egress cost to every query. It follows then that full-stack platforms, where you can host the vast majority of your application infrastructure, are preferred to dedicated database-only platforms.

# First-class databases on Railway

Databases are the foundation of your app, and Railway invests accordingly to ensure all the criteria for a first-class database are met.

## First-class Postgres on Railway

Postgres is the most popular database in the world, and for good reason. It’s mature, extensible, and has a dedicated community behind it. Railway makes it easy to get started with Postgres, and simple to productionize as your stakes get higher.

### High availability

Any eligible Postgres service running a supported Railway Postgres image and version tag can be converted to a high availability (HA) cluster from its configuration pane.

![Postgres High Availability](https://cms.railway.com/media/f5f5b0bf-74f8-4aac-9864-e530c3f60448-image.png)

Under the hood, Railway leverages the popular open source technologies Patroni, etcd, and HAProxy to create a cluster of HA databases. The original database becomes what is known as the primary, and additional nodes are spun up to act as secondaries. Data is continuously replicated from the primary to the secondaries. If the primary fails, a secondary is elected as the new primary, and the proxy starts routing traffic to it automatically. No connection strings to swap out. Because replication is asynchronous by default, a sudden primary failure can still lose writes that had not yet reached a secondary. In general, converting a single-node database to an HA setup is complex and error-prone, but Railway makes it simple to add redundancy as you scale.

### Point-in-time recovery and backups

In addition to traditional volume-based backups, Railway supports restoring your database state to a specific point in time using pgBackRest. pgBackRest archives the database’s write-ahead log (WAL) to bucket storage. The dashboard shows the recovery window currently available from the retained backup and WAL archive, and you can restore the database to a timestamp within that range. Restores create a new sibling database service for inspection and verification; cutting the application over to the restored database is a separate step. PITR is available for both standalone and HA databases. Restoring an HA database currently produces a single-node fork rather than a new HA cluster.

![Postgres High Availability](https://cms.railway.com/media/247453d3-774a-4a49-83b8-75817a9692ff-image.png)

![Postgres High Availability](https://cms.railway.com/media/cb8cc48d-e332-432d-9e09-c43f6214932d-image.png)

### Connection management

As an application scales, the Postgres connection limit often becomes a bottleneck, far before resource limits like RAM or CPU are hit. Railway can add the popular connection pooler PgBouncer directly from the database settings pane.

![Postgres connection management](https://cms.railway.com/media/1462ac5f-0ee6-4b24-827a-ef02fb06adb2-image.png)

PgBouncer accepts large numbers of application connections and spreads them over a much smaller pool of connections to Postgres, preventing overload. Transaction, session, and statement pooling modes are available depending on the behavior your application needs, and unpooled connection strings are preserved for special workloads, such as migrations, that require a dedicated session.

![Postgres connection management](https://cms.railway.com/media/db5bda81-7362-4fe1-bdf4-1fb7f46d54b0-image.png)

### Extensibility and specialized functionality

Common Postgres extensions can be installed and managed directly from the Railway dashboard. Useful extensions like pgvector ship with Railway’s Postgres image and can be enabled from the database’s Config screen. Extensions that require a different Postgres image, including PostGIS and TimescaleDB, are available through Railway templates.

### Observability

Railway provides Postgres-specific observability directly in the dashboard, without requiring you to stand up Prometheus or Grafana (unless you want to).

The database view shows connection counts by activity, cache hit ratios, table sizes and row counts, index usage, and query-level statistics. Railway’s Query Statistics view surfaces expensive queries along with call counts, rows returned, total execution time, and maximum execution time. The database view also surfaces bloat and vacuum health, including dead rows, last-vacuum information, and transaction-ID freeze risk.

![Postgres database view](https://cms.railway.com/media/70f50c6e-eecc-4024-a26b-89efcd74d9f4-image.png)

In addition, all Railway services surface normal CPU, memory, disk, network, logs, and network-level observability for the rest of the application.

![Postgres metrics](https://cms.railway.com/media/bc0d5246-45a7-40f3-8a3e-18a7c204cf19-image.png)

### Backups you can actually test

Whether you’re using normal volume-based backups or PITR backups leveraging the WAL, you can easily stage a restoration by restoring a backup into a new database instance. After verification, you can swap out connection strings and successfully restore your application data to its prior, healthy state.

![Postgres backups](https://cms.railway.com/media/dbbd676a-00df-4eb7-9a5d-d3df44f4e8ad-image.png)

![Postgres backups](https://cms.railway.com/media/ac45f9aa-8f4b-4997-97f0-4d3180224cf6-image.png)

### Version upgrades

Railway has a guided Postgres major-version upgrade workflow that checks for common upgrade blockers, takes a backup, upgrades the database, and re-anchors PITR to the new major version. The database is stopped during the upgrade, so the process involves downtime. A dry-run mode lets you rehearse the upgrade against a snapshot without disrupting the running database. Railway retains the pre-upgrade backup for up to 30 days. Restoring it returns the database to its pre-upgrade state, which means any writes made after the upgrade are discarded.

![Postgres version upgrades](https://cms.railway.com/media/ceef5e5b-4682-484c-b34d-34dbf395ad08-image.png)

This is separate from, and in addition to, routine minor version and security maintenance, where Railway can automatically patch its Postgres images when a known CVE has a mitigation available during its configured maintenance window, which can be customized from the platform default.

![Postgres version upgrades](https://cms.railway.com/media/830de709-b306-42ff-9d7e-2b5d8d87146b-image.png)

### Adjacency and private networking

All new Railway Postgres databases are private by default. Applications in the same Railway environment connect over Railway's private network using `*.railway.internal`, keeping database traffic off the public internet and avoiding public-network egress charges. Public access can be added through a TCP proxy when it’s actually needed.

Your application, database, connection pooler, logs, and database metrics can all live on the same platform and private network, rather than stitching together a PaaS and a separate database vendor.

## First-class MySQL on Railway

Like Postgres, MySQL is an insanely popular database for its maturity, rich feature set, and dependability. And also like Postgres, Railway makes it easy to get started with MySQL and simple to harden it as you scale.

### High availability

Railway can convert eligible MySQL 8 and 9 databases using a supported image and a `major.minor` version tag into a high-availability cluster directly from the Config page. The cluster uses MySQL Group Replication to maintain redundant copies, with HAProxy providing a stable endpoint and automatically routing connections to the current primary. The secondaries are failover targets rather than read replicas: application reads and writes are both routed to the primary.

![MySQL HA](https://cms.railway.com/media/e14e3248-3bfc-4d29-a59f-747ee210921c-image.png)

### Point-in-time Recovery and Backups

Railway provides an official [MySQL PITR deployment template](https://railway.com/deploy/mysql-pitr--mysql-pitr). It continuously archives MySQL's binary log to a Railway Bucket, allowing you to restore to a specific timestamp by restoring a full backup and replaying transactions up to that point. Unlike Postgres PITR, this is currently an additional deployment rather than a toggle on every MySQL database.

### Connection management

MySQL generally doesn’t need a separate connection pooler like PgBouncer. The usual MySQL pattern is for the application driver or framework to maintain its own pool of reusable connections, avoiding the overhead of opening a new connection for every query. MySQL's own connectors support this model directly.

### Extensibility and specialized functionality

MySQL approaches this a bit differently from Postgres's extension ecosystem. A number of capabilities that require an extension in Postgres are simply built into MySQL.

By way of a common example, geospatial workloads, MySQL natively supports `POINT`, `LINESTRING`, `POLYGON`, and other geometry types, spatial reference systems, geographic calculations, and `SPATIAL` indexes. MySQL 9 also includes a native `VECTOR` type, although standard MySQL’s vector-search functionality is not yet comparable to pgvector. Additional plugins in the official MySQL image can be enabled by running `INSTALL PLUGIN` or `INSTALL COMPONENT` .

### Observability

Railway exposes MySQL-specific database metrics directly in the dashboard, alongside normal infrastructure metrics like CPU, memory, disk, and network usage. The database Stats view includes connection utilization, running threads, aborted connections, query throughput and slow queries, InnoDB row operations, table scan ratio, temporary tables written to disk, buffer pool usage and cache hit rate, read and write I/O, network traffic, lock contention, and currently active queries. Query-level digest statistics make it possible to identify expensive query patterns, including queries flagged as having executed without an index. These tools give you visibility into both the health of the MySQL process and the behavior of the workload without standing up a separate monitoring stack.

![MySQL observability](https://cms.railway.com/media/52dfd454-4ffe-4d19-b463-f8ebb4c48a1c-image.png)

![MySQL observability](https://cms.railway.com/media/e99f5ce5-a9d9-4071-ba18-2444905de542-image.png)

### Backups you can actually test

Railway supports manual and scheduled volume backups for MySQL, with daily backups retained for 6 days, weekly backups for 1 month, and monthly backups for 3 months. Restores are staged rather than immediately overwriting the running database: Railway mounts the restored volume, keeps the previous volume unmounted but intact, and lets you review the change before deploying it.

![MySQL backups](https://cms.railway.com/media/f4afca52-d35a-4641-979c-cee93a361166-image.png)

For more granular recovery, Railway also has a MySQL PITR workflow currently in limited availability for eligible standalone databases. Enabling PITR moves the database onto Railway’s PITR-capable MySQL image, which archives binary logs to a Railway Bucket. A restore starts from the newest full backup and replays binary logs up to the requested timestamp.

### Version upgrades

MySQL upgrades on Railway are accomplished by updating the official Docker image tag and following MySQL's supported upgrade path.

For minor releases, this is generally straightforward and can be automated. Major version upgrades require more care: you should check application and schema compatibility first, take a backup, and then move through the versions MySQL supports rather than jumping arbitrarily between releases.

![MySQL version upgrades](https://cms.railway.com/media/7eb4e3fe-9546-449a-b9be-81895ca74c34-image.png)

Railway gives you control over the MySQL version you run, but unlike Postgres, it does not currently provide a guided in-place major-version upgrade workflow.

### Adjacency and private networking

Like Railway's other databases, MySQL is private by default. Applications in the same environment connect over Railway's encrypted private network using the database's `*.railway.internal` address. Public access is opt-in via a TCP Proxy and incurs network egress charges.

# Conclusion

As your application scales, it’s important to invest in resilient data storage. If you’re still hopping between SaaS tools or running single instance storage, don’t wait until the first incident to start exploring your options. Railway gives both Postgres and MySQL a strong path from a one-click database to a resilient production deployment. To get started, check out the HA [Postgres](https://docs.railway.com/databases/postgresql-ha) and [MySQL](https://www.notion.so/First-Class-Databases-on-Railway-3c8cad2e212d80749b9ef114bc135489?pvs=21) docs, explore your database’s settings panel, or reach out on [Central Station](https://station.railway.com/)!


---

Open this post in a browser: https://blog.railway.com/p/first-class-databases-on-railway
