#Computer Science

Articles about Computer Science — exploring patterns, best practices, and real-world implementations in production systems.

32 posts tagged with computer science. ← All posts

#A2A (14)#ADK (8)#AG-UI (6)#AI (9)#AI Agents (311)#AI Architecture (10)#AI Cost (10)#AI Cost Optimization (8)#AI Engineering (201)#AI Evaluation (8)#AI Governance (29)#AI Red Teaming (9)#AI Research (9)#AI Safety (8)#AI Security (21)#AI in Production (12)#AML (3)#API Design (10)#API Security (8)#APIs (55)#AWS (17)#Accounting (9)#Agent Skills (3)#Agentic AI (24)#Agentic Commerce (12)#Agentic RAG (8)#Agents (4)#Amazon Bedrock (8)#Analytics (3)#Architecture (36)#Audit (3)#Authentication (11)#Authorization (3)#Automation (6)#Azure (11)#Azure AI Foundry (9)#Backend Engineering (310)#Benchmarks (3)#Best Practices (3)#BigQuery (6)#Business Finance (8)#Business Strategy (55)#C (8)#CI/CD (8)#Caching (10)#Capital Markets (14)#Card Payments (12)#Cards (13)#Career (24)#Checkpointing (4)#Claude Code (8)#Cloud (5)#Cloud Architecture (3)#Cloud Native (10)#Code Review (8)#Collaboration (5)#Communication (9)#Compliance (52)#Computer Networking (9)#Computer Science (32)#Computer Vision (5)#Concurrency (37)#Consulting (3)#Containers (10)#Context Engineering (10)#Cost Optimisation (5)#Credit (14)#Credit Risk (14)#CrewAI (8)#Crypto (12)#Cryptocurrency (12)#Cryptography (8)#Custody (9)#DSPy (8)#Data (13)#Data Engineering (12)#Data Structures (9)#Databases (37)#Deployment (3)#Design Patterns (10)#DevOps (16)#DevSecOps (11)#Developer Experience (5)#Developer Tools (5)#Distributed Systems (94)#Documentation (3)#Edge AI (8)#Embeddings (15)#Emotional Intelligence (8)#Energy (8)#Engineering (11)#Engineering Culture (3)#Engineering Practices (16)#Error Handling (4)#Evaluation (53)#Event-Driven Architecture (8)#FREE-AI (8)#FX (5)#Feedback (4)#FinOps (23)#FinTech (6)#Financial AI (14)#Financial Systems (129)#Fine-Tuning (11)#Fintech (131)#Flutter (8)#Foreign Exchange (5)#Forward Deployed Engineer (8)#Forward Deployed Engineering (8)#Fraud (10)#Function Tools (5)#Functional Programming (3)#Fundraising (8)#GCP (5)#Gemma (4)#Generative AI (3)#Git (8)#Go (220)#Go-to-Market (8)#Google ADK (36)#Governance (56)#Granite (6)#GraphQL (3)#Growth (3)#Guardrails (25)#HIPAA (3)#HTTP (3)#Harness Engineering (8)#Hiring (8)#Hugging Face (8)#Human-in-the-Loop (8)#IBM watsonx (8)#Identity (11)#Integration (3)#Intellectual Property (8)#Interfaces (3)#JavaScript (8)#KYC (11)#KYC and AML (12)#Kafka (10)#Kubernetes (17)#LLM (5)#LLM Inference (8)#LLM-as-Judge (3)#LLMs (135)#LangChain (8)#LangGraph (11)#Leadership (26)#Ledger (12)#Legal (8)#Lending (14)#LlamaIndex (8)#MCP (22)#MLOps (31)#Machine Learning (32)#Marketing (16)#Markets (4)#Memory (15)#Memory Management (5)#Metrics (6)#Microservices (3)#Microsoft Agent Framework (150)#Middleware (6)#Migration (9)#Monitoring (3)#Multi-Agent (10)#Multi-Agent AI (14)#Multi-Agent Systems (73)#Multimodal (3)#Multimodal AI (8)#NIM (5)#NVIDIA (8)#OAuth (3)#OWASP (7)#Observability (44)#On-Device AI (8)#Open Source (7)#OpenTelemetry (5)#Operating Systems (8)#Operations (10)#Opinion (6)#Orchestration (10)#Organizational Design (8)#Payment Rails (16)#Payments (54)#People (8)#Performance (43)#Platform Engineering (9)#PreSales (8)#Privacy (5)#Privacy Engineering (3)#Process (4)#Product (27)#Product Management (8)#Production (8)#Programming (10)#Programming Languages (48)#Prompt Engineering (66)#Prompt Injection (6)#Protocol Buffers (3)#Protocols (9)#Providers (4)#Pydantic AI (8)#Python (142)#Quality (3)#RAG (58)#RBI (3)#REST (5)#Rails (16)#Reasoning Models (8)#Reconciliation (3)#RegTech (8)#Regulation (9)#Reliability (48)#Resilience (4)#Responsible AI (5)#Retrieval (3)#Risk (13)#Rust (32)#SRE (21)#Sales (9)#Scalability (3)#Security (81)#Security Engineering (8)#Self-Evolving Agents (16)#Sessions (3)#Settlement (9)#Soft Skills (8)#Software (3)#Software Architecture (36)#Software Engineering (144)#Spanner (4)#Startups (30)#Strands (8)#Streaming (28)#Structured Output (4)#Sustainability (8)#System Design (32)#Systems Programming (48)#Testing (49)#Tool Use (22)#Tooling (4)#Tools (3)#Trading (8)#Treasury (6)#Type System (3)#Type Systems (11)#TypeScript (8)#Vector Databases (21)#Vector Search (11)#Venture Capital (8)#Version Control (8)#Web Development (6)#Workflows (14)#gRPC (13)#smolagents (8)
Pratik Dhanave · ·6 min read

