---
title: "Deploy TiDB Cluster"
description: "A MySQL-compatible distributed SQL database, deploy in 1-click 🚀"
category: "Storage"
url: https://railway.com/deploy/tidb-cluster
---

# Deploy TiDB Cluster

A MySQL-compatible distributed SQL database, deploy in 1-click 🚀

**[Deploy TiDB Cluster on Railway](https://railway.com/template/tidb-cluster)**

- **Creator:** INF Labs
- **Category:** Storage

## Template content

### pd

- **Image:** pingcap/pd:v8.5.8
- **Start command:** `pd-server \   --name=pd \   --data-dir=/data/pd \   --client-urls=http://0.0.0.0:2379 \   --advertise-client-urls=http://${RAILWAY_PRIVATE_DOMAIN}:2379 \   --peer-urls=http://0.0.0.0:2380 \   --advertise-peer-urls=http://${RAILWAY_PRIVATE_DOMAIN}:2380 \   --initial-cluster=pd=http://${RAILWAY_PRIVATE_DOMAIN}:2380`

### tidb https://raw.githubusercontent.com/pingcap/tidb/refs/heads/master/docs/tidb-logo.png

- **Image:** pingcap/tidb:v8.5.8
- **Start command:** `tidb-server \   --store=tikv \   --path=${pd.RAILWAY_PRIVATE_DOMAIN}:2379 \   --host=0.0.0.0 \   --advertise-address=${RAILWAY_PRIVATE_DOMAIN} \   --port=4000 \   --status=10080`

### tikv https://github.com/tikv/tikv/raw/master/images/tikv-logo.png

- **Image:** pingcap/tikv:v8.5.8
- **Start command:** `tikv-server \   --addr=0.0.0.0:20160 \   --advertise-addr=${RAILWAY_PRIVATE_DOMAIN}:20160 \   --status-addr=0.0.0.0:20180 \   --advertise-status-addr=${RAILWAY_PRIVATE_DOMAIN}:20180 \   --pd=${pd.RAILWAY_PRIVATE_DOMAIN}:2379 \   --data-dir=/data/tikv`

## Documentation

# Deploy and Host TiDB Cluster on Railway

TiDB is an open-source distributed SQL database designed for scalability, strong consistency, and MySQL compatibility.

This Railway template deploys a minimal TiDB cluster using separate TiDB, PD, and TiKV services connected through Railway Private Networking.

## About Hosting

Hosting TiDB Cluster on Railway gives you a simplified distributed SQL environment without manually provisioning multiple virtual machines or managing Kubernetes.

This template deploys:

* **TiDB** as the SQL processing layer
* **PD** for cluster metadata and placement management
* **TiKV** as the persistent transactional storage layer

Only the TiDB service should be accessed by applications.

PD and TiKV remain internal and communicate through Railway Private Networking.

For external database connections, use Railway **TCP Proxy** on the TiDB service instead of an HTTP public domain.

## Why Deploy

Deploying TiDB Cluster on Railway makes it easier to experiment with distributed SQL while keeping infrastructure management relatively simple.

This template is useful when you want to:

* Run a MySQL-compatible distributed SQL database
* Test TiDB architecture with PD and TiKV
* Separate SQL processing from persistent storage
* Build applications using standard MySQL drivers
* Experiment with distributed database behavior
* Use Railway Private Networking for cluster communication
* Persist PD metadata and TiKV data with Railway Volumes
* Access TiDB externally through Railway TCP Proxy
* Develop and test applications before moving to a larger TiDB deployment

This template uses a minimal topology:

```text
1× TiDB
1× PD
1× TiKV
```

&gt; ⚠️ This topology is intended for development, testing, learning, and lightweight workloads. It is not a High Availability TiDB deployment.

## Common Use Cases

* Distributed SQL development
* MySQL-compatible application backends
* TiDB integration testing
* Database migration testing
* Transactional application development
* Distributed database experiments
* Cloud-native application prototypes
* Backend development
* Learning TiDB architecture
* Testing MySQL-compatible frameworks and ORMs

## Dependencies for TiDB Cluster

This template deploys three core TiDB components.

### TiDB

* Image: `pingcap/tidb`
* Provides the MySQL-compatible SQL endpoint
* Default SQL port: `4000`
* Connects to PD through Railway Private Networking
* Does not require persistent storage

### PD

* Image: `pingcap/pd`
* Manages cluster metadata
* Handles scheduling and placement information
* Default client port: `2379`
* Uses a persistent Railway Volume
* Accessible only through Railway Private Networking

### TiKV

* Image: `pingcap/tikv`
* Provides transactional key-value storage
* Default service port: `20160`
* Stores database data on a persistent Railway Volume
* Connects to PD through Railway Private Networking

No additional services are required.

This template does **not** require:

* PostgreSQL
* MySQL
* Redis
* MinIO
* S3-compatible object storage
* Railway Bucket

## Architecture

```text
                Application
                     │
                     │ MySQL Protocol
                     ▼
              ┌─────────────┐
              │    TiDB     │
              │    :4000    │
              └──────┬──────┘
                     │
                     │ Railway Private Network
                     ▼
              ┌─────────────┐
              │     PD      │
              │    :2379    │
              │             │
              │  /data/pd   │
              └──────┬──────┘
                     ▲
                     │
              ┌──────┴──────┐
              │    TiKV     │
              │   :20160    │
              │             │
              │ /data/tikv  │
              └─────────────┘
```

The dependency flow is:

```text
TiDB ─────► PD
TiKV ─────► PD
```

PD provides cluster coordination and metadata services, while TiKV stores the actual application data.

## Storage

Persistent Railway Volumes are used only for stateful components.

| Service | Volume  | Purpose                        |
| ------- | ------- | ------------------------------ |
| TiDB    | ❌       | Stateless SQL processing layer |
| PD      | `/data` | Cluster metadata               |
| TiKV    | `/data` | Database data                  |

Do not delete or replace the PD or TiKV volumes after the cluster contains important data.

## Networking

Cluster communication should remain private.

### TiDB

* SQL port: `4000`
* Accessible internally through Railway Private Networking
* External access should use Railway TCP Proxy

### PD

* Client port: `2379`
* Peer port: `2380`
* Private only
* Do not expose using a public domain

### TiKV

* Service port: `20160`
* Status port: `20180`
* Private only
* Do not expose using a public domain

TiDB and TiKV reference PD through its Railway private hostname.

Example:

```env
PD_HOST="${{pd.RAILWAY_PRIVATE_DOMAIN}}" # Private hostname of the PD service
```

## Connecting to TiDB

TiDB uses the MySQL wire protocol.

It is **not** an HTTP API.

### From Another Railway Service

Applications deployed in the same Railway project can connect using the TiDB private hostname.

Example:

```text
tidb.railway.internal:4000
```

or through the generated Railway private domain reference.

### From Outside Railway

Enable **TCP Proxy** on the TiDB service.

Then connect using a MySQL-compatible client.

Example:

```bash
mysql \
  -h  \
  -P  \
  -u root
```

Compatible clients include:

* MySQL CLI
* DBeaver
* DataGrip
* TablePlus
* MySQL Workbench
* MySQL-compatible application drivers

Do not use a Railway HTTP public domain for port `4000`.

## Important Environment Variables

Only the variables that are relevant to the Railway deployment are shown below.

### TiDB

```env
PORT="4000" # MySQL-compatible TiDB SQL port
PD_HOST="${{pd.RAILWAY_PRIVATE_DOMAIN}}" # Private hostname of the PD service
```

### PD

```env
PORT="2379" # PD client port used by TiDB and TiKV
RAILWAY_RUN_UID="0" # Allow PD to write to the Railway-mounted volume
```

### TiKV

```env
PORT="20160" # TiKV service port
PD_HOST="${{pd.RAILWAY_PRIVATE_DOMAIN}}" # Private hostname of the PD service
RAILWAY_RUN_UID="0" # Allow TiKV to write to the Railway-mounted volume
```

## Initial Database Security

A fresh TiDB deployment may allow the `root` account without a password depending on the upstream configuration.

After deployment, secure the database before exposing it to external clients.

Example:

```sql
ALTER USER 'root'@'%' IDENTIFIED BY 'your-strong-password';
```

For applications, use a dedicated user instead of the root account.

Example:

```sql
CREATE DATABASE app;

CREATE USER 'app'@'%' IDENTIFIED BY 'your-strong-password';

GRANT ALL PRIVILEGES ON app.* TO 'app'@'%';
```

## Important Notice

&gt; ⚠️ **This template is not a High Availability TiDB deployment.**

The template runs:

* `1× TiDB`
* `1× PD`
* `1× TiKV`

This topology does not provide node-level redundancy.

If PD or TiKV becomes unavailable, the cluster may become unavailable until the affected service is restored.

Production-grade TiDB environments typically use multiple PD and TiKV instances to provide redundancy, fault tolerance, and quorum-based operation.

Use this template primarily for:

* Development
* Testing
* Learning
* Integration environments
* Lightweight workloads
* Non-critical deployments

## TiDB Cluster vs Traditional Databases

| Feature                          | TiDB Cluster | PostgreSQL | MySQL |
| -------------------------------- | -----------: | ---------: | ----: |
| MySQL-compatible protocol        |            ✅ |          ❌ |     ✅ |
| Distributed architecture         |            ✅ |          ❌ |     ❌ |
| TiKV storage                     |            ✅ |          ❌ |     ❌ |
| Separate SQL and storage layers  |            ✅ |          ❌ |     ❌ |
| Transactional SQL                |            ✅ |          ✅ |     ✅ |
| Horizontal scaling design        |            ✅ |         ⚠️ |    ⚠️ |
| Cloud-native architecture        |            ✅ |         ⚠️ |    ⚠️ |
| Simple single-process deployment |            ❌ |          ✅ |     ✅ |

## Why Railway

Railway simplifies the infrastructure required to run a minimal TiDB cluster.

This template uses:

* Railway Private Networking for TiDB, PD, and TiKV communication
* Railway Volumes for persistent PD and TiKV storage
* Railway reference variables for internal service discovery
* Railway TCP Proxy for external MySQL-compatible connections
* Isolated services for each TiDB component
* Automatic container deployment and restart management

This provides a practical way to deploy and experiment with TiDB without manually provisioning multiple servers or operating a Kubernetes cluster.


## Similar templates

- [Garage S3 Storage](https://railway.com/deploy/garage-s3-storage) — Ultra-light S3 server: fast, open-source, plug-and-play.
- [Redis](https://railway.com/deploy/redis-1) — Self Host Latest Redis with Railway
- [EasyImg](https://railway.com/deploy/easyimg) — Simple self-hostable Nuxt.js personal image hosting system.

Open this page in a browser: https://railway.com/deploy/tidb-cluster
