blog.dopana

Back

Railway Serverless là tính năng tự động scale to zero — service ngủ khi không hoạt động, wake khi có request.

Không Serverless:  Service chạy 24/7 → trả tiền 24/7
Có Serverless:     Service ngủ khi idle → chỉ trả khi chạy
plaintext

Kết quả: giảm chi phí đến 90% cho staging, dev, API ít traffic.

Cách Hoạt Động#

Railway phát hiện inactivity qua outbound traffic:

Service chạy → 10 phút không có outbound packets → Ngủ
Service ngủ  → Có request từ internet/private network → Wake
plaintext

Outbound Traffic là gì?#

Bất kỳ packet nào từ service ra ngoài:

# Gọi API bên ngoài → outbound → service không ngủ
curl https://api.example.com

# Kết nối database → outbound → service không ngủ
psql -h db.railway.internal ...

# NTP sync → outbound → service không ngủ
# Telemetry (Next.js, Sentry, ...) → outbound → service không ngủ
bash

Inbound Traffic#

Railway chỉ dùng outbound để detect inactivity. Request từ internet vào không tính là activity cho việc ngủ.

Inbound request → KHÔNG reset inactivity timer
Outbound request → CÓ reset inactivity timer
plaintext

Wake#

Khi service ngủ, request đầu tiên sẽ wake nó. Có thể mất vài giây (cold boot).

Khi Nào Nên Dùng#

✅ Nên dùng#

  • Staging / Preview — không cần chạy 24/7
  • API ít traffic — vài request/ngày
  • Bot / Cron job — chạy theo lịch
  • Development — personal project, demo
  • Background worker — không real-time

❌ Không nên#

  • Production API cần response nhanh — cold boot >502
  • WebSocket / real-time — cần kết nối liên tục
  • Database — không support serverless (cần chạy 24/7)
  • Service có cron job trong container — không chạy khi ngủ

Enable#

# Railway Dashboard
Service Settings Deploy Serverless Toggle On
bash

Apply cho tất cả replicas. Có thể toggle bất kỳ lúc nào.

Cold Boot#

Khi service ngủ, request đầu vào wake nó:

Request → Railway wake → Build/Start → Response

          ~1-5 giây (tuỳ service size)
plaintext

502 Bad Gateway#

Request đầu tiên đến service đang ngủ có thể trả về 502:

Client:   GET /api/data
Railway:  Service đang ngủ → wake
          Client nhận 502 (timeout chờ wake)
          Service wake xong → request tiếp theo OK
plaintext

Giải pháp: retry từ client.

async function fetchWithRetry(url: string, retries = 3) {
  for (let i = 0; i < retries; i++) {
    try {
      const res = await fetch(url)
      if (res.ok) return res
    } catch (e) {
      if (i === retries - 1) throw e
      await new Promise(r => setTimeout(r, 1000 * (i + 1)))
    }
  }
}
typescript

Hoặc dùng keep-alive ping để service không ngủ:

# Cron job ping mỗi 5 phút — service không bao giờ ngủ
*/5 * * * * curl https://my-service.railway.app/health
bash

Cost Savings#

ScenarioKhông ServerlessCó Serverless
Staging (chạy 24/7)$5/ngày~$0.50/ngày
Dev API (100 req/ngày)$3/ngày~$0.10/ngày
Production (10k req/ngày)$5/ngày$3/ngày (ít savings)

Càng ít traffic, savings càng lớn.

Keep Service Awake#

Nếu muốn service không ngủ nhưng vẫn enable Serverless:

// Ping internal network mỗi 5 phút
// Railway coi private network traffic là outbound
setInterval(async () => {
  await fetch('http://other-service.railway.internal/health')
}, 5 * 60 * 1000)
typescript

Hoặc disable Serverless nếu cần uptime 24/7.

Use Cases#

Staging Environment#

# railway.json
{
  "environments": {
    "production": {
      "serverless": false
    },
    "staging": {
      "serverless": true
    }
  }
}
yaml

Staging chỉ chạy khi dev push PR và test. Tiết kiệm ~80% chi phí staging.

Preview Deployments#

Mỗi PR → preview deployment với Serverless. Chạy khi review, ngủ khi không ai dùng.

API Bot#

# Telegram bot, Discord bot — chỉ chạy khi có message
# Serverless: ngủ khi không ai chat
bash

Cron Job#

# Service chạy theo lịch, wake nhờ cron trigger
# Railway cron + Serverless: service wake, run, sleep
bash

Giới Hạn#

  • Slot consumption: Service ngủ vẫn chiếm slot infrastructure
  • De-prioritized workload: Service ngủ có thể bị ưu tiên thấp hơn
  • Rebuild cần thiết: Trường hợp remote, có thể cần rebuild để wake
  • Cold boot delay: Request đầu có thể 502
  • 10 phút inactivity: Không config được threshold

So Sánh#

Railway ServerlessAWS LambdaCloudflare Workers
Cold boot~1-5s~100-500ms~0ms (isolate)
Max timeoutKhông giới hạn15 phút30s (free), 15 phút (paid)
LanguageAny (Docker)Node, Python, Java, Go…JS/TS, Wasm
Persistent storage✅ Volumes❌ (EFS chậm)❌ (KV, R2)
StateGiữa các requestStatelessStateless
PricingRAM/CPU usage + egressRequest + durationRequest + CPU time

Railway Serverless phù hợp cho full backend service cần persistent storage, bất kỳ ngôn ngữ nào, không bị timeout — nhưng cold boot lâu hơn.

Tổng Kết#

Railway Serverless là giải pháp scale-to-zero đơn giản nhất — toggle một nút, không config, không code change.

# Trước: trả $150/tháng cho staging chạy 24/7
# Sau: toggle Serverless → $15/tháng
bash
Ưu điểmNhược điểm
Zero config — toggle 1 nútCold boot ~1-5s
Giảm cost 80-90%Request đầu có thể 502
Wake tự độngKhông cho service real-time
Any language, any framework10 phút inactivity threshold fixed
Persistent volumeVẫn chiếm slot

Serverless là tính năng tiết kiệm nhất cho staging, dev, và API ít traffic. Cho production traffic cao, không cần bật.

Tài liệu tham khảo#