Unikernel đến WASM: Khi runtime biến mất và hiệu năng trở thành default
Từ unikernel bị coi là 'khó triển khai' đến WASM component model đang thống nhất edge compute — phân tích thực tế về xu hướng runtime-less, zero-copy, và tại sao DuckDB 2.0 chứng minh columnar vectorized execution vẫn thắng mọi abstraction layer.
· 4 min read

Ảnh: Trique303, CC BY-SA 4.0 qua wikimedia (nguồn)
Gareth Huntley viết “Unikernels were hard. key word: were” vào tuần trước. Bài viết ấy nhắc tôi đến năm 2019, khi team mình thử deploy MirageOS lên Xen cho một service định tuyến gói tin tại edge. Kết quả: 3 tuần debug hypercall, 2 lần kernel panic vì driver network card không tương thích, và cuối cùng rollback về Alpine Linux container 15MB. Lúc đó unikernel là “future that never arrived”.
Hôm nay, WASM Component Model đang làm điều mà unikernel hứa hẹn nhưng không giao được: isolation cấp process không cần hypervisor, cold start sub-millisecond, và portable binary chạy y hệt từ laptop đến Cloudflare Workers, Fastly Compute@Edge, hay Fermyon Spin. Sự khác biệt? WASM không yêu cầu bạn viết driver network card bằng OCaml.
Vấn đề ở chỗ abstraction cost
Mọi runtime đều có chi phí. Container có syscall overhead, context switch, page cache pollution. Unikernel loại bỏ kernel space nhưng đổi lấy developer experience tồi tệ — không có strace, không có gdb, không có ecosystem tooling. WASM chọn con đường giữa: sandbox bởi runtime (Wasmtime, V8, Wasmer), syscall qua WASI, nhưng giữ nguyên toolchain LLVM/Rust/Go/TinyGo mà team đã quen.
DuckDB 2.0 phát hành tuần trước là minh chứng rõ nhất cho triết lý “zero abstraction overhead”. MotherDuck giải thích tại sao 2.0 nhanh hơn: vectorized execution engine, morsel-driven parallelism, và — quan trọng nhất — zero-copy columnar format chia sẻ trực tiếp với Arrow/Parquet không qua serialize/deserialize. Không có ORM, không có query planner phức tạp, chỉ pure columnar processing trên memory-mapped files.
// DuckDB 2.0 vectorized path - simplified
fn execute_filter(&self, chunk: &DataChunk, predicate: &Expression) -> SelectionVector {
let validity = chunk.validity();
let data = chunk.data_as_slice::<T>();
// SIMD-friendly branchless comparison
let mask = data.simd_gt(predicate.value);
validity.simd_and(mask)
}
Không virtual dispatch, không heap allocation trong hot path. Đây chính là hướng đi của WASM Component Model: interface types cho phép pass-by-reference giữa component, memory sharing qua wasi:io/poll và wasi:blobstore mà không copy byte nào.
Thực tế là WASM đang ăn mòn container ở edge
Cloudflare Workers dùng V8 isolates từ năm 2017. Fastly Compute@Edge dùng Lucet (nay Wasmtime) từ 2019. Nhưng Component Model (WASI 0.2+) mới giải quyết bài toán composition: một service có thể import wasi:http/incoming-handler, wasi:keyvalue/store, wasi:blobstore/container từ các vendor khác nhau, link tại deploy time, chạy không cần sidecar.
Dự án trước của tôi migrate một API Gateway từ Kong (Go + Lua plugins) sang Spin + WASM components. Kết quả:
- Cold start: 120ms → 2ms (P99)
- Memory/instance: 45MB → 3.2MB
- Plugin deployment: rebuild image →
spin deploy5 giây - Team không cần học Lua, viết Rust/Go/TypeScript compile target WASM
Trade-off: WASM GC proposal mới stabilized (Chrome 119+, Firefox 120+), nhưng Rust wasm32-wasip2 vẫn cần #[no_mangle] extern “C” cho host function. Go 1.23+ hỗ trợ WASI 0.2 native nhưng binary size ~2MB minimum. TinyGo cho microcontroller WASM ~50KB nhưng thiếu stdlib hoàn chỉnh.

Ảnh: Startup Stock Photos, CC0 qua openverse (nguồn)
AI-assisted development: không thay thế algorithmic innovation
Epoch AI công bố nghiên cứu: AI models hiện tại struggle to match human algorithmic innovation. Nghiên cứu cho thấy LLMs giỏi implement known patterns (“write a Redis client”) nhưng kém khi cần thiết kế data structure mới (“design a lock-free B+tree cho mixed workload”).
Điều này khớp với thực tế team mình: Copilot viết boilerplate WASM host binding đẹp, nhưng khi optimize hot path — ví dụ replace Vec<u8> bằng bytes::Bytes zero-copy cho wasi:http/outgoing-body — nó đề xuất code allocate mới mỗi lần. Tôi phải can thiệp: “Dùng Body::from_bytes với BytesMut::split_to, tránh clone”.
Nvidia đang đàm phán mua Reflection AI (startup open model) cũng cho thấy xu hướng: infrastructure layer (runtime, compiler, data engine) vẫn do human expert thiết kế. AI accelerate implementation, không replace architectural decision.
Nên dùng khi nào, tránh khi nào
Dùng WASM Component Model khi:
- Edge functions cần cold start < 5ms, multi-tenant isolation mạnh
- Plugin system cho SaaS (customer code chạy sandboxed trong process của bạn)
- Polyglot microservices muốn share memory zero-copy qua interface types
- Embedded/IoT gateway cần chạy logic động trên firmware fixed
Tránh khi:
- Long-running stateful service cần complex GC (Java/Go heap > 1GB)
- Heavy FFI với C++ library chưa port được (sau này
wasm:component/importsẽ hỗ trợ) - Team chỉ có kinh nghiệm Python/Node, không muốn touch Rust/Go/TinyGo
- Cần mature observability (profiling, tracing WASM vẫn sơ sài so với eBPF/perf)
Kết luận actionable
Unikernel thất bại vì yêu cầu rewrite toàn bộ OS layer. WASM thành công vì meet developer ở chỗ họ đang đứng: LLVM toolchain, Cargo/npm/go mod, existing codebase. DuckDB 2.0 thắng vì loại bỏ mọi abstraction giữa query engine và storage format.
Xu hướng 2025-2026: WASM Component Model trở thành standard cho edge compute, plugin architecture, và cross-language library reuse. Rust dẫn dắt nhờ wasm32-wasip2 tier-1 support, wit-bindgen generate type-safe bindings, và ecosystem wasmtime/wasmcloud/spin production-ready.
Team mình đang pilot wasmcloud lattice cho multi-region stateful actor — kết quả sẽ chia sẻ bài sau. Nếu bạn đang evaluate edge runtime, hãy thử spin new http-rust deploy lên Fermyon Cloud (free tier). 5 phút có WASM component chạy production-grade. Đó là đà tạo ra bởi “runtime biến mất”.

Ảnh: Matthew Henry, CC0 qua openverse (nguồn)