Rewriting History Safely

Git lets you rewrite history — amend a commit, squash a messy branch, drop a secret that was committed by mistake. But "rewrite" is a misnomer: you never edit a commit, you replace it with a new one and move a pointer. Once you understand that, the rules for doing it safely become obvious, and the one genuine danger — rewriting history other people are building on — comes into sharp focus. This closing post turns the whole series into a working discipline.

"Rewrite" is a misnomer: you never edit a commit, you replace it with a new one and move a pointer. Once you see that, the rules for doing it safely become obvious — and the one real danger, rewriting history others build on, comes into sharp focus. The capstone that turns the series into a discipline.

Pratik Dhanave · ·5 min read

Remotes, Refspecs, and How Fetch and Push Work

Collaboration in Git is the same object model, stretched across two repositories. A remote is just a named URL; a remote-tracking branch is just a local pointer that remembers where the other side was; fetch and push are just object transfers plus ref updates, governed by a small syntax called the refspec. Nothing new is invented for the network — it's the graph and the pointers, reaching across a wire.

Collaboration in Git is the same object model stretched across two repositories. A remote is a named URL; a remote-tracking branch is a pointer remembering where the other side was; fetch and push are object transfers plus ref updates governed by refspecs. The network adds almost no new concepts.

Pratik Dhanave · ·5 min read

The Reflog: Git's Safety Net

"I lost my commits" is almost never true. A bad reset, a botched rebase, a deleted branch — the commits are usually still there, sitting unreachable in the object store, waiting out their grace period before garbage collection. The reflog is the log of everywhere your refs have been, and it's the tool that turns "I destroyed my work" into a thirty-second recovery. Knowing it exists changes how fearlessly you can use Git.

"I lost my commits" is almost never true. A bad reset or botched rebase leaves the commits sitting unreachable in the object store, waiting out a grace period. The reflog is the log of everywhere your refs have been — the tool that turns "I destroyed my work" into a thirty-second recovery.

Pratik Dhanave · ·8 min read

System Calls, and Why OS Knowledge Matters

You can build software for years treating the operating system as a black box — and then one day a production mystery (a service that's slow for no reason, a memory crash, a concurrency heisenbug, a server that won't scale) has an answer that lives entirely below your framework. OS knowledge is what lets you see down there. This closing post shows how everything in the series connects, through the system-call boundary and the diagnostic power it gives you.

You can build software for years treating the OS as a black box — then a production mystery has an answer that lives entirely below your framework. OS knowledge is what lets you see down there. How everything connects, through the system-call boundary and the diagnostic power it gives.

Pratik Dhanave · ·5 min read

Packfiles and How Git Stays Small

A snapshot-per-commit model sounds like it should balloon a repository to enormous size. It doesn't — a project with a decade of history often clones smaller than a single day's build artifacts. The trick is packfiles: Git periodically takes its loose objects, deltas the similar ones against each other, and compresses the result. This is where "Git stores snapshots" and "Git repositories are tiny" stop seeming contradictory.

