135 articles · 9 subjects
Everything published here
The whole archive on one page, grouped by subject rather than by date — the newest ten are on the front page, the computer-science track is taught in order at /cs, and the AI work has its own reading order at /ai.
AI & LLM engineering45
How language models actually work, and how to build on them — retrieval, agents, prompting, inference and the parts that break in production.
Anthropic Prompt Engineering: The Production Checklist (copy-paste templates)
Anthropic's docs teach you the techniques. This is the other half — the checklist you run before you ship, and four blocks you paste into a file: a system prompt that does not destroy your cache, a few-shot block, a tool definition plus the loop around it, and an untrusted-content wrapper for prompt-injection hardening. Written against the current models, where several moves from a two-year-old tutorial now return HTTP 400.
Embedding Dimensionality: Cut Your Vectors 4× Without Re-Embedding Anything (Matryoshka)
Embedding vectors don't have to stay at full width. Matryoshka representation learning lets you truncate from 3,072 to 768 dimensions after the fact, cutting storage 4× with minimal quality loss—no re-embedding required.
Prompt Compression: 30,000 Tokens → 9,200, Same Answer (and the Caching Trap)
Prompt compression shrinks token counts by 70% using extractive and abstractive techniques, but breaks prompt caching and costs latency upfront. Learn when the tradeoff wins.
Chain of Thought — why 'think step by step' actually works
Chain-of-thought prompting works because it buys your model more forward passes and external scratch space, not because it tries harder. Learn the mechanism from first principles.
Ollama vs vLLM: Local Dev Tool or Production Inference Engine?
Ollama and vLLM both run LLMs locally, but optimize different axes: Ollama trades throughput for simplicity on one laptop; vLLM trades setup complexity for production concurrency. Learn which to use and why they're not competitors.
Next-Token Prediction: How an AI Actually Writes Text (Not Magic — Just Probability)
An LLM never sees a finished sentence. It answers one tiny question, over and over: given everything so far, what's the next token? It builds a probability distribution over the whole vocabulary, samples from it (not always the top score), glues the winner on, and re-runs from scratch. That loop is the entire engine — and it explains why the same prompt can give two different answers, what 'personalization' really is, and where hallucinations come from.
Perplexity — the one number that says how surprised the model is
Perplexity measures how surprised a language model is by real text—expressed as an effective number of equally-likely token choices. Learn the math from scratch: probability → surprise → cross-entropy → perplexity, and why lower is better only for fluency, not correctness.
Speculative Decoding, Explained: Free LLM Speed With Zero Quality Loss
Speculative decoding uses a small draft model to propose K tokens, then verifies all K+1 in one big-model forward pass. Same weight load, mathematically identical output, zero quality loss — typical 2–3× speedup.
Prompt Injection Explained: Why There Is No 'Parameterised Prompt' (LLM Security)
Prompt injection occurs because LLM apps send instructions and user data as a single text stream with no channel separation, unlike SQL which has parameterised queries. Learn why there is no fix and what defences actually work.
Continuous Batching: How One GPU Serves Hundreds of Chat Users at Once
Continuous batching schedules LLM inference requests at each token generation step instead of locking the batch. This lets one GPU serve dozens of concurrent users by evicting finished sequences and admitting queued ones mid-flight, trading per-user latency for throughput.
Mixture of Experts (MoE): How a 400B Model Runs Like a 40B One
Mixture of Experts (MoE) lets a 400B-parameter model compute like a 40B one by routing each token to only 2 of 8 expert sub-networks. Learn how sparse routing trades memory for compute efficiency.
Zero-Shot vs Few-Shot Prompting: Why Your LLM Output Keeps Breaking (and the 1-Minute Fix)
Learn why your LLM output drifts in production: zero-shot asks without examples, few-shot pastes worked examples so the model copies your exact format. Same weights, different prompt.
Vector Search — how HNSW finds nearest neighbours
HNSW turns nearest-neighbor search from brute-force (2M comparisons, 1.2s) into a hierarchical graph walk (1.8k comparisons, 2ms). Learn how greedy navigation trades exact answers for speed.
Concurrent LLM Calls in Python: asyncio.gather + a Semaphore
500 LLM calls in a for-loop takes 17 minutes — and your CPU does nothing for all of it. await is not concurrency. Here's how asyncio.gather puts every request in flight at once, why it's named for the results and not the speed, and why asyncio.Semaphore is the one line that stops you from DDoS-ing yourself into a wall of 429s.
RAG vs Fine-tuning
RAG retrieves documents at query time; fine-tuning changes model weights to teach behavior. Learn which solves knowledge updates vs. consistent output style.
ReAct From Scratch: Make Your LLM Reason and Act in ~40 Lines (No LangChain)
ReAct (Reason + Act) is already baked into the frontier models you use every day — it started as a 2022 paper and became the backbone of modern AI agents. Here's what it actually is: the Thought → Action → Observation loop, a real trace, and a ~40-line build from scratch in Python, TypeScript, and Java — without the model's native tool-calling — so every moving part is visible.
How Should Your LLM Stream Tokens? SSE vs WebSockets vs Polling
Your chatbot dumps the whole answer after an 8-second stare. ChatGPT types it out token by token. The difference is one transport decision — and for LLM streaming the answer is almost always Server-Sent Events, not WebSockets. Here's why, with the FastAPI code.
Quantization vs Distillation
Quantization keeps the same model at lower precision (no retraining); distillation trains a new, smaller student to mimic a teacher. Learn when to use each technique to shrink your LLM.
From Toy to Truth: Building Production-Grade RAG
Your RAG demo works on 100 documents and dies in production — not because retrieval is hard, but because nobody measures it. Here's the two-layer eval framework, the three-stage ranking funnel, and the diversity algorithms (MMR vs VRSD) that separate a toy from a system you can trust.
The LLM Gateway: One Endpoint Instead of Five SDKs
An LLM gateway is the reverse proxy your AI stack is missing — one endpoint that handles fallback, cost control, caching, and observability across every model provider. Here's what it buys you, the 2026 landscape, where it's heading (agents + MCP), and when to skip it.
Prompt Versioning Without Langfuse — Three Lean Paths from prompts.yaml to Postgres
Langfuse, PromptLayer, and Promptfoo will all sell you a prompt registry. There are three reasonable ways to ship prompt versioning in 2026, and the choice is about team shape, not technology. This post walks through all three — Langfuse Cloud, prompts.yaml + git, and a 2-table Postgres schema with an 80-line FastAPI router — on the same customer-support classifier, running on Claude Haiku 4.5.
Anthropic's Prompt Engineering Best Practices, Distilled
Anthropic published one consolidated page covering everything they recommend about prompting Claude. It's long, mixed with model-migration trivia, and easy to skim past. Here are the techniques that survive past the demo — what to do, when each one matters, and the snippet you can paste.
What is LangChain? Build Your First Agent in 15 Lines
LangChain is the most-used framework for building LLM apps — agents, RAG, multi-step workflows. This tutorial shows you what it actually is, the three primitives that matter, and your first working agent with one tool in under fifteen lines of Python — runnable today on Google's free Gemini tier, no credit card. Plus the same agent rewritten without LangChain for comparison, so you can see exactly what the framework is doing for you.
The Guardrail Stack You Actually Need in LLM Production
Five layers of LLM guardrails get talked about. Two of them carry the weight in most shipped features: output schema validation and tool/action policy. The other three are mostly theater until specific triggers fire. A practical breakdown drawn from running LLM features in production.
Build Your Own Model Registry in a Weekend — FastAPI + Postgres, No MLflow
Most ML teams reach for MLflow before they need it and pay the operational tax for years. The custom model-registry pattern from a real labeling platform — version, compare, roll back models with a 200-line FastAPI service. When the DIY version is the right answer, and the three signals that say it isnt anymore.
Stop Vibe-Checking Your Prompts - Building an Eval Harness That Catches Regressions Before Your Users Do
Most LLM features ship on vibes. The first time you regret it is the day a prompt change quietly breaks half your traffic and nobody notices for a week. Here is what an honest eval harness actually contains - golden datasets, LLM-as-judge, prompt versioning - and the real cost of running it.
The MCP Token Tax — Your Agent Is Burning Tokens Before It Starts
Every MCP server you connect loads its tool schemas into the context window before the first user turn. Here's the arithmetic on how expensive that gets, why most teams never measure it, and how to stop paying for tools the agent will never call.
MCP vs REST API vs Markdown — How Agents Should Actually Consume Your Data
Three ways to hand data to an LLM agent: the Model Context Protocol, a boring REST API with an API key, or a curated Markdown file. Each is right some of the time and wrong a lot of the time. Here's the honest decision tree.
Long Context vs RAG — When to Stuff Gemini's 2M Window vs Build a Vector DB
Gemini 2M and Claude 1M made 'just paste it all' a real engineering option. Here's the cost math, the latency curve, the quiet failure mode of context dilution, and the rule for when stuffing beats RAG — and when it silently hurts.
RAG Ingestion & Chunking — The Missing Engine Behind Hybrid Search
You tuned the embedding model. You went hybrid. Your RAG still misses. The bug is upstream — in how you split documents. Five chunking strategies, when each wins, and how to actually evaluate them.
Why Your LLM Keeps Returning Garbage JSON (And How to Stop It)
Every LLM-powered feature breaks the same way in production: the model returns almost-JSON. Markdown fences, trailing commas, a chatty preamble, a missing closing brace. Here's the 3-layer fix that ships — native structured outputs, Pydantic validation, and json_repair + retry loops.
Semantic vs Keyword vs Hybrid Search: What Every RAG Demo Skips
Every RAG demo shows embeddings and stops there. Real production search almost always mixes keyword and semantic retrieval. Here's what's happening under the hood, why hybrid wins, and a runnable Postgres example in ~40 lines.
When LLMs Learn to Remember — Part 4: Why Your AI's Memory Shouldn't Be a Graph Database
Graph databases look like the obvious answer for AI memory — entities, relationships, multi-hop queries. So why did OpenClaw, MemOS, and every shipping system pick flat markdown instead? A contrarian deep dive into the real tradeoffs.
When LLMs Learn to Remember — Part 3: How OpenClaw Turns LLMs into an Operating System
OpenClaw treats AI as an infrastructure problem. This deep dive covers its 3-tier memory architecture, MemOS, hybrid search, automatic memory flush, and what it means for the future of AI assistants.
When LLMs Learn to Remember — Part 2: Building a Memory System for Your AI Assistant
A practical guide to building persistent AI memory: Memory CRUD operations, post-conversation sweeps, context tree curation, prompt templates, and the unsolved problems nobody talks about.
When LLMs Learn to Remember — Part 1: LLMs Don't Remember Anything
LLMs are completely stateless - they forget everything after each call. So how does ChatGPT remember your preferences? This post breaks down the illusion of AI memory, compares current memory strategies (markdown trees, vector databases, hybrid systems), and explains context tree indexing.
Running LLMs Locally — Small Models, Quantization, and Your 4GB GPU
A hands-on guide to running language models on consumer hardware. What fits on a 4GB GPU, what quantization actually does, how llama.cpp and Ollama work, and whether local models can replace your API subscription.
LLM Model Types — Reasoning, Thinking, and Beyond
A practical guide to understanding the different types of language models: base models, instruction-tuned, reasoning models, thinking models, and MoE architectures — what they are, how they differ, and when to use each.
Transformers — The Architecture That Changed AI (Part 1 of 3)
A deep dive into the Transformer architecture — from attention mechanisms to self-attention, multi-head attention, positional encoding, and why this single paper reshaped all of modern AI.
RAG vs Knowledge Graphs — How to Give LLMs the Right Context
A practical comparison of Retrieval-Augmented Generation and Knowledge Graphs for grounding LLM responses, with architecture patterns, code examples, and guidance on when to use each approach.
How AI Agents Do Deep Search — Building a Research Agent from Scratch
Why a single LLM call fails for complex research questions, and how to build an agent that iteratively searches, reads, reasons, and synthesizes — with full Python code you can run.
Build Your Own Local Text-to-Speech Stack with Python
A hands-on guide to deploying 3 TTS engines (Edge TTS, Piper, Coqui XTTS v2) and a speech-to-text service — from a simple API to desktop keyboard shortcuts that read any selected text aloud.
Building a Verifiable AI Agent with the ReAct Framework
How to build an AI agent that does not just fire and forget — using the Check-Action-Verify loop, ReAct reasoning pattern, and paired action/verification tools to ensure every operation is confirmed.
Building AI Tool-Calling Agents from Scratch with Python
A hands-on guide to building LLM agents that call real tools — from a single weather function to a multi-tool database agent with safety constraints and interactive chat.
How LLM Function Calling Actually Works — From Tokens to Tool Orchestration
How LLMs return structured data through function calling, how constrained decoding works under the hood, and what happens when the model needs to call multiple tools in a single turn.
System design & distributed systems25
What happens to a design once there is more than one server, more than one request at a time, and something is always broken somewhere.
Design a Notification System: The Four-Point Answer, and the Duplicate-Send Trap
"Design a notification system" sounds like a feature question. It is an infrastructure question: is notification a shared service every producer calls, or code each service bolts on for itself? Here is the whole answer in four points — one central service, a queue that absorbs the burst, push/email/SMS as separate channels, and per-channel limits plus preferences — and the trap that fails candidates: not sending the same notification five times.
Architecture Patterns: The Six Shapes a System Can Take (and Why They Are Not a Menu)
Event-driven, layered, monolithic, microservices, MVC, primary-replica — teams compare these six as if they were alternatives, which is why the meeting never ends. They are not alternatives. They sit on three different levels: the deploy unit, the code organisation, and the data topology. Here is the sort, proved on a real 246-line FastAPI service where four of the six are true at the same moment, with the price of each level measured rather than argued.
SLIs, SLOs and Error Budgets: How to Turn Reliable Enough Into a Number
One person says ship it, another says the system is not stable enough, and neither of them has a number — so the loudest voice wins. Here is the arithmetic that ends that argument: what an SLI actually measures and where to measure it, why an SLO is meaningless without a time window, how an error budget turns a target into an allowance you are meant to spend, and why burn rate is the only one of the four that tells you how much time you have left.
HTTP Caching Explained: max-age, ETag and Why Your Users Still See Last Week's CSS
You fixed the CSS, deployed, and a customer sends a screenshot of last week's layout. Nothing is broken — the browser is obeying the header you sent it. Here is HTTP caching from first principles: why max-age is a promise you cannot take back, why no-cache does not mean don't cache, how ETag revalidation buys you a round trip with zero bytes, and why content-hashed filenames are the only invalidation strategy that actually works.
Design a URL Shortener: the Four-Move Answer, and the 301 vs 302 Trap
'Design a URL shortener' is the classic system-design warm-up, and most candidates answer the wrong question. The interviewer is not testing your hash function — they want a data-store choice, defended. Here is the whole answer in four moves: base62-encode a hash into a short code, store code → URL as one key and one value in a KV store, handle collisions with a retry or a monotonic counter, and serve the redirect. Then the follow-up that separates a rehearsed answer from a real one: a 301 is cached by the browser, so your click counter flatlines and you can never repoint the link. A 302 costs a request per click — and that request is the product.
Feature Flags vs Load Balancer: One Splits Versions, the Other Splits People
Both tools split your traffic, so 'send 10% to the new thing' sounds like one task. It is two, at two different layers. A load balancer splits VERSIONS by weight at the infrastructure layer — 90/10 at Envoy, Istio or NGINX — and it splits connections, not people, so the same user can bounce between v1 and v2 on every request. A feature flag splits BEHAVIOR inside one running service, per user, by hashing a stable id into a bucket so the same person always lands in the same group. Here is the code for both, what each one actually costs you, the rule of thumb, and how the same split shows up in an LLM serving stack.
Chaos Engineering vs Load Testing: One Measures the Ceiling, the Other Measures the Floor
Both practices break your system on purpose, so they get filed under the same heading — and that is why a system can pass a load test at ten times its traffic and still be taken down the following week by one slow, non-critical service. A load test drives traffic up a ramp against a healthy system and finds the knee. A chaos experiment holds traffic at a normal Tuesday and breaks exactly one thing, to test the sentences written into your architecture diagram. Here is the real code for both, the hypothesis-blast-radius-abort discipline that separates an experiment from an outage, and how the same two questions apply to an LLM serving stack.
Hot Keys in a Cache: Why One Key Saturates One Node While the Cluster Looks Idle
Your cache dashboard says 10% average and everything is fine. One machine is at 96% and checkout is timing out. That is a hot key — one popular key, one node, and no amount of hardware. Here is how hash(key) picks the machine, why adding nodes takes the hot one from 96.00% to 95.50%, why consistent hashing with virtual nodes does nothing for it, and the three fixes that actually work — key splitting, an in-process cache, and request coalescing — with their real costs, every number executed.
Active-Active vs Active-Passive: You Had a Second Server, So Why Were You Down for 41 Minutes?
You own two machines. Only one of these two designs is actually using the second one. Active-passive keeps a standby in sync and promotes it when the primary dies; active-active runs both live, all the time. Here's what each one looks like in code, the four steps of a failover and what they cost, the conflicts and split brain that active-active hands you instead, and why the honest answer is usually both — at different layers of the same system.
Write-Through vs Write-Back Caching — Explained in Detail
Every caching tutorial teaches the read path. The bugs live on the write. Write-through, write-back and write-around with the real code for each, the measured cost of a durable write, and the data-loss window reproduced step by step.
Circuit Breaker — Explained in Detail
The circuit breaker pattern isolates failing dependencies by stopping retries before they amplify outages. Learn the three states, failure arithmetic, and when to open the breaker instead of retry.
Monitoring vs Observability: Why Every Dashboard Is Green During the Outage
Your dashboards are green during the outage because monitoring answers questions you asked in advance. Observability keeps the question open. Learn the mechanism, the cardinality trap, and when to use which.
Autoscaling Explained: Why New Servers Always Arrive Two Minutes Too Late
Autoscaling is a reaction, not a prediction. A metric is sampled every ~60 seconds, has to hold over a threshold for two samples, and only then does a machine launch — and launched is not serving. Boot, image pull, app warmup and health checks add another ~90 seconds before the load balancer sends it a single request. Here's the full loop, why it is structurally late by exactly one boot cycle, and what actually absorbs a spike.
At-Least-Once vs Exactly-Once Delivery: Why the Customer Got Charged Twice
A customer taps Pay once and gets charged twice — with no bug in your code. Delivery semantics from first principles: why a lost acknowledgement makes at-most-once, at-least-once and 'exactly-once' inevitable, and why exactly-once is a property of your consumer, not a setting on your broker.
Distributed Tracing — how you find which service ate the 3 seconds
Distributed tracing mints one trace ID at the edge, propagates it through every service, and reassembles spans into a waterfall to show exactly which hop ate the latency. Compare: logs alone vs. traces with parent pointers.
Connection Pooling: Why Your API Dies at 200 Users (But the DB Is at 4% CPU)
Your API falls over at 200 concurrent users while Postgres sits at 4% CPU. That paradox is what connection pooling exists to fix. Here's what opening a database connection actually costs, the max_connections=100 wall, how a pool turns connections into a borrowed-and-returned resource, why it's a queue and not a multiplier, how to size it, and why 'pool exhausted' is almost always a slow query — with code, and the same idea applied to LLM serving.
Pub/Sub Explained From Scratch — One Event, Five Systems, Zero Direct Calls
Pub/sub decouples producers from consumers by publishing one event to a broker that fans it out to all subscribers with queues and retries. Compare direct calls vs. event-driven architecture.
Load Balancer Explained From Scratch — How One Site Survives a Traffic Flood
A load balancer distributes incoming requests across multiple servers to prevent any single server from becoming a bottleneck. Learn how round-robin routing, health checks, and redundancy keep sites online during traffic spikes.
API Gateway Explained: One Front Door for Every Service (and Why the Bad Bot Never Gets In)
An API gateway puts a single front door in front of all your services — one entrance every request has to pass through, including the bad ones. Here's the problem it solves, how it terminates TLS, authenticates, rate-limits, routes, and aggregates in one place, and why the same idea now guards your LLM calls too.
Stateless vs Stateful
Stateless servers forget you after each request, scaling infinitely but requiring every call to carry full context. Stateful servers remember you, enabling natural continuity but pinning you to one node.
Cache vs CDN
Cache and CDN both store copies for faster reads, but solve different problems: cache cuts backend work for dynamic data; CDN cuts network distance for static content. Learn when to use each.
Pub/Sub vs API Calls: Should Your Services Publish an Event or Just Call Each Other?
A user signs up, and email, push, and analytics all need to know. Do you call each service yourself, or publish one event and walk away? Here's Pub/Sub vs direct API calls — event-driven async messaging vs synchronous request/response — with a clear rule for which one to reach for.
Synchronous vs Asynchronous: Block and Wait, or Fire and Forget? (and When to Use Which)
Synchronous vs asynchronous comes down to one choice: when you send a request, do you block and wait for the answer, or fire it off and get notified later? Here's what each actually does — blocking vs non-blocking, callbacks, promises, async/await, and webhooks — the throughput payoff and the complexity cost, a clear rule for which to reach for, and how the same trade-off shows up in async servers and LLM streaming.
Horizontal vs Vertical Scaling: Scale Up vs Scale Out (and When to Use Which)
Your app is slowing down under load — do you scale up or scale out? Vertical scaling means moving to a bigger machine: same app, same code, more CPU/RAM/disk. Horizontal scaling means adding more machines behind a load balancer. Here's how they really differ on cost, ceiling, fault tolerance, and the coordination tax — with a clear rule for which to reach for, plus how the same trade-off shows up when you serve LLMs.
Latency vs Throughput: Time per Request vs Requests per Second (and When to Optimize Which)
Latency and throughput both measure performance, but they answer different questions: how long ONE request takes versus how MANY you can serve per second. Here's the difference that actually helps you debug — milliseconds and p99 tail latency, RPS/QPS capacity, Little's Law, why pushing utilization toward 100% makes latency explode, and how the same trade-off shows up in LLM serving.
Databases & data storage10
Indexes, transactions, query plans and the storage decisions that only hurt later — plus where data goes when one table stops being enough.
Offset vs Cursor Pagination: Why LIMIT/OFFSET Breaks at Scale (and What to Use Instead)
LIMIT 20 OFFSET 40 works perfectly on page two — and page two is the one page that hides both of offset pagination's defects. Deep pages get slower because the database builds and discards every skipped row, and an offset is a position in a list that keeps moving, so inserts duplicate rows across pages and deletes make them vanish. Here's how keyset (cursor) pagination fixes both by pointing at a row instead of counting positions, what it honestly costs you, and how to pick.
View vs Materialized View: A Saved Question vs a Saved Answer
You wrapped the slow query in a view and believed it made something faster. It did not. A view stores no data — it stores SQL text, so every SELECT re-runs the query from scratch. A materialized view stores the answer as a real table on disk you can index, which turns 40 seconds into milliseconds and charges you freshness. Here is exactly what each one is, why a materialized view is neither a cache nor an index, what REFRESH really costs (an exclusive lock, or CONCURRENTLY and a unique index), and the one question you must answer before you ship one.
Background Jobs Without a Broker: Your Worker Is Holding a Database Connection for 40 Minutes
A job is a row, not a function call. And a connection is not a transaction. Those two sentences separate a background worker that survives a deploy from one that quietly stops Postgres cleaning up. Measured on PostgreSQL 16.14 — including why 'idle in transaction blocks VACUUM' is false as usually told.
60 Years of Data Storage: Database → Warehouse → Lake → Lakehouse
We rebuilt the way companies store data four times. Each generation fixed one precise failure of the last — and once you know what broke, the buzzwords collapse into a single argument.
SQLite FTS5: How Full-Text Search Actually Works (Inverted Index + BM25)
You have 10,000 markdown notes and you search for 'postgres backup'. grep takes 400 ms and returns 40 files in folder order. SQLite FTS5 takes 3 ms and puts the right note first. Same files, same query — the difference is an inverted index and BM25 ranking. Here's how both actually work, the negative-score gotcha everyone hits once, the staleness trap of a derived index, and where lexical search ends and vector search begins — including why RAG pipelines still run BM25 next to embeddings.
Data Modeling Explained: From One Messy Table to a Real Schema
Data modeling is designing which facts live where. Learn the three layers (conceptual, logical, physical), normalization vs. denormalization, and why your schema is the contract every pipeline depends on.
The N+1 Query Problem: Why 100 Products Cost 101 Queries (and Why an Index Won't Save You)
You write one query to list 100 products, and the database quietly runs 101. That is the N+1 problem — and the fix is not an index. Here's why a query's real cost is the round-trip, why an index makes ONE query fast but can't change how many you issue, how a single JOIN collapses 101 queries to 1, and why the same shape shows up in REST calls, GraphQL resolvers, and 500 sequential LLM awaits.
How a Database Index Actually Works: B-Trees, Seq Scans, and the Cost Nobody Mentions
The same query, 4.2 seconds then 3 milliseconds — and the only thing that changed was one line of SQL. Most explanations stop at 'it's like the index in a book.' This one goes a level below: what a table actually is on disk, why a full table scan is the database's only option without an index, how a B-tree gets you there in three hops, and the cost nobody mentions — every write has to update every index.
S3 vs Database Blobs: Why Your Files Don't Belong in Postgres (and What Pre-Signed URLs Fix)
Should raw image and video bytes live inside your database or in object storage like S3? Stuffing files into a bytea/BLOB column keeps everything in one place and works for a weekend project — then backups drag terabytes through your most expensive tier and reads pull huge binaries through the connection pool. Here's why object storage plus a tiny DB reference plus short-lived pre-signed URLs is how the big apps actually store media — and how the same pattern serves model weights and generated media for LLM apps.
ACID vs BASE
ACID vs BASE is the core CAP trade-off: ACID prioritizes correctness (banks, ledgers), BASE prioritizes availability (likes, carts). Choose per-data, not per-database.
Backend, APIs & security17
The layer between the browser and the database: API shape, auth, sessions and tokens, concurrency, and the security defaults worth knowing by heart.
How Safe Is a 60-Minute Signed URL? The Link Is the Credential
You added a CORS rule to a private bucket and then wondered whether you had just made every customer invoice public. You had not — CORS lives in the browser and never decides who may fetch a file. The signed URL does, and it is a bearer token: whoever holds the string gets in, with no login, no session, and no way to cancel it. The expiry is the only dial you get, so here is how to set it on purpose.
Bearer Token: The Two Things Hiding In One HTTP Header
Authorization: Bearer eyJhbGciOi… is not one thing, it is two — a scheme and a credential. Here is what the word Bearer actually promises, why the token comes in exactly two flavours (opaque and JWT) and what that choice costs you, why OAuth 2.0 is not a third flavour, and the three pieces of code that issue it, send it and verify it.
Route Handler vs Service vs Repository — Where Business Logic Should Live
The rule for publishing an article ends up in four files — the web handler, a nightly job, a CLI, a webhook — and one of them never gets the fix. This is the whole extraction, line by line: what belongs in the handler, what belongs in the...
Debouncing vs Throttling: Only the Last Event, or the Ones in Between?
Debounce waits for silence and fires once; throttle watches the clock and fires steadily. The search box makes debounce look universal — a drag handler at 60 events/sec proves it isn't. Both mechanisms in plain JavaScript, both honest failure modes (debounce can starve forever, a naive throttle drops the final event), and a rule for picking one.
bcrypt vs SHA-256: Why a Password Hash Should Be Slow on Purpose
"We hashed the passwords, so they're safe." Both bcrypt and SHA-256 are one-way hashes — but only one survives a database leak. SHA-256 isn't broken; it's fast, and fast is exactly the bug for password storage. Here's how salting, cost factors and GPU guess rates turn the same leak from hours into centuries — plus what bcrypt actually costs you, and why the fast hash is still the right call for API keys in an LLM app.
RBAC vs ABAC
RBAC attaches permissions to roles; ABAC evaluates policies over user, resource, action and environment attributes. RBAC scales with role explosion; ABAC with policy opacity. Real systems use both.
Symmetric vs Asymmetric Encryption
Symmetric encryption uses one shared key (fast, hard to distribute). Asymmetric uses a public/private pair (solves key distribution, but slow). Real systems use both—like HTTPS and JWTs.
CORS — the attack it stops, and the one-line fix
CORS isn't browser gatekeeping—it stops an attack where cross-site requests auto-attach your login cookies. Learn the threat, the same-origin policy, and the one-line server fix.
Access Token vs Refresh Token
Why one login gives you two tokens: access tokens are short-lived and sent everywhere (small blast radius if stolen), refresh tokens are long-lived and server-tracked (enabling real logout). Together they escape the single-token security-vs-UX trade-off.
Encryption vs Hashing
Encryption is reversible (lock and unlock with a key); hashing is one-way (no way back). Learn when to use each, why passwords must always be hashed, and how salt and slow hashing defeat brute-force attacks.
Callback vs Promise vs Webhook: Where Does Your Async Result Actually Come Back?
Callback, promise, and webhook get treated like three flavors of the same thing — they aren't. The real difference is WHERE the result lives. Callback and promise hand a result back to the same program in memory in milliseconds; a webhook is another machine calling you back over the network, seconds to minutes later. Here's the mental model, the trade-offs, code for each, and a clear rule for which to reach for — including what it means for async LLM jobs.
Authentication vs Authorization: AuthN vs AuthZ (and Why 401 ≠ 403)
Authentication and authorization sound the same and get mixed up constantly, but they answer two different questions: who are you, versus what are you allowed to do. Here's the difference that actually prevents security bugs — credentials and the three factors that build MFA, roles and scopes and policies checked on every request, the classic 401-vs-403 trap, and how the exact same split governs API keys and tool permissions for LLM agents.
OAuth vs JWT: A Format vs a Flow (and Why You Probably Use Both)
OAuth vs JWT is the wrong comparison — they're not even the same kind of thing. A JWT is a token FORMAT: a tamper-proof, self-contained ID card the server verifies by signature, no database lookup. OAuth is a delegation PROTOCOL: how an app gets permission to access your data in another app without ever seeing your password. Here's how they actually differ — with code — and why an OAuth flow usually hands back a token that's a JWT.
gRPC vs REST: Web Menu vs Phone-Line Contract (and When to Use Which)
REST and gRPC are two ways to build an API. REST is ordering à la carte off a web menu — a plain HTTP request to a resource, JSON back, anyone can call it. gRPC is a dedicated phone line with a strict contract — a Protobuf schema, generated typed stubs, compact binary over HTTP/2 with streaming. Here's how they actually differ on speed, payload, reach, and tooling — with code — and a clear rule for which to reach for.
Sessions vs JWT: How Your App Remembers You're Logged In
After you log in, every request has to prove it's still you. There are two ways to do it: let the server remember you (a session) or carry the proof yourself (a JWT). One is a coat-check ticket, the other a signed wristband — and the difference decides how you revoke access, scale, and store state. Here's the real trade-off, with the code in Python, TypeScript, and Java.
How to Handle Stripe Webhooks in Development and Production
Learn how to configure Stripe webhooks in local development using the Stripe CLI and transition seamlessly to a production environment. Secure your webhook endpoints and manage environment-specific settings the right way.
Understanding setTimeout and setInterval in JavaScript
The setTimeout function allows us to execute a function at a later time, while setInterval repeatedly executes a function at a fixed interval. This guide explains their usage and differences with examples.
Networking & protocols1
How a request actually reaches a machine: names, routes, tunnels and the layers people skip until something times out.
Computer science fundamentals6
The machine underneath, and the classic data structures and algorithms that interviews assume you were taught.
Big-O Without the Maths: a Prediction, Not a Measurement
Your function ran in 40 milliseconds on your laptop. That number tells you almost nothing, because a stopwatch measures the trip you just took and Big-O predicts the road you are on. Here is what Big-O actually counts — growth, not time — taught with one Python function, real measured numbers, the hidden linear scan that turns 258 ms into 0.9 ms with one word, and the honest half nobody writes down: the crossover below which the worse complexity class wins on the clock, every time.
Heaps and Priority Queues: The Array That Is Secretly a Tree
A binary heap drains 100,000 background jobs in 54.8 ms where a plain list with min() takes 72 seconds — a 1,300x gap from one rule: every parent is smaller than its children. Here is how the tree is never actually built, why sift up and sift down are the only two moves, why building bottom-up is O(n) and not O(n log n), and the four things a heap will not do for you.
Arrays vs Linked Lists: Why the Textbook Winner Loses on Real Hardware
The textbook says a linked list inserts in O(1) and an array inserts in O(n), so the linked list should win. On real hardware the array wins almost every time — and the reason is not in the code, it's in where the data physically sits. Measured: the same ten million numbers, the same O(n) walk, 0.53s vs 1.53s. Here's contiguity, the 64-byte cache line, the prefetcher, and pointer chasing — plus the experiment that proves the cause with no linked list in it at all.
Hash Tables Explained in Detail: Why a Dict Lookup Beats a List Scan by 62,000x
You use a hash table every day and almost nobody can say what happens underneath. Built from scratch in about twenty lines of Python: the hash function, the bucket index, a real collision, chaining, the load factor, the resize — and where O(1) quietly stops being true.
Concurrency vs Parallelism: One Chef Juggling Orders vs Many Chefs Cooking (and Which Your Bottleneck Needs)
Concurrency and parallelism sound like synonyms but they're two independent ideas. Concurrency is structure — one worker interleaving many tasks, great for I/O-bound work that spends its time waiting. Parallelism is execution — many cores each running a task at the same instant, the only thing that actually speeds up CPU-bound work. Here's the difference, why they're orthogonal, and how it maps to serving LLMs (async request handling vs batched GPU compute).
Processes vs Threads
A process is its own isolated house; threads are roommates sharing memory. Learn when to use each for crash safety, performance, and avoiding deadlocks.
Servers, Docker & operations23
Running the thing: containers, deploys, scheduled work, monitoring and the Linux housekeeping every side project eventually needs.
Airflow vs Cron: When a Crontab Line Isn't Enough
cron and Airflow both run jobs on a schedule, but they answer different questions. cron asks 'is it time yet?' — one line, zero dependencies, forty years of uptime. Airflow asks 'what's the state of my whole pipeline?' — a DAG with dependencies, retries, backfills and a UI, at the cost of a scheduler, a Postgres and a worker pool. Here's the real distinction, with code, and a rule for picking.
Docker vs VM
Containers and VMs both isolate apps on one server, but at different layers. Containers share the host kernel (fast, dense, thinner boundary); VMs virtualize hardware (slower, isolated, any OS). In the cloud, you run containers inside VMs.
Ansible — Automate Your Server Infrastructure with Code
Stop SSH-ing into servers to run the same commands manually. This hands-on guide shows how to use Ansible to provision, configure, and deploy to Hetzner cloud servers — with real playbooks you can copy and run.
Docker Secrets vs .env Files: Secure Configuration Management
A comprehensive comparison of Docker secrets and traditional .env files for managing sensitive configuration. Learn why Docker secrets provide better security, how to migrate from .env files, and best practices for production deployments.
How to Run n8n on Your VPS Server Using Docker and Nginx
Learn how to deploy n8n on your existing VPS without interfering with your primary website or application. This guide walks you through setting up Docker Compose and configuring Nginx to serve n8n on a subpath (e.g., yourdomain.com/n8n).
How to Add a Deploy Key to GitHub on Windows and Use Multiple Repositories
Learn to securely manage multiple GitHub deploy keys on Windows using Git Bash and SSH config. This tutorial covers key generation, GitHub setup, SSH configuration, and proper cloning.
Monitor CPU, RAM, Disk Usage and Docker health with Prometheus, Node Exporter & cAdvisor
Expand your monitoring stack to include detailed observability of CPU, memory, and disk usage. With Prometheus, node_exporter, and cAdvisor, you can track both server health and container performance.
How to Deploy a Grafana Server in Your VPS for Small Team Use
Set up Grafana easily inside a VPS with Docker Compose and start building dashboards with your team. Learn how to integrate external Loki logs securely through NGINX authentication.
How to Add a Deploy Key to GitHub: Step-by-Step Guide
Deploy keys are a secure way to grant read or write access to your GitHub repository from a server. Learn how to generate, configure, and test deploy keys in this easy-to-follow tutorial.
How to Run Docker Without Sudo: A Step-by-Step Guide
Tired of typing sudo before every Docker command? Learn how to add your user to the Docker group and run Docker without elevated privileges. This guide walks you through the process, along with important security considerations.
How to Create a Non-Root User and Disable Root SSH Access in Ubuntu
Learn how to create a non-root user on Ubuntu for improved security. Follow these simple steps to add a new user, grant sudo privileges, and disable root SSH access to secure your server.
How to Use Screen for Long File Transfers with Rsync
Learn how to use the screen command to keep your Rsync file transfer running even if your SSH session disconnects. This method ensures uninterrupted data transfers, making it ideal for large file movements.
Comprehensive GlusterFS Installation and Configuration Guide
A step-by-step guide on installing, configuring, and verifying a replicated GlusterFS setup across two Linux servers. This tutorial ensures high availability, scalability, and data replication.
How to Configure a VLAN (vSwitch) on Hetzner Using Netplan
Learn how to configure a VLAN (vSwitch) on a Hetzner server using Netplan. This step-by-step guide will help you set up VLANs, apply configurations, and verify connectivity for seamless network management.
How to Change a User’s Password on Ubuntu: A Step-by-Step Guide
Learn how to change your own password or reset another user's password on Ubuntu using simple terminal commands. This guide covers both user-level and administrative password management.
Ubuntu Server Setup with Dual RAID Systems
This guide walks you through installing and configuring Ubuntu Server with two RAID systems. Learn how to set up RAID 1 for SSDs and RAID 0 for HDDs using mdadm
Secure Loki Access with NGINX Authentication
Learn how to protect Loki with NGINX using HTTP Basic Authentication, ensuring only authorized users can access logs. This guide covers password protection, configuration, and testing.
Logs Monitoring with Loki and Promtail
Learn how to set up a complete log monitoring stack using Loki and Promtail.
Scheduled Backup and Restore PostgreSQL Database Using Docker
Learn how to automate PostgreSQL database backups using Docker, a Bash script, and Crontab. This guide ensures your data is securely stored and can be restored efficiently when needed.
How to Exclude Local Files from Git Repositories Using .gitignore
Sometimes, you need certain files in your local project but don’t want them to be included in the remote repository. The solution is to use a .gitignore file, which allows you to specify files that should remain local. This guide will show you how to create and use a .gitignore file effectively.
A Step-by-Step Guide to Setting Up SSH Key Authentication
Learn how to check for an existing SSH key, generate one if necessary, and securely copy it to your remote server for password-free authentication.
Crontab with logging (Automating Tasks on Your Server: A Step-by-Step Guide to Setting Up Crontab with Python and Shell Scripting)
Learn how to automate tasks on your server using Crontab, Python scripting, and Shell scripts. This step-by-step guide will help you schedule and manage tasks efficiently.
Prometheus for Monitoring a Flask App, Redis, and PostgreSQL
Prometheus is a powerful toolkit for monitoring applications and infrastructure. This guide provides clear, step-by-step instructions to install, configure, and verify Prometheus for your Flask app, Redis, and PostgreSQL.
Geospatial & WebGIS5
Map data on the web: the OGC services, the spatial formats worth using, and how location gets queried without scanning the planet.
Proximity Search: How "Restaurants Near Me" Doesn't Scan Every Restaurant
You tap "restaurants near me" and get an answer in 50 ms — out of ten million rows the database never measured the distance to. That's spatial indexing: stop indexing points, start indexing space. Here's the grid trick, the 3×3 neighbor lookup, the cell-size trade-off with both extremes, why fixed grids go lopsided, and how the exact same prune-then-measure idea powers vector search for LLMs.
GeoParquet Explained: Your Geodata Has Two Shapes (One You Edit, One You Scan)
The database that is perfect for editing one parcel is the worst possible thing for scanning two hundred million of them. This is the OLTP-vs-OLAP split in geospatial storage — what a row physically is on disk, why columnar layout makes column pruning obvious, what GeoParquet actually specifies, and the Hilbert-sorting trap that decides whether any of the speed is real.
WMS vs WMTS vs WFS: A Picture, Fast Tiles, or the Raw Data (and When to Use Each)
WMS, WMTS, and WFS are three OGC web services that answer the same question — how does map data get from a server into your browser — in three completely different ways. WMS renders a flat PNG picture on the fly (flexible, but just pixels). WMTS is that same picture pre-sliced into cacheable tiles (fast, but rigid). WFS sends the actual vector geometry plus attributes (clickable and queryable, but heavier). Here's the mental model, the trade-offs, and a clear rule for which to reach for.
PostGIS vs DuckDB — Choosing the Right Tool for Spatial Data
A practical guide to OLTP vs OLAP for geospatial workloads. When to use PostGIS for serving and transactions, when DuckDB wins for analytics and batch processing, and how to combine both in a modern spatial data stack.
GeoServer Installation: A Step-by-Step Guide
Learn how to install GeoServer on your system with this comprehensive step-by-step guide. GeoServer is an open-source server used for managing and sharing geospatial data.
Computer vision3
Teaching a model to see — detection, segmentation and the architectures that replaced hand-built pipelines.
25 Years of Object Detection in 4 Walls (Sliding Window → YOLO → DETR)
Object detection shifted from sliding windows (145K per image) to YOLO's fixed grids (~8,400 boxes) to DETR's learned sets (100 queries). The breakthrough: replacing greedy non-maximum suppression with Hungarian matching in the loss function.
Vision Language Models — When AI Learns to See and Talk (Part 3 of 3)
The final piece: combining vision and language into unified models. From CLIP to GPT-4V, LLaVA, and Gemini — how VLMs understand images and text together, and why this changes everything.
Vision Transformers — How Transformers Learned to See (Part 2 of 3)
From CNNs to Vision Transformers — how splitting images into patches and applying self-attention revolutionized computer vision. A deep dive into ViT, DeiT, Swin, and the models that followed.