Skip to content

Part 3: How Do Chinchillas Talk?

A lone chinchilla only needs to manage itself. But a COLONY of chinchillas needs communication. Who talks to whom? How? What if a message gets lost?

The problem: A chinchilla finds a big cache of seeds. It needs to tell the others. Options:

  1. Run to each chinchilla individually and whisper the location (reliable, but slow)
  2. Stand on a rock and squeak (fast, but not everyone might hear)

The principle: There’s a fundamental tradeoff between targeted, reliable communication and fast, broad communication.

Synchronous (whispering): Caller sends a request, WAITS for a response. Like a phone call: both parties engaged. The caller blocks until it gets an answer.

  • Pro: You KNOW if it worked. You get an immediate response.
  • Con: If the other party is slow, YOU are slow. If they’re down, you’re stuck.

Asynchronous (squeaking into the void): Caller sends a message and moves on. Someone picks it up later. Like leaving a voicemail: you don’t wait.

  • Pro: The caller is never blocked. Sender and receiver don’t need to be alive at the same time.
  • Con: You don’t know immediately if it worked. More complex error handling.

The instinct question: “Does the caller need an answer RIGHT NOW?”

  • Yes -> Synchronous (API call, database query)
  • No -> Asynchronous (send email, queue a job, fire an event)

Instinct: SUSTAIN

The problem: Chinchilla A finds seeds. Chinchillas B, C, D, and E all need to know. But chinchilla A doesn’t know (or care) exactly who needs to know. And some chinchillas are napping: they’ll need the information when they wake up.

The solution: Chinchilla A posts a note to the colony board: “Seeds found near the old rock.” Anyone who cares will check the board.

The principle: Decouple the producer (who sends the message) from the consumer (who processes it). The board is the middleman.

Message queue: One message, one consumer. Like a to-do list: someone posts a task, ONE worker picks it up and does it. Once done, it’s removed from the queue. Examples: RabbitMQ, Amazon SQS.

  • Use when: “This job needs to be done ONCE by SOMEONE”
  • Pattern: Job queues, background processing, order processing

Pub/Sub (publish/subscribe): One message, MANY consumers. Like a newspaper: the publisher prints it, every subscriber gets a copy. Examples: Apache Kafka, Google Pub/Sub, Redis Pub/Sub.

  • Use when: “Everyone who cares should hear about this”
  • Pattern: Event notifications, real-time feeds, log aggregation

The key difference:

  • Queue: “Process this payment” -> ONE processor handles it
  • Pub/Sub: “User signed up!” -> Welcome email service hears it AND analytics service hears it AND notification service hears it

Tradeoff: A middleman adds latency and complexity, but gives you:

  • Decoupling (services don’t know about each other)
  • Buffer (if consumer is slow, messages pile up instead of timing out)
  • Replay (Kafka can replay messages from any point in time)

Instinct: SUSTAIN + SURVIVE

The problem: A chinchilla runs up to the seed warehouse. It needs 3 sunflower seeds. How does it ask? Does it squeak “GIMME FOOD”? Does it fill out a form? Does it whisper in code?

The principle: Systems need a shared language for making requests. That language should be predictable, well-documented, and resistant to misunderstanding.

REST (Representational State Transfer): The most common API style. Resources are things (nouns): /seeds, /chinchillas/42. Actions are HTTP methods (verbs): GET, POST, PUT, DELETE.

  • GET /seeds/7 = “give me seed #7”
  • POST /seeds = “create a new seed”
  • PUT /seeds/7 = “replace seed #7 completely”
  • DELETE /seeds/7 = “remove seed #7”
  • Pro: Simple, stateless, cacheable, universally understood
  • Con: Over-fetching (you wanted the seed’s name but got its whole life story) and under-fetching (you need the seed AND its burrow, but that’s two requests)

GraphQL: The client specifies EXACTLY what data it wants. Like ordering at a restaurant: “I want the seed name, the burrow location, and nothing else.”

  • Pro: No over-fetching or under-fetching. One request gets exactly what you need.
  • Con: More complex server-side. Caching is harder. Easy to write expensive queries accidentally.

gRPC: Binary protocol using Protocol Buffers. Faster than REST (compact binary vs verbose JSON). Supports streaming.

  • Pro: High performance, strongly typed, bidirectional streaming
  • Con: Not human-readable. Harder to debug. Requires code generation.

How to choose:

  • Public API for third parties? -> REST (everyone knows it)
  • Mobile app with varied data needs? -> GraphQL (minimize network calls)
  • Internal microservice-to-microservice? -> gRPC (performance matters, both sides controlled)

Instinct: AGREE + ORGANIZE

The problem: 1,000 chinchillas all running to the same seed warehouse at the same time. The warehouse has one entrance. Bottleneck. Chaos.

The solution: Put a dispatcher out front. The dispatcher directs chinchillas to different entrances, checks their credentials, and turns away chinchillas who are asking too fast.

The principle: A layer between clients and servers that handles routing, security, and traffic management.

Load balancer: Distributes incoming requests across multiple servers.

  • Round-robin: Server 1, 2, 3, 1, 2, 3… (simple, doesn’t account for server load)
  • Least connections: Send to whichever server has the fewest active requests
  • Weighted: Fast server gets 3x the traffic of slow server
  • Consistent hashing: Each client always goes to the same server (good for caching)

API Gateway: Like a smart load balancer that also handles:

  • Authentication (is this chinchilla allowed in?)
  • Rate limiting (is this chinchilla asking too much?)
  • Request transformation (translate the question format)
  • Caching (we already answered this 5 seconds ago, here’s the cached response)

Reverse Proxy: Sits in front of servers, hides them from clients. Clients think they’re talking to one server, but the proxy forwards to many. Handles SSL termination, compression, caching.

Tradeoff: Every middleman adds latency (one more hop) and is a potential single point of failure (if the load balancer goes down, everything is down: so you need redundant load balancers).

Instinct: SUSTAIN + PROTECT

The problem: A chinchilla wants to know THE MOMENT a fox appears, not 30 seconds later when it checks the board.

The solution: Keep a constant connection open. The moment something happens, push a squeak through the open line.

The principle: Sometimes polling (“check every N seconds”) is too slow. You need the server to PUSH data to the client immediately.

Short polling: Client asks every N seconds: “Any foxes?” “No.” “Any foxes?” “No.” “Any foxes?” “YES!”

  • Pro: Simple. Works everywhere.
  • Con: Wasteful. 99% of requests return “no.” Delay up to N seconds.

Long polling: Client asks “Any foxes?” Server holds the connection open and WAITS until there IS a fox, then responds. Client immediately reconnects.

  • Pro: Near-instant response. Less wasteful than short polling.
  • Con: Holding connections open is expensive on the server.

WebSockets: A persistent, bidirectional connection. Both sides can send messages at any time. Like a two-way radio.

  • Pro: True real-time. Low latency. Efficient.
  • Con: More complex. Doesn’t work through all proxies. Need to handle disconnections.

Server-Sent Events (SSE): One-way stream from server to client. Server pushes, client listens. Like a radio broadcast.

  • Pro: Simpler than WebSockets. Built into HTTP. Auto-reconnect.
  • Con: One-way only. Client can’t send messages back through the stream.

How to choose:

  • Chat, gaming, collaboration -> WebSockets (bidirectional)
  • Live feeds, dashboards, notifications -> SSE (server push only)
  • Simple, low-frequency updates -> Long polling (works everywhere)

Instinct: SUSTAIN