All posts
When Your Python Server Is Slow — Finding the Bottleneck in 5 Minutes with py-spy
Using py-spy, the sampling profiler that attaches to a running Python process with no code changes or restarts: dump to identify a hung process, top for live bottleneck watching, record and flame graphs, --idle for off-CPU waits, reading the GIL numbers, and running it in containers.
Build a Desktop App with PySide6 #4: Qt Designer and UI Files — Draw the Screen, Then Load It
Draw your screen with Qt Designer, which ships with PySide6, and load the .ui file in two ways: pyside6-uic and QUiLoader. We practice the code-and-screen separation workflow on the todo app form.
Cutting NAT Gateway Costs: The Data Processing Fee Is the Real Bill
A breakdown of the NAT Gateway bill and the order to cut it: the three overlapping charge layers (hourly, data processing, internet transfer), why downloads get charged too, the cost math of each bypass route from free gateway endpoints through interface endpoints, IPv6, and NAT instances, how to find the traffic culprits, and the cost structure of multi-AZ placement.
How a CDN Makes Things Fast — From Cache Hits to Dynamic Content
CDN mechanics from the practitioner's side: the edge structure that shrinks distance (RTT), the Cache-Control headers and cache keys that decide hit rate, invalidation and deploy strategy, how CDNs help even uncacheable dynamic traffic (TLS termination, connection reuse), and the common mistakes that eat hit rate.
Build a Desktop App with PySide6 #3: Signals and Slots — the Core of Event Handling
A tour of signals and slots, the center of event handling in Qt. From clicked.connect through signals that carry arguments to custom signals declared with Signal, and wiring real behavior into the todo app.
DynamoDB vs RDS: Choosing an AWS Database
A working standard for choosing between DynamoDB and RDS: the data-model difference between key-value and relational, how per-request versus per-instance-hour billing splits the bill, DynamoDB's constraint of designing access patterns up front, the trap of GSIs multiplying write costs, a selection order driven by traffic patterns, and the setup that runs both side by side.
Why Redis Is Fast — Memory, a Single Thread, and Data Structures
The structural reasons Redis handles hundreds of thousands of requests per second: memory access with no disk in the path, a lock-free single-threaded event loop, and purpose-built data structures — plus the single-thread trap (one slow command stalls everything) and the cases where Redis gets slow.
Build a Desktop App with PySide6 #2: Widgets and Layouts — Assembling the Screen
A catalog of the widgets you will use most, and how to assemble a real screen by nesting QVBoxLayout and QHBoxLayout. We build the screen skeleton of the todo app we will extend throughout the series.
MCP (Model Context Protocol) Explained: The Standard for AI Tool Use
A single-post summary of MCP, the protocol that keeps appearing in agent articles: how a standard interface turns the N-by-M tool-integration problem into N-plus-M, its relationship to function calling, hosts, clients, servers and the tools/resources/prompts primitives, adoption status and foundation governance as of 2026, security cautions from third-party server trust to prompt injection, and when adopting it is worth it — and when it is not.
What a Database Index Actually Does — B-trees, Lookup Cost, and the Price of Writes
How indexes make lookups fast, from the B-tree up: the cost gap versus full scans, composite indexes and column order, why indexes are not free (write cost, storage), and the working rules for what to index and what to leave alone.
Build a Desktop App with PySide6 #1: What PySide6 Is — Desktop Apps with Qt and Python
A comparison of your options for building desktop apps in Python, and the case for PySide6, the official Qt bindings. We go from installation to showing your first window and understanding what the event loop means.
RAG vs Fine-Tuning vs Long Context: Getting Knowledge Into an LLM
A working standard for the three ways to get your data into an LLM: the structural difference between retrieving and injecting (RAG), modifying weights (fine-tuning), and stuffing everything in with caching (long context), the boundary that fine-tuning teaches behavior rather than knowledge, a selection order driven by knowledge size and update frequency, and the practical setup that combines all three.