1---
2title: MySQL
3description: Official MySQL in a Project. Bind Railway.ConnectMySQL and query with Drizzle or SQL.
4---
5
6A [`Railway.MySQL`](/providers/railway/mysql) is MySQL as a Service:
7the official `mysql:9` image, a Volume at `/var/lib/mysql`, `MYSQL_*`
8/ `MYSQL_URL` variables, and an optional TCP proxy for the public URL.
9The IaC helper is `Railway.mysql`.
10
11Private hostname is `{name}.railway.internal`. From a
12[Service](/railway/compute/services), yield
13[`ConnectMySQL`](/providers/railway/connectmysql). From a laptop, use
14`publicConnectionUri`.
15
16## Create MySQL
17
18Pass a Project. Alchemy generates a unique name, password, volume,
19and a public TCP proxy.
20
21```typescript
22const site = yield* Railway.Project("Site");
23const db = yield* Railway.MySQL("Db", { project: site });
24```
25
26:::caution[Changing `project` replaces MySQL]
27A new service + volume are created in the new Project. The old
28service and volume are deleted. Data is not copied.
29:::
30
31## Connect from a Service
32
33Yield `ConnectMySQL` in the Service's constructor. Provide
34`ConnectMySQLHttp`. Pass `conn.connectionString` to Drizzle or SQL.
35
36```typescript
37import * as Drizzle from "alchemy/Drizzle/MySQL";
38import * as HttpServerResponse from "effect/http/HttpServerResponse";
39
40export default class Api extends Railway.Service<Api>()(
41 "Api",
42 {
43 project: Site,
44 main: import.meta.url,
45 build: { install: ["mysql2"] },
46 },
47 Effect.gen(function* () {
48 const conn = yield* Railway.ConnectMySQL(Db);
49 const db = yield* Drizzle.MySQL(conn.connectionString);
50 return {
51 fetch: Effect.gen(function* () {
52 const rows = yield* db.execute("select 1 as ok", "objects");
53 return HttpServerResponse.json({ rows });
54 }),
55 };
56 }).pipe(Effect.provide(Railway.ConnectMySQLHttp)),
57) {}
58```
59
60`connectionString` is the private URI
61(`{name}.railway.internal:3306`). Packed into the Service env — not
62`Config.Redacted`.
63
64To store Railway's `${{Db.MYSQL_URL}}` template instead of a
65resolved URI, pass [`Railway.ref`](/providers/railway/ref)
66(`Railway.ref(Db, "MYSQL_URL")`) as a
67[Variable](/railway/data/variables) `value`.
68
69## Public TCP
70
71`public` (default `true`) creates a TCP proxy on 3306.
72`publicConnectionUri` is `{domain}:{proxyPort}` for laptop access.
73
74```typescript
75const db = yield* Railway.MySQL("Db", {
76 project: site,
77 public: false,
78});
79```
80
81## Where next
82
83[Postgres](/railway/data/postgres) is the same shape for Postgres.
84[Mongo](/railway/data/mongo) is MongoDB.
85[TcpProxy](/railway/networking#tcp-proxies) is the public TCP
86resource.
87The [`MySQL` reference](/providers/railway/mysql) lists every prop.
88The [`ConnectMySQL` reference](/providers/railway/connectmysql) is
89the runtime binding.