A snapshot-per-commit model sounds like it should balloon a repository, yet a decade of history often clones smaller than a day's build artifacts. Packfiles are the trick: Git deltas similar objects against each other and compresses the result — a storage layer under the snapshot model, invisible in daily use.

Pratik Dhanave · ·8 min read

I/O and the I/O Models

The difference between a server that handles a hundred connections and one that handles a hundred thousand on the same hardware usually comes down to one choice: how it does I/O. Blocking, non-blocking, and asynchronous I/O aren't interchangeable styles — they're fundamentally different models with different scaling limits, and understanding them explains async/await, event loops, and why the network stack works the way it does.

The difference between a server handling a hundred connections and one handling a hundred thousand usually comes down to one choice: how it does I/O. Blocking, non-blocking, and asynchronous I/O are fundamentally different models with different scaling limits.

Pratik Dhanave · ·6 min read

Merge and Rebase, Demystified

Merge and rebase are where Git's DAG earns its keep — and where most fear lives. Both integrate one line of work into another; they differ only in the shape of history they leave behind. Merge preserves the fork and records a convergence; rebase rewrites your commits as if you'd started later, producing a straight line. Neither is magic. Once you know what a merge base is, both become predictable.

Merge and rebase both integrate one line of work into another; they differ only in the shape of history they leave. Merge preserves the fork and records a convergence; rebase replays your commits as new objects into a straight line. Once you know what a merge base is, both become predictable.

Pratik Dhanave · ·7 min read

The Memory Hierarchy and Caching

The single most counterintuitive fact in performance engineering: accessing memory is not one speed. A value in the CPU cache is hundreds of times faster to reach than one in main memory, which is thousands of times faster than disk. Your code's speed often depends less on how many operations it does than on where the data lives — and understanding the memory hierarchy is what lets you see that.

The most counterintuitive fact in performance: accessing memory is not one speed. A value in CPU cache is hundreds of times faster to reach than one in RAM. Your code's speed often depends less on how many operations it does than on where the data lives.

Pratik Dhanave · ·6 min read

The Index: Git's Staging Area

Every Git user meets the staging area on day one — `git add` puts things there, `git commit` takes them out — but almost nobody knows what it actually is. The index is a real file, a binary snapshot-in-progress that sits between your working directory and the object store. Understanding it turns `add`, `reset`, and the difference between "staged" and "modified" from memorized rules into a picture you can see.

Everyone meets the staging area on day one, but almost nobody knows what it is: a real binary file holding a snapshot-in-progress between your working directory and the object store. Understanding the index turns add, reset, and the staged-vs-modified distinction into a picture you can see.

Pratik Dhanave · ·7 min read

Virtual Memory

Every process believes it has the whole machine's memory to itself, starting at address zero, contiguous and private — and none of that is literally true. Virtual memory is the elaborate illusion the OS and hardware maintain to make it true enough, and it's simultaneously what gives processes isolation, what lets you run programs bigger than RAM, and the reason a stray pointer segfaults instead of corrupting another program.

Every process believes it has the whole machine's memory to itself — and none of that is literally true. Virtual memory is the elaborate illusion the OS and hardware maintain, giving isolation, letting you run programs bigger than RAM, and making a stray pointer segfault instead of corrupting others.

Pratik Dhanave · ·6 min read

Refs, HEAD, and the Commit DAG

If commits are content-addressed and immutable, how does anything ever move forward? The answer is refs: tiny mutable files, most of them containing nothing but a 40-character hash. A branch is not a copy of your work or a container for commits — it is a single sticky note pointing at one commit. Understanding that branches are pointers, and history is a graph, dissolves most of the confusion around Git.

A branch is not a copy of your work or a container for commits — it is a ~41-byte file holding one hash. Understanding that refs are movable pointers, HEAD points at your current branch, and history is a directed acyclic graph dissolves most Git confusion via one idea: reachability.

Pratik Dhanave · ·6 min read

CPU Scheduling

Your machine runs hundreds of processes on a handful of CPU cores, and yet everything feels like it's running at once. That illusion is the CPU scheduler's doing — rapidly switching the cores between processes, dozens of times a second, deciding who runs and for how long. Understanding scheduling explains why your program isn't always running, why context switches cost, and why "add more threads" doesn't always mean faster.

Your machine runs hundreds of processes on a handful of cores, yet everything feels simultaneous. That illusion is the scheduler's doing — rapidly switching cores between processes. It explains why your program isn't always running and why more threads isn't always faster.

Pratik Dhanave · ·5 min read

The Git Object Model

Git looks like a tool for tracking changes, but underneath it is something simpler and stranger: a small content-addressed key-value store. Four object types — blob, tree, commit, tag — are all it keeps, each named by the hash of its own bytes. Once you see that everything else (branches, history, staging) is a thin layer over these four objects, Git stops being a bag of memorized commands and becomes a system you can reason about.

Underneath the commands, Git is a small content-addressed key-value store built on four object types — blob, tree, commit, tag — each named by the hash of its own bytes. Seeing that everything else is a thin layer over these objects turns Git from memorized incantations into a system you can reason about.

Pratik Dhanave · ·7 min read

Threads and Concurrency

A thread lets one process do several things at once — and the moment you have two threads touching the same memory, you've entered the hardest territory in all of programming: concurrency. Race conditions, deadlocks, and the need for synchronization are not exotic edge cases; they're the fundamental consequences of shared mutable state, and understanding them is what separates working concurrent code from code that fails mysteriously.

A thread lets one process do several things at once — and the moment two threads touch the same memory, you're in the hardest territory in programming: concurrency. Race conditions, deadlocks, and synchronization are the fundamental consequences of shared mutable state.

Pratik Dhanave · ·7 min read

Processes

A process is the OS's answer to "what is a running program?" — and it's more than the code: it's the code plus its own private memory, its own resources, and its own isolated view of the machine, as if it owned the computer. That isolation is what lets many programs run at once without corrupting each other, and understanding it explains a huge amount of how systems behave.

A process is the OS's answer to 'what is a running program?' — more than the code: it's the code plus its own private memory, resources, and isolated view of the machine. That isolation is what lets many programs run at once without corrupting each other.

Pratik Dhanave · ·7 min read

What an Operating System Does

You write applications that run on top of an operating system every day, and mostly you can ignore it — until a performance mystery, a concurrency bug, or a resource limit forces you to understand what's underneath. The OS is doing two jobs for you constantly: managing the hardware's finite resources, and giving you clean abstractions over messy reality. Understanding those two jobs is understanding the machine your code actually runs on.

You write applications on top of an OS every day and mostly ignore it — until a performance mystery, concurrency bug, or resource limit forces you to understand it. The OS does two jobs: managing finite hardware, and abstracting messy reality. Understanding them is understanding the machine your code runs on.

Pratik Dhanave · ·8 min read

Applied Cryptography: Pitfalls and a Decision Guide

The primitives in this series are unbreakable in practice — and yet crypto keeps failing in the real world. That's the paradox of applied cryptography: almost every vulnerability is a misuse of a sound primitive, not a broken one. A predictable random number, a comparison that returns early, a reused nonce, a missing authentication check — each is a one-line mistake that silently voids the guarantee. This closing post catalogs the pitfalls that matter and distills the whole series into a decision guide.

The primitives are unbreakable in practice, yet crypto keeps failing — because almost every vulnerability is a misuse of a sound primitive, not a broken one. A predictable random number, an early-exit comparison, a reused nonce: one-line mistakes that silently void the guarantee. Plus a decision guide.

Pratik Dhanave · ·8 min read

Key Management: The Hardest Part

Every cryptographic guarantee in this series ultimately rests on one thing: the key stays secret and available to exactly the right parties. That's not a math problem — it's an operational one, and it's where real systems fail. A perfect algorithm with a key committed to a Git repo, hardcoded in an image, or never rotated is worthless. Key management is the unglamorous discipline that decides whether all the cryptography actually protects anything.

Every cryptographic guarantee rests on one thing: the key stays secret and available to exactly the right parties. That's not a math problem — it's an operational one, and it's where real systems fail. A perfect algorithm with a key committed to Git is worthless.

Pratik Dhanave · ·7 min read

TLS: Where It All Comes Together

TLS is the protocol securing nearly every connection you make, and it's not a single cryptographic trick — it's the whole toolkit orchestrated into one handshake. Key exchange, certificates, signatures, and authenticated encryption each solve one sub-problem, and TLS composes them so that two parties who've never met can establish a private, tamper-proof, authenticated channel over a hostile network. Understanding the handshake is understanding how every earlier piece fits.

TLS secures nearly every connection you make, and it's not a single trick — it's the whole toolkit orchestrated into one handshake. Key exchange, certificates, signatures, and AEAD each solve one sub-problem, and TLS composes them into a private, authenticated channel over a hostile network.

