---
title: "Deploy Citus | (Just Updated) Distributed Postgres 17, Extension Enabled, Data Survives Redeploys"
description: "Citus distributed PostgreSQL 17, extension on, generated password"
category: "Storage"
url: https://railway.com/deploy/citus-or-just-updated-distributed-postgr
---

# Deploy Citus | (Just Updated) Distributed Postgres 17, Extension Enabled, Data Survives Redeploys

Citus distributed PostgreSQL 17, extension on, generated password

**[Deploy Citus | (Just Updated) Distributed Postgres 17, Extension Enabled, Data Survives Redeploys on Railway](https://railway.com/template/citus-or-just-updated-distributed-postgr)**

Machine-readable deploy manifest (JSON, validated by TemplateCI): https://railway.com/deploy/citus-or-just-updated-distributed-postgr/manifest.json

- **Creator:** SuperSlowSloth
- **Category:** Storage

## Template content

### citus

- **Image:** citusdata/citus:14.2.0-pg17@sha256:a8e720198e83d9f8bd3884a0aeb32aa1e2b426393fba96882587c9fe607d1417
- **Start command:** `/bin/sh -c 'eval "$(echo IyBDaXR1cyBib290OiBzaXplIFBvc3RncmVzIGZyb20gdGhlIGNvbnRhaW5lciBsaW1pdHMsIHRoZW4gaGFuZCBvdmVyIHRvIHRoZSBzdG9jayBlbnRyeXBvaW50Lgp1bnNldCBQR0hPU1QgUEdQT1JUIFBHVVNFUiBQR1BBU1NXT1JEIFBHREFUQUJBU0UKTT0kKGNhdCAvc3lzL2ZzL2Nncm91cC9tZW1vcnkubWF4IDI+L2Rldi9udWxsKTsgTT0ke006LW1heH0KWyAiJE0iID0gbWF4IF0gJiYgTT0yMTQ3NDgzNjQ4Ck1CPSQoKE0vMTA0ODU3NikpClNCPSQoKE1CLzQpKTsgWyAiJFNCIiAtbHQgMTI4IF0gJiYgU0I9MTI4CkVDPSQoKE1CKjMvNSkpOyBbICIkRUMiIC1sdCAyNTYgXSAmJiBFQz0yNTYKTVc9JCgoTUIvNSkpOyBbICIkTVciIC1sdCA2NCBdICYmIE1XPTY0OyBbICIkTVciIC1ndCAyMDQ4IF0gJiYgTVc9MjA0OApXTT0kKChNQi82NCkpOyBbICIkV00iIC1sdCA0IF0gJiYgV009NDsgWyAiJFdNIiAtZ3QgNjQgXSAmJiBXTT02NApzZXQgLS0gJChjYXQgL3N5cy9mcy9jZ3JvdXAvY3B1Lm1heCAyPi9kZXYvbnVsbCk7IFE9JHsxOi1tYXh9OyBQPSR7MjotMTAwMDAwfQppZiBbICIkUSIgPSBtYXggXTsgdGhlbiBDPTI7IGVsc2UgQz0kKChRL1ApKTsgZmkKWyAiJEMiIC1sdCAxIF0gJiYgQz0xClBNPSQoKEMvMikpOyBbICIkUE0iIC1sdCAxIF0gJiYgUE09MTsgWyAiJFBNIiAtZ3QgNCBdICYmIFBNPTQKZXhwb3J0IFBPU1RHUkVTX1VTRVI9cG9zdGdyZXMgUE9TVEdSRVNfREI9cmFpbHdheQplY2hvICJbcmFpbHdheV0gdWlkPSQoaWQgLXUpIG93bmVyPSQoc3RhdCAtYyAldTolZyAvdmFyL2xpYi9wb3N0Z3Jlc3FsKSBtZW09JHtNQn1NQiBjcHU9JEMgc2hhcmVkX2J1ZmZlcnM9JHtTQn1NQiBlZmZlY3RpdmVfY2FjaGVfc2l6ZT0ke0VDfU1CIG1haW50ZW5hbmNlX3dvcmtfbWVtPSR7TVd9TUIgd29ya19tZW09JHtXTX1NQiBkc209bW1hcCIKZXhlYyBkb2NrZXItZW50cnlwb2ludC5zaCBwb3N0Z3JlcyBcCiAgLWMgZHluYW1pY19zaGFyZWRfbWVtb3J5X3R5cGU9bW1hcCBcCiAgLWMgc2hhcmVkX2J1ZmZlcnM9JHtTQn1NQiAtYyBlZmZlY3RpdmVfY2FjaGVfc2l6ZT0ke0VDfU1CIFwKICAtYyBtYWludGVuYW5jZV93b3JrX21lbT0ke01XfU1CIC1jIHdvcmtfbWVtPSR7V019TUIgXAogIC1jIG1heF93b3JrZXJfcHJvY2Vzc2VzPSQoKEMrOCkpIC1jIG1heF9wYXJhbGxlbF93b3JrZXJzPSRDIFwKICAtYyBtYXhfcGFyYWxsZWxfd29ya2Vyc19wZXJfZ2F0aGVyPSRQTSAtYyBtYXhfcGFyYWxsZWxfbWFpbnRlbmFuY2Vfd29ya2Vycz0kUE0K | base64 -d)"'`

## Documentation

# Deploy and Host Citus on Railway

**Built for an LLM agent to deploy and use.** There is no setup step and nothing to fill in: a 32-character password is generated at deploy time, a database named `railway` is created, and the `citus` extension is already enabled in it. The contract below lists every URL, variable name and the one script that proves it works.

Citus turns PostgreSQL into a distributed database: tables are split into shards by a distribution column, and queries, inserts and joins run in parallel across them. It is used for multi-tenant SaaS back ends, real-time analytics and any workload that outgrows one Postgres table. This template runs a single-node Citus, so it is a plain PostgreSQL 17 you can already call `create_distributed_table` on, and the same schema can later move to a multi-node cluster.

## About Hosting Citus

This template runs one service, `citus`, built from the official **Citus 14.2.0 on PostgreSQL 17** image (`citusdata/citus`, pinned by digest). The image preloads the `citus` library and creates the extension in the `railway` database on first boot. In single-node mode Citus keeps all 32 shards on this node, so `create_distributed_table` works with no worker nodes. The data volume is mounted at `/var/lib/postgresql` and PGDATA stays at its default subdirectory, so the `lost+found` folder Railway puts at the volume root never lands inside the data directory. The start command runs as root so the root-owned volume is writable and prints the user id and mount owner in the deploy log. `shared_buffers`, `effective_cache_size`, `work_mem` and the worker counts are computed from the container limits, not from the host's RAM. The database port is exposed on a Railway TCP proxy; services in the same project use the private address.

### Agent contract

- Public URL: none over HTTP. The database is reached on the TCP proxy as `DATABASE_URL` (host `RAILWAY_TCP_PROXY_DOMAIN`, port `RAILWAY_TCP_PROXY_PORT`).
- Private URL: `postgresql://postgres:@citus.railway.internal:5432/railway`, exposed as `DATABASE_PRIVATE_URL`.
- Credentials: user `postgres`, password in `POSTGRES_PASSWORD`, database `railway`.
- Auth: PostgreSQL password authentication (SCRAM-SHA-256) in the connection string. A wrong password is refused. The server does not offer TLS, so use the private URL for anything sensitive.
- Health: no HTTP health path (a TCP proxy and an HTTP healthcheck cannot share a service). Readiness is `pg_isready -d "$DATABASE_URL"` returning `accepting connections`, or a successful `psql "$DATABASE_URL" -c 'select 1'`.

```bash
# run with DATABASE_URL set; needs psql
until pg_isready -q -d "$DATABASE_URL"; do sleep 2; done
psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -At &lt;&lt;'SQL'
select 'citus ' || extversion from pg_extension where extname = 'citus';
drop table if exists agent_events;
create table agent_events (id bigint primary key, body text);
select create_distributed_table('agent_events', 'id');
insert into agent_events select g, 'event ' || g from generate_series(1, 100) g;
select 'rows ' || count(*) from agent_events;
select 'shards ' || count(*) from citus_shards where table_name = 'agent_events'::regclass;
SQL
```

A fresh deploy prints `citus 14.2-1`, `rows 100` and `shards 32`. Run it again and it prints the same, because the table is dropped first.

## Why Deploy Citus on Railway?

Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.

By deploying Citus on Railway, you are one step closer to supporting a complete full-stack application with minimal burden. Host your servers, databases, AI agents, and more on Railway.

- **Agent-ready** - generated password, contract block and one working script; no setup step.
- **Extension on from the first boot** - `create_distributed_table` works immediately, with no `CREATE EXTENSION` and no worker nodes.
- **One service** - a single node you can deploy, pay for and redeploy, instead of a coordinator plus workers.
- **State survives redeploys** - the volume is mounted one level above PGDATA, so the data directory is never polluted by `lost+found`.
- **Right-sized** - Postgres memory and worker settings come from the container limits.
- **Pinned image** - the Citus and PostgreSQL versions are pinned, so a redeploy never changes the server underneath you.

## Common Use Cases

- **Multi-tenant SaaS** - distribute every table by tenant id and keep one tenant's rows together.
- **Real-time analytics** - parallel aggregation over large event tables with plain SQL.
- **A Postgres that can grow** - start on one node and keep the same schema when you add workers later.

## Dependencies for Citus Hosting

- One Railway volume for the data directory (created by the template).

### Deployment Dependencies

- [Citus documentation](https://docs.citusdata.com/)
- [Official image](https://hub.docker.com/r/citusdata/citus)
- [citusdata/citus](https://github.com/citusdata/citus) - upstream project

### Implementation Details

| Variable | Purpose |
| --- | --- |
| `POSTGRES_PASSWORD` | Password of the `postgres` user, generated per deploy. |
| `DATABASE_PRIVATE_URL` | Connection string on the private network, for services in the same project. |
| `DATABASE_URL` | Connection string on the TCP proxy, for clients outside Railway. |


## Similar templates

- [RustFS | (Just Updated) S3 Object Store, Public URL and Keys Set](https://railway.com/deploy/rustfs-or-just-updated-s3-object-store-p) — S3-compatible object store, keys and public URL preset, volume kept
- [TimescaleDB](https://railway.com/deploy/timescaledb-railway-template) — A PostgreSQL-based time-series database for analytics on Railway.
- [Garage S3 Storage](https://railway.com/deploy/garage-s3-storage) — Ultra-light S3 server: fast, open-source, plug-and-play.

Open this page in a browser: https://railway.com/deploy/citus-or-just-updated-distributed-postgr
