API Rate Limit Là Gì? Cách Xử Lý Giới Hạn API Trong Vnstock

Bạn đang chạy chương trình phân tích dữ liệu chứng khoán Việt Nam thì bỗng dưng gặp báo lỗi "RateLimitExceed: Bạn đã gửi quá nhiều request đến VCI1. Vui lòng thử lại sau 15 giây." sau đó chương trình tự thoát thì đây là bài viết dành cho bạn.
I. API2 Rate Limit là gì?
Các loại API Rate Limit phổ biến
- Rate limit theo thời gian:
- Request/giây (RPS)
- Request/phút (RPM)
- Request/giờ (RPH)
- Request/ngày (RPD)
- Rate limit theo nguồn:
- Theo IP
- Theo tài khoản/API key
- Theo ứng dụng
- Rate limit theo endpoint:
- Giới hạn khác nhau cho từng endpoint cụ thể
- Giới hạn chung cho toàn bộ API
Cách nhận biết khi đạt giới hạn request của API
Khi đạt đến giới hạn request hay Rate Limit, API thường trả về mã lỗi HTTP 4293 cùng với thông báo lỗi cụ thể. Nhiều API còn cung cấp thông tin trong header response4 về số request còn lại, thời gian đợi trước khi có thể gọi lại API, v.v.
II. API Rate Limit của thư viện vnstock
vnstock là thư viện Python mã nguồn công khai theo giấy phép riêng, cung cấp các công cụ truy xuất và phân tích dữ liệu chứng khoán Việt Nam từ nguồn bên thứ ba.
Khi vnstock phát hiện chương trình của bạn dùng vòng lặp gửi yêu cầu dồn dập tới nguồn, một cảnh báo sẽ xuất hiện. Chương trình vẫn chạy tiếp cho tới khi chạm hạn mức thì dừng lại.
Trong môi trường dòng lệnh (Terminal/Command Prompt), thông báo hiện ra dưới dạng văn bản, kèm gợi ý giãn thời gian chờ giữa các yêu cầu.
Giới hạn hiện tại của vnstock
Tại thời điểm viết bài (04/2025), vnstock áp dụng các giới hạn khi gửi yêu cầu dữ liệu như sau:
- 60 requests/phút
- 3000 requests/giờ
Hạn mức này giữ tải ở mức hợp lý với nguồn. Khi số lượt yêu cầu chạm hạn mức, chương trình tự động dừng và hiển thị thông báo lỗi. Đây là tín hiệu chương trình đang dồn quá nhiều yêu cầu tới nguồn trong thời gian ngắn, nên giãn nhịp gửi, lưu dữ liệu cục bộ và chỉ lấy phần bạn thật sự cần.
Thông báo lỗi API Rate Limit
III. Vì sao vnstock áp dụng API Rate Limit?
Có nhiều lý do khiến việc áp dụng cơ chế Rate Limit là cần thiết cho một dự án và nhất là với dự án cộng đồng như vnstock:
1. Giữ tải ở mức hợp lý với nguồn
Truy vấn đi thẳng từ máy của bạn tới nguồn bên thứ ba. Hạn mức là đơn vị kỹ thuật để giữ tải ở mức hợp lý với nguồn, giúp chương trình của bạn chạy ổn định hơn thay vì dồn quá nhiều yêu cầu trong thời gian ngắn.
2. Sử dụng nguồn truy cập công khai có trách nhiệm
Cơ chế Rate Limit hạn chế việc gửi yêu cầu liên tục tới nguồn bên thứ ba, giúp kết nối giữa công cụ phân tích của bạn và nguồn ổn định hơn.
3. Phân bổ nguồn lực hiệu quả
Vnstock là dự án mã nguồn công khai theo giấy phép riêng, được thiết kế để hỗ trợ cộng đồng làm quen với Python và phân tích dữ liệu tài chính cho nhu cầu cá nhân. Hạn mức mặc định được đặt vừa đủ cho nhu cầu đó, đồng thời giữ tổng lưu lượng từ cộng đồng người dùng ở mức hợp lý với nguồn.
4. Hạn chế truy cập bất thường
API Rate Limit cũng hạn chế các mẫu truy cập bất thường, chẳng hạn vòng lặp gửi yêu cầu liên tục không kiểm soát, vốn có thể bị nhìn nhận giống lưu lượng tấn công từ chối dịch vụ (DDoS)5.
IV. Năm cách làm việc trong hạn mức
Khi làm việc với vnstock API, bạn có thể áp dụng một số cách sau để chương trình chạy ổn định trong hạn mức và giữ tải hợp lý với nguồn:
1. Bổ sung thời gian nghỉ giữa các requests
Đây là phương pháp đơn giản nhất, thêm thời gian nghỉ (delay) giữa các lần gọi API để giãn nhịp gửi yêu cầu khi bạn dùng vòng lặp tải dữ liệu cho nhiều mã.
import time
from tqdm import tqdm
from vnstock import Vnstock
stock = Vnstock().stock(symbol='ACB', source='VCI')
# Truy xuất danh sách mã trong VN100
vn100 = stock.listing.symbols_by_group('VN100')
# Chỉ giữ lại những mã bạn thật sự theo dõi; dữ liệu đã tải nên lưu lại để dùng lại
# Tạo vòng lặp tải dữ liệu, sử dụng tqdm[^7] hiển thị tiến độ
for symbol in tqdm(vn100, desc='Processing VN100 symbols'):
df = stock.quote.history(symbol=symbol, start='2024-01-01', end='2024-12-31')
df['symbol'] = symbol
print(df)
# nghỉ 1s trước khi chuyển sang mã tiếp theo
time.sleep(1)- Ưu điểm: Dễ thực hiện.
- Nhược điểm: Chương trình chạy lâu hơn, đổi lại tải lên nguồn đều đặn. Độ trễ cố định (hard delay) chưa thích ứng được với tốc độ phản hồi thực tế của từng request, có thể kết hợp thêm cách ở mục 5.
2. Chọn nguồn phù hợp với loại dữ liệu
Chọn nguồn phù hợp với loại dữ liệu cần truy vấn giúp bạn dùng hạn mức hiệu quả hơn.
- Với dữ liệu lịch sử OHLCV6 kéo dài nhiều năm, một số nguồn cần nhiều yêu cầu phụ hơn để ghép đủ khoảng thời gian, nên tổng số lượt gọi tăng lên.
- Chỉ truy vấn đúng khoảng thời gian và loại dữ liệu bạn cần thay vì tải lại toàn bộ.
3. Thiết lập bộ đếm để giữ nhịp gọi trong hạn mức
Phương pháp này giúp theo dõi số lượng request đã gửi và tự động giãn nhịp gọi API. Bạn có thể tạo một bộ đếm đơn giản để theo dõi số lượng request và tự động tạm dừng khi gần chạm hạn mức.
Nguyên tắc hoạt động:
-
Theo dõi số lượng request đã thực hiện trong 1 phút
-
Nếu gần chạm hạn mức, tự động đợi trước khi tiếp tục
-
Reset bộ đếm sau mỗi phút
-
Ưu điểm: Quản lý request chủ động, tối ưu hóa thời gian chờ
-
Nhược điểm: Cần thêm logic để quản lý bộ đếm
4. Sử dụng caching để giảm số lượng request
Lưu trữ kết quả API để tránh gọi lại những dữ liệu đã lấy trước đó.
Nguyên tắc hoạt động:
-
Lưu kết quả vào file hoặc bộ nhớ sau khi gọi API
-
Kiểm tra cache trước khi gọi API
-
Chỉ gọi API khi dữ liệu không có trong cache hoặc đã hết hạn
-
Ưu điểm: Giảm đáng kể số lượng request, tối ưu hiệu suất trong dài hạn
-
Nhược điểm: Dữ liệu có thể không phải là mới nhất khi lấy từ cache
5. Sử dụng thuật toán Exponential Backoff7
Phương pháp này tăng dần thời gian chờ sau mỗi lần gặp lỗi Rate Limit.
Nguyên tắc hoạt động:
-
Bắt đầu với thời gian chờ ngắn (ví dụ: 1 giây)
-
Khi gặp lỗi Rate Limit, tăng thời gian chờ theo cấp số nhân
-
Thử lại request sau thời gian chờ
-
Thêm yếu tố ngẫu nhiên để tránh đồng bộ hóa giữa các client
-
Ưu điểm: Xử lý lỗi tự động, thích ứng với điều kiện mạng và tải hệ thống
-
Nhược điểm: Có thể mất nhiều thời gian hơn nếu gặp nhiều lỗi liên tiếp
V. Bản Mở rộng dành cho người tài trợ
Lợi ích khi tham gia tài trợ
- Thư viện bản Mở rộng: Dùng thêm các thư viện như
vnstock_datavới lớp chuẩn hoá dữ liệu, bộ lọc nâng cao và tài liệu đi kèm. - Ưu tiên hỗ trợ: Được hỗ trợ ưu tiên khi gặp vấn đề trong quá trình sử dụng.
- Hạn mức cao hơn: Hạn mức và lượt quy đổi là đơn vị kỹ thuật để giữ tải ở mức hợp lý với nguồn, không phải dữ liệu bán theo đơn vị.
- Đóng góp cho dự án: Giúp duy trì việc phát triển, bảo trì thư viện và các tính năng mới cho cộng đồng.
VI. Câu hỏi thường gặp
Tôi có thể tự nâng hạn mức trong mã nguồn không?
Không nên. Hạn mức là lan can kỹ thuật giữ tải ở mức hợp lý với nguồn, và Vnstock không thiết kế hay hỗ trợ cách né hạn mức. Cách hiệu quả là điều tiết lưu lượng: đặt khoảng nghỉ giữa các request, lưu dữ liệu cục bộ để dùng lại và chỉ cập nhật phần dữ liệu mới.
Làm sao để biết tôi đã sử dụng bao nhiêu request?
Hiện tại, Vnstock chưa hỗ trợ tính năng xem trực tiếp số lượng request đã gọi trong phiên. Bạn nên chủ động ghi log hoặc xây dựng bộ đếm thời gian trong ứng dụng của mình để theo dõi và điều chỉnh tần suất cho phù hợp.
Tôi bị rate limit dù chỉ gửi rất ít request?
Có thể do ứng dụng của bạn gọi các hàm khác nhau nhưng chúng đều truy vấn dữ liệu từ cùng một nguồn ẩn dưới nền, dẫn đến tổng số request cộng dồn đạt giới hạn cho phép.
Footnotes
-
VCI: Công ty Cổ phần Chứng khoán Vietcap (trước đây là Chứng khoán Bản Việt). ↩
-
API (Application Programming Interface): Giao diện lập trình ứng dụng, phương thức kết nối để các phần mềm giao tiếp với nhau. ↩
-
HTTP 429 (Too Many Requests): Mã phản hồi tiêu chuẩn của giao thức HTTP cho biết máy khách đã gửi quá nhiều yêu cầu trong một khoảng thời gian cho phép. ↩
-
Response Header (Tiêu đề phản hồi HTTP): Phần chứa siêu dữ liệu (metadata) được máy chủ gửi kèm trong phản hồi HTTP, cung cấp thông tin phụ về phản hồi như kiểu dữ liệu, độ dài, trạng thái giới hạn request (rate limit), v.v. ↩
-
DDoS (Distributed Denial of Service): Tấn công từ chối dịch vụ phân tán, phương thức làm nghẽn lưu lượng truy cập của máy chủ bằng cách gửi lượng yêu cầu khổng lồ từ nhiều nguồn. ↩
-
OHLCV: Định dạng dữ liệu tài chính cơ bản gồm giá Mở cửa (Open), Cao nhất (High), Thấp nhất (Low), Đóng cửa (Close) và Khối lượng giao dịch (Volume). ↩
-
Exponential Backoff: Thuật toán giảm tải bằng cách tăng dần thời gian chờ sau mỗi lần gửi yêu cầu thất bại theo cấp số nhân (ví dụ: 1s, 2s, 4s, 8s...). ↩