Pratik Dhanave · ·8 min read

Digital Signatures and Public-Key Infrastructure

A public key lets anyone encrypt to you and verify your signatures — but it raises a new question: how do you know a public key really belongs to who it claims? If an attacker can substitute their own public key for the bank's, all the cryptography in the world protects your connection to the attacker. Solving "whose key is this?" is what certificates, certificate authorities, and chains of trust exist for — the plumbing that makes public keys into verifiable identities.

A public key lets anyone verify your signatures — but how do you know a public key really belongs to who it claims? If an attacker substitutes their key for the bank's, all the cryptography protects your connection to the attacker. Certificates, CAs, and chains of trust solve 'whose key is this?'

Pratik Dhanave · ·7 min read

Public-Key Cryptography

Symmetric encryption has a chicken-and-egg problem: to share a secret key securely, you seem to need a secure channel — which is what you were trying to build. Public-key cryptography is the astonishing idea that broke that loop: two mathematically-linked keys where knowing the public one doesn't reveal the private one. It's the foundation of key exchange, digital signatures, and essentially all secure communication over the open internet.

Symmetric encryption has a chicken-and-egg problem: sharing a secret key securely seems to need a secure channel. Public-key cryptography broke that loop — two mathematically-linked keys where the public one doesn't reveal the private. It's the foundation of key exchange and signatures.

Pratik Dhanave · ·7 min read

Hashing, MACs, and Storing Passwords

"Just hash the password" is advice that's simultaneously right and dangerous — right that you never store plaintext, dangerous because a fast cryptographic hash like SHA-256 is exactly the wrong tool for passwords. Hashing, message authentication, and password storage are three different jobs that all involve hashing, and confusing them is a classic source of real breaches.

'Just hash the password' is simultaneously right and dangerous — right that you never store plaintext, dangerous because a fast hash like SHA-256 is the wrong tool for passwords. Hashing, MACs, and password storage are three different jobs that all involve hashing.

Pratik Dhanave · ·7 min read

Symmetric Encryption and Authenticated Encryption

Symmetric encryption is the workhorse of confidentiality — the same fast primitive protecting your disk, your database fields, and every byte inside a TLS connection. But "encrypt this" is a trap: raw encryption alone doesn't stop tampering, block ciphers need a mode of operation, and modes need nonces that must never repeat. The single right answer for almost every case is authenticated encryption, and this post explains why.

Symmetric encryption is the workhorse of confidentiality — but 'encrypt this' is a trap. Raw encryption doesn't stop tampering, block ciphers need a mode, and nonces must never repeat. The right answer for almost every case is authenticated encryption (AEAD), and this post explains why.

Pratik Dhanave · ·8 min read

What Cryptography Actually Gives You

Most engineers reach for cryptography wanting "make this secure," but crypto doesn't provide "secure" — it provides four specific, separable guarantees, and using the wrong one (encrypting when you needed to authenticate, hashing when you needed to encrypt) is how most real-world crypto failures happen. This series is about using cryptography correctly as an engineer who builds on top of it, not about inventing it.

Most engineers reach for cryptography wanting 'make this secure' — but crypto doesn't provide 'secure.' It provides four specific, separable guarantees: confidentiality, integrity, authenticity, and non-repudiation. Using the wrong one is how most real-world crypto failures happen.

Pratik Dhanave · ·7 min read

Structs, Unions, and Data Structures

Structs let you bundle related data into a single named type — the closest C gets to an object. Combined with pointers and heap allocation, they're how you build every data structure C is famous for: linked lists, trees, hash tables. This post covers structs, their cousins unions and enums, the memory-layout details that bite (padding), and puts it all together to build a linked list from scratch.

Structs let you bundle related data into a single named type — the closest C gets to an object. Combined with pointers and heap allocation, they're how you build every data structure C is famous for: linked lists, trees, hash tables. This post covers structs, unions, enums, the padding that bites, and builds a linked list from scratch.

Pratik Dhanave · ·7 min read

Dynamic Memory Management

Stack memory is automatic but rigid — sized at compile time and gone when a function returns. For data whose size you only know at runtime, or that must outlive the function that created it, C gives you the heap and four functions to manage it: `malloc`, `calloc`, `realloc`, and `free`. With that power comes C's heaviest responsibility: every allocation you make, you must free — exactly once, and never use again.

Stack memory is automatic but rigid. For data whose size you only know at runtime, or that must outlive its function, C gives you the heap and four functions: malloc, calloc, realloc, and free. With that power comes C's heaviest responsibility: every allocation you make, you must free — exactly once, and never use again.

Pratik Dhanave · ·6 min read

Pointers

Pointers are the heart of C, the feature that makes it powerful and the one that makes it dangerous. A pointer is just a variable that holds a memory address — but that simple idea is how C functions modify their callers, how arrays and strings work, how dynamic memory is managed, and how data structures are built. Everything hard and everything essential in C runs through pointers.

Pointers are the heart of C — the feature that makes it powerful and the one that makes it dangerous. A pointer is just a variable holding a memory address, but that simple idea is how C functions modify their callers, how arrays and strings work, how dynamic memory is managed, and how data structures are built. Everything essential runs through pointers.

Pratik Dhanave · ·6 min read

Control Flow, Functions, and the Stack

C's control flow is the ancestor of the syntax you already know — `if`, `while`, `for`, `switch`. Its functions look familiar too, but they hide a defining C fact: arguments are passed by value, always copied. Understanding pass-by-value, and the call stack that makes function calls work, is the bridge to the hardest and most important topic in C — pointers.

C's control flow is the ancestor of the syntax you already know, and its functions look familiar too — but they hide a defining C fact: arguments are passed by value, always copied. Understanding pass-by-value, and the call stack that makes function calls work, is the bridge to the hardest and most important topic in C: pointers.

Pratik Dhanave · ·6 min read

Types, Variables, and Operators

In C, a type is a promise about how many bytes a value occupies and how to interpret them. There's no hidden bignum, no automatic string, no safety rail — just fixed-width integers, floating-point, and the bit patterns underneath. Understanding C's types means understanding sizes, signedness, and the surprising rules of integer promotion, because in C the difference between `int` and `unsigned` can be the difference between correct and catastrophically wrong.

In C, a type is a promise about how many bytes a value occupies and how to interpret them — no hidden bignum, no safety rail, just fixed-width integers and the bits underneath. Understanding C's types means understanding sizes, signedness, and the surprising rules of integer promotion, where the difference between int and unsigned can be catastrophic.

Pratik Dhanave · ·6 min read

Why C, and How It Compiles

C is fifty years old and still runs the world — operating systems, databases, language runtimes, embedded devices, and the standard libraries under almost everything else. Learning C is learning how computers actually work: memory, pointers, and the thin layer between your code and the machine. This series builds C from the ground up, and it starts with what C is and what really happens when you compile it.

C is fifty years old and still runs the world — operating systems, databases, language runtimes, embedded devices. Learning C is learning how computers actually work: memory, pointers, and the thin layer between your code and the machine. This series builds C from the ground up, starting with what C is and what really happens when you compile it.

Pratik Dhanave · ·8 min read

Caching Fundamentals

A cache lives or dies by one number: its hit rate. Every cache access is a small bet — that the data will be there (a hit, served fast) rather than missing (a miss, served slow, plus the overhead of caching it). Whether caching helps at all comes down to how often that bet pays off, and understanding hits, misses, and hit rate — and what you should and shouldn't cache — is the foundation of using caches effectively. Get these fundamentals right, and the rest of caching makes sense.

A cache lives or dies by one number: its hit rate. Every cache access is a small bet — that the data will be there (a hit, served fast) rather than missing (a miss, served slow). Whether caching helps at all comes down to how often that bet pays off.

Pratik Dhanave · ·8 min read

Why Caching Exists

There's an old joke that there are only two hard things in computer science: cache invalidation and naming things. It's a joke because caching is everywhere and sounds simple — just keep a copy of stuff you'll need again — and it's true because getting caching right is genuinely, surprisingly hard. Caching is one of the most universal and powerful ideas in computing, appearing at every layer from CPU to CDN, and understanding why it exists and when it helps is foundational to building fast systems.

There's an old joke that there are only two hard things in computer science: cache invalidation and naming things. It's a joke because caching sounds simple, and true because getting it right is genuinely hard. Caching is one of the most universal ideas in computing, appearing at every layer from CPU to CDN.

All posts on this site are written by Pratik Dhanave, an Agentic AI Architect with 7+ years building production distributed systems, multi-agent AI platforms, and cloud-native infrastructure. About the author → Each article includes working code, architecture diagrams, and references to the specific frameworks and standards discussed. Browse all posts or explore related topics using the tag cloud above.