Node.js chạy JavaScript trên một thread duy nhất, nhưng vẫn xử lý được nhiều request đồng thời nhờ cơ chế non-blocking I/O và event loop. Khi có tác vụ I/O (đọc file, gọi database, HTTP request), Node.js giao cho libuv xử lý trong thread pool riêng và tiếp tục nhận request mới. Khi tác vụ I/O hoàn thành, callback được đưa vào event queue và event loop sẽ đẩy lên call stack khi stack trống.
Tuy nhiên, nếu có tác vụ tính toán nặng (CPU-intensive) thì sẽ block main thread, lúc này cần dùng Worker Threads để chạy song song.