~/notes

Notes.

Quick thoughts, TILs, and observations from building mobile & backend systems.

AUG 2026
FlutterRustFFIPerformance

Making local key-value reads asynchronous (Future<T>) creates microtask queue hops and forces widget build methods into FutureBuilder or unnecessary state churn. With flutter_rust_bridge synchronous wire functions, in-memory cache hits in Rust return across the FFI boundary in microseconds with zero Future allocation overhead.

AUG 2026
SecurityCryptographyRust

Encrypting values with AES-256-GCM isn’t enough if you don’t bind the key name in the Authenticated Additional Data (AAD). Without AAD binding, an attacker with write access to the raw store could swap the ciphertext of user_role: "admin" into another user’s slot. Binding the key name to the AAD ensures the payload will fail authentication if decrypted under any other key.

AUG 2026
RustStorageArchitecture

Rewriting a full JSON or binary snapshot on every mutation scales with $O(N)$ data size and kills mobile flash storage with write amplification. An append-only Write-Ahead Log (WAL) makes every mutation $O(1)$ disk I/O. Pair it with an in-memory index for $O(1)$ reads, and run log compaction (compact()) lazily in the background.

JUL 2026
RustConcurrencySystems

In embedded storage engines, using a single Mutex over the entire state causes unnecessary read contention. Pairing RwLock<HashMap<K, V>> for concurrent multi-reader access with a focused Mutex<Wal> for serializing disk appends gives you thread-safe mutations without stalling concurrent cache hits.

JUL 2026
FlutterDartRustConcurrency

Dart isolates serialize and copy memory across message ports on separate event loops. When heavy computation or I/O occurs on the native side, spawning an OS thread in Rust and communicating back to Dart via StreamSink avoids isolate serialization overhead and keeps the Flutter UI thread completely unblocked.

JUN 2026
GoSystem Design

Circuit breakers beat blind retries when the downstream is already on fire. Fail fast, shed load, recover clean. Half-open state is the part everyone forgets to implement properly — without it you just DDOS yourself on recovery.

MAY 2026
FlutterRiverpod

Riverpod’s ref.listen is underrated for side-effects — stop cramming navigation and snackbars into build. Listen fires once per state change, not on every frame. Your widget tree will thank you.

APR 2026
Go

Go’s errors.Join finally made aggregating failures readable. Wrap with %w, join at the boundary, unwrap with errors.Is at the handler. No more string concatenation that swallows stack context.

MAR 2026
FlutterArchitecture

Server-driven UI pays off the moment product wants to A/B a flow without shipping a new build. The tax is a robust schema contract and a typed renderer on the client. Pay it once, win every sprint after.

FEB 2026
TestingFlutter

Growing SDK test coverage from 4% to 76% taught me one thing: start with the event dispatcher, not the UI. Dispatchers are pure functions with clear contracts — easy to test, impossible to skip. UI tests are flaky; logic tests are gold.

JAN 2026
GoSystem Design

gRPC shines on internal service communication — typed contracts, bi-directional streaming, and a fraction of the JSON overhead. REST still wins at the public boundary where you need browser support and human-readable payloads. Use both, know why.

DEC 2025
KotlinAndroid

Kotlin Channel vs SharedFlow — Channel is a queue with backpressure (good for work items), SharedFlow is a broadcast with replay (good for events). Mixing them up causes dropped UI events or unbounded queues. Know the difference before you pick.

NOV 2025
FlutterML

Face liveness with ML Kit: blink + smile + head-turn challenges cut spoofing attempts by ~65% in our KYC flow. The real gain wasn’t the challenges themselves — it was randomising the sequence so recorded videos can’t replay. Spoofers hate randomness.

OCT 2025
KafkaSystem Design

Kafka consumer group rebalances are the silent killer of throughput during deploys. Use session.timeout.ms and max.poll.interval.ms to tune how quickly the group detects a dead consumer vs how long a slow consumer gets before eviction. Default values are too conservative for most production loads.

SEP 2025
SwiftiOS

Swift’s @MainActor is a compile-time guarantee that UI mutations stay on the main thread — something we used to enforce with DispatchQueue.main.async and hope. Actors eliminate the data races but they shift the discipline from runtime crashes to await boundaries. Trust the compiler, not your memory.