+1

Postgres là tất cả những gì bạn cần

Khi tôi bắt đầu làm sản phẩm SaaS tiếp theo của mình, tôi quyết định đơn giản hóa mọi thứ trong tech stack.

Sản phẩm SaaS đầu tiên của tôi là một công cụ phân tích được xây dựng trên một hạ tầng khá phức tạp: Redis, Postgres, ClickHouse, Amazon SQS và nhiều thứ khác. Sự phức tạp đó phục vụ mục đích rất tốt, vì nó có nhiều yêu cầu đặc biệt. Nhưng với dự án mới, tôi thử thách bản thân đi theo hướng hoàn toàn ngược lại: Ưu tiên sự đơn giản trên hết.

Câu hỏi đặt ra là: Liệu tôi có thể vận hành toàn bộ một ứng dụng SaaS sẵn sàng cho sản xuất chỉ với Postgres không?

Câu trả lời là: Hoàn toàn có thể.

Sự phức tạp không phải là bạn của bạn (Ít nhất là lúc ban đầu)

Các sản phẩm giai đoạn đầu hiếm khi thất bại vì vấn đề mở rộng. Chúng thất bại vì quá phức tạp sớm và thiếu sự phù hợp với thị trường. Mỗi dịch vụ bên ngoài bạn thêm vào — Redis, BullMQ, Pinecone, SQS — đều kéo theo sự phức tạp, chi phí bảo trì, và các điểm dễ gặp lỗi.

Với dự án mới, tôi bám sát một nguyên tắc duy nhất:

Đừng giải quyết những vấn đề mà bạn chưa gặp phải.

Và cuối cùng thì Postgres đã giải quyết gần như mọi thách thức liên quan đến dữ liệu mà tôi có.

Sử dụng Postgres làm hàng đợi tác vụ

Kiến trúc hướng sự kiện rất tuyệt. Các hiệu ứng phụ được tách biệt, còn logic chính thì sạch sẽ. Thông thường, bạn sẽ cần dùng Redis và BullMQ hoặc các dịch vụ tương tự để làm điều đó.

Nhưng có cách đơn giản hơn:

Giới thiệu pg-boss

pg-boss là một hàng đợi tác vụ nhẹ, dựa trên PostgreSQL, sử dụng SELECT FOR UPDATE SKIP LOCKED. Nó hỗ trợ lập lịch công việc đáng tin cậy, retry, delay, và xử lý song song—không cần phụ thuộc vào dịch vụ bên ngoài. Tôi đã viết chi tiết về nó tại đây.

Tức là:

  • Không cần Redis
  • Ít thành phần cần vận hành
  • Dễ debug
  • Nếu sau này lưu lượng tăng mạnh? Bạn hoàn toàn có thể thêm Redis vào sau — khi thực sự cần.

Tìm kiếm Vector Với Postgres (Tạm biệt Pinecone)

UserJot có một số tính năng phụ thuộc vào tìm kiếm vector. Thông thường, bạn sẽ cần đến một cơ sở dữ liệu vector chuyên biệt như Pinecone hoặc Weaviate.

Thay vào đó, tôi dùng pgvector – một extension của PostgreSQL, cho phép thực hiện tìm kiếm vector ngay trong cơ sở dữ liệu:

SELECT id, title
FROM submissions
WHERE project_id = 'xyz'
ORDER BY embedding <-> $1
LIMIT 5;

Lợi ích:

  • Dữ liệu tập trung: Không cần tách biệt nhiều hệ thống
  • Join và filter dễ dàng: Kết hợp truy vấn vector với SQL truyền thống
  • Hạ tầng đơn giản: Không cần đồng bộ dữ liệu giữa các hệ thống

Nếu sau này cần mở rộng, việc chuyển sang cơ sở dữ liệu vector chuyên biệt cũng dễ dàng—nhưng thường là không cần thiết cho phần lớn ứng dụng SaaS.

Postgres như một Key-Value Store

Cần lưu trữ key-value cho token tạm thời, feature flag hay cấu hình?

Thông thường bạn sẽ nghĩ đến Redis. Nhưng một lần nữa, Postgres xử lý được việc này:

CREATE TABLE kv_store (
  key TEXT PRIMARY KEY,
  value TEXT,
  expires_at TIMESTAMP WITH TIME ZONE
);

-- Retrieve keys that haven't expired yet
SELECT * FROM kv_store
WHERE key = 'feature_flag'
AND (expires_at IS NULL OR expires_at > NOW());

Postgres xử lý việc này rất tốt, với thêm một số lợi ích:

  • Dữ liệu lưu trữ bền vững
  • Dễ thay đổi schema và migrate
  • Truy vấn linh hoạt

Với phần lớn các sản phẩm SaaS nhỏ và vừa (tức là nhỏ hơn mức Netflix), Postgres là đủ dùng.

Liệu nó có thể mở rộng không?

Chắc chắn có thể.

Postgres có khả năng scale theo chiều dọc rất tốt. Nó dễ dàng xử lý hàng triệu dòng dữ liệu, hàng nghìn truy vấn mỗi giây, và các truy vấn phức tạp. Phiên bản Postgres hiện đại hỗ trợ index nâng cao, caching, phân vùng và tối ưu hiệu suất.

Khi tôi nói “đủ cho sản phẩm nhỏ”, ý tôi là nhỏ so với các gã khổng lồ công nghệ. Thực tế, 99.9% các sản phẩm SaaS, kể cả những sản phẩm indie thành công, sẽ không bao giờ đẩy Postgres đến giới hạn của nó.

Và nếu bạn thật sự đạt tới quy mô đó? Xin chúc mừng! Khi đó bạn hoàn toàn có thể tách các phần cần thiết ra thành hệ thống riêng.

Kết luận

Hạ tầng của bạn nên phản ánh quy mô của vấn đề hiện tại, chứ không phải những vấn đề giả định trong tương lai.

Chọn sự đơn giản từ sớm giúp bạn:

  • Giảm phức tạp và chi phí hạ tầng
  • Tăng tốc độ phát triển
  • Dễ debug và bảo trì
  • Làm chủ hạ tầng
  • Thiết lập môi trường phát triển cục bộ dễ dàng
  • Dễ mở rộng khi cần

Sự phức tạp sẽ tìm đến bạn sớm muộn, nhưng một khi đánh mất sự đơn giản thì rất khó để lấy lại.

Hy vọng bài viết này sẽ giúp ích phần nào cho các bạn.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí