Tutorial Optimasi Query Analitik dengan DuckDB Asynchronous I/O
AW
Axel W

Dipublikasikan 16 Agustus 2026

Tutorial Optimasi Query Analitik dengan DuckDB Asynchronous I/O

DuckDB telah menjadi pilihan utama untuk analitik lokal berkat kemampuannya memproses data besar dengan cepat langsung dari laptop. Namun sejak adopsi data lake dan remote storage seperti S3 meningkat, bottleneck bergeser dari CPU ke I/O. Artikel ini membahas fitur asynchronous I/O yang akan hadir di DuckDB v2.0 dan bagaimana kamu bisa memanfaatkannya untuk query remote data hingga 3,7 kali lebih cepat. Konten ini diadaptasi dari pengumuman resmi DuckDB blog.

1. Memahami Masalah Synchronous I/O

Secara default, DuckDB membaca file secara sinkron. Thread worker meminta data dan menunggu response datang sebelum melanjutkan decoding atau agregasi. Di local SSD, latensinya sangat rendah sehingga ini bukan masalah. Tapi di setup cloud seperti EC2 dengan S3, thread bisa menghabiskan sebagian besar waktunya menunggu response HTTP daripada bekerja. Ketika thread terblokir, CPU core menjadi idle padahal masih ada banyak data yang perlu diproses.

Tim DuckDB memberikan contoh konkret pada query FROM read_parquet('s3://bucket/file.parquet'). Parquet scan dipecah menjadi row group jobs. Tiap job punya fetch task yang mengirim byte-range request. Dengan I/O sinkron, worker thread blocked sampai data tiba. Kalau bandwidth jaringan 25 Gbit/s tapi hanya satu request yang outstanding, throughput nyata bisa jauh di bawah potensi. Solusinya bukan menambah CPU, melainkan menjaga lebih banyak request I/O berjalan secara paralel.

2. Mengaktifkan Asynchronous I/O di DuckDB

DuckDB v2.0 memperkenalkan dua thread pool terpisah yang dikelola oleh task scheduler:

  • REGULAR pool: thread worker untuk decoding, join, agregasi. Defaultnya satu per CPU thread.

  • ASYNC pool: thread khusus untuk blocking I/O. Defaultnya 4 * system threads, maksimal 256 thread.

ASYNC thread hampir selalu blocked menunggu HTTP response, sehingga CPU utilization-nya rendah. Memisahkan pool ini memastikan worker thread tidak terhenti oleh I/O. Konsep ini mirip dengan thread pool di web server seperti Nginx atau Tomcat, di mana thread I/O dipisahkan dari thread bisnis logic.

-- Cek versi DuckDB
SELECT version();

-- Async I/O aktif secara default di v2.0
-- Untuk preview build:
-- https://duckdb.org/install/preview

Kamu bisa mengunduh preview build DuckDB v2.0.0-dev dari halaman official preview. Fitur ini akan digunakan secara default saat rilis stabil nanti. Preview build cocok untuk eksperimen di staging environment sebelum migrasi produksi.

3. Konfigurasi Read-Ahead Depth

Konsep utama async I/O di DuckDB adalah read-ahead. Daripada membaca tepat saat worker butuh data, ASYNC thread mengambil data untuk job berikutnya sambil worker memproses job saat ini. Tujuannya: selalu ada fetch task yang in-flight sehingga latensi remote storage tersembunyi di balik pekerjaan CPU.

Read-ahead dikontrol melalui parameter read_ahead_depth:

  • -1 (default): unlimited depth, dibatasi oleh memory manager.

  • N > 0: maksimal N job di queue, tanpa memory budget.

  • 0: read-ahead dimatikan, tiap scan task hanya schedule I/O untuk job-nya sendiri.

-- Set read-ahead depth ke 5 job
SET read_ahead_depth = 5;

-- Atur jumlah async thread jika perlu tuning manual
SET async_threads = 48;

Perlu diperhatikan: read-ahead menggunakan memori untuk menampung data yang sudah di-fetch tapi belum didekode. Jika decoding lambat dan jaringan cepat, data prefetch bisa menumpuk dan memicu out-of-memory. DuckDB menangani ini dengan asynchronous memory governance yang bernegosiasi dengan temporary memory manager yang sama mengatur join, sort, dan window operators. Ketika ada operator besar yang memakan banyak RAM, queue read-ahead otomatis mengecil hingga hanya satu job.

4. Benchmark Parquet dari S3

Benchmark menggunakan TPC-H Query 6 pada skala SF100 dengan tabel lineitem sekitar 600 juta baris. Dataset disimpan di S3 sama region dengan EC2 r7i.16xlarge (64 vCPU, 512 GB RAM). File Parquet sekitar 22 GB dengan 4.880 row groups. Eksekusi dilakukan lima kali dan diambil rata-rata. File tidak di-cache, artinya setiap eksekusi benar-benar membaca dari S3.

Versi DuckDBRuntime Q6
v1.5.5 (synchronous)8.230 s
v2.0.0-dev (async default)2.844 s
v2.0.0-dev (async tuned)2.227 s

Versi tuned menambahkan konfigurasi: async_threads = 48, http_retries = 8, http_retry_wait_ms = 50, dan http_retry_backoff = 2. Dengan lebih sedikit koneksi yang lebih aktif dan retry murah, variance throughput turun hingga minimum dan jaringan 25 Gbit/s hampir fully saturated. Waktu eksekusi turun 21,7% dibanding default async, dan 3,7 kali lebih cepat dibanding v1.5.5.

v1.5.5 hanya mencapai sekitar 5 Gbit/s karena synchronous reads tidak bisa menjaga cukup request in-flight untuk memenuhi bandwidth. Grafik network throughput dari DuckDB blog memperlihatkan dengan jelas bagaimana v2.0 mendekati limit jaringan sementara v1.5.5 stagnan di level rendah.

5. Menerapkan Async I/O di Pipeline Produksi

Berikut langkah-langkah konkret untuk migrasi pipeline analitik kamu:

  1. Audit query bottleneck: jalankan EXPLAIN ANALYZE pada query lambat. Jika waktu I/O mendominasi, async I/O akan membantu.

  2. Update ke v2.0 preview: unduh dari DuckDB preview builds.

  3. Verifikasi setup remote: pastikan endpoint S3 atau blob storage berada di region yang sama dengan compute. Latensi antar-region bisa menghilangkan manfaat async I/O.

  4. Tune read_ahead_depth: mulai dari default (-1). Jika memory pressure tinggi karena operator besar, turunkan ke nilai fixed seperti 32 atau 64.

  5. Monitor throughput: bandingkan network utilization sebelum dan sesudah. Targetnya adalah mendekati bandwidth theoretical maksimum.

Dukungan async I/O saat ini tersedia untuk Parquet dan CSV uncompressed yang seekable. Format native DuckDB dan JSON masih dalam pengembangan. Untuk CSV, tiap job mencakup fixed byte range, dan fetch task mengambil buffer awal serta buffer lanjutan saat boundary tercapai. Quack protocol yang diperkenalkan Mei 2026 juga mendukung mode server-remote, menjadikan async I/O semakin relevan untuk arsitektur modern.

Async I/O bukan magic bullet. Ini adalah optimasi untuk scenario di mana latensi remote storage menghambat throughput. Jika data kamu masih di lokal SSD, manfaatnya minimal. Tapi untuk arsitektur modern data lake dengan compute-storage separation, fitur ini bisa menjadi pembeda antara pipeline yang lamban dan yang responsif. Evaluasi workload-mu dan mulai eksperimen dengan preview build sebelum rilis stabil v2.0 di musim gugur 2026.