Living Systems Handbook microservices as humans Bipin Singh
Anatomy of one human

Hands

2 min readChapter 09 of 34By Bipin Singh

Hands let a human change the world: pick something up, write, pay. A microservice's hands are its outbound integrations — calls to other services, third-party APIs (payment gateways, SMS providers, LLM APIs) and AWS services. Hands are powerful and dangerous: the outside world can be slow, broken or expensive.

What hands typically do

Action Example
Call another internal service The Cashier asks the Waiter for the order total
Call a third-party API Charge a card via a payment provider; send an SMS
Call an AI model Summarise customer feedback
Use AWS services Store a receipt PDF in S3

Five rules for safe hands

1. Always use a timeout

Never wait forever. If the payment provider usually answers in 300 ms, a 3-second timeout is generous. Without one, a slow partner keeps your human (and your bill) running until Lambda's own timeout.

const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), 3000);
try {
  const res = await fetch(`${process.env.PAYMENTS_URL}/charges`, {
    method: "POST",
    headers: { "Content-Type": "application/json", "Idempotency-Key": orderId },
    body: JSON.stringify({ amount, currency: "INR" }),
    signal: controller.signal,
  });
  if (!res.ok) throw new Error(`Payment failed: ${res.status}`);
  return await res.json();
} finally {
  clearTimeout(timer);
}

2. Retry carefully, with backoff

Temporary failures are normal. Retry a few times with exponential backoff and jitter (wait 200 ms, 400 ms, 800 ms… plus randomness) — but only for errors that might succeed next time, and only for operations that are idempotent (notice the Idempotency-Key header above: the provider won't charge twice).

If the work came from an SQS queue, the simplest retry is to let the message fail and return to the queue; after a few attempts it moves to a dead-letter queue for investigation.

3. Don't keep hitting a broken thing

If a partner is down, hammering it makes everything worse. A circuit breaker stops calls for a while after repeated failures, then tries again carefully. In serverless designs, queues plus dead-letter queues and Step Functions retries often give the same protection with less code.

4. Keep the keys in your pocket, not your hand

API keys and passwords belong in Secrets Manager (or Parameter Store), fetched at runtime and cached briefly — never hard-coded or committed to Git.

5. Prefer letters for slow or risky work

If an action is slow or might fail, don't do it while a customer waits. Put a message in a queue, acknowledge the customer, and let a worker's hands do it in the background.

Hands that call other humans

When one service calls another synchronously, it creates a dependency. Prefer:

Key idea

Hands should be gentle with the world: time out, retry only what's safe, back off when others are struggling, and never carry secrets openly.

Bipin Singh
Written by Bipin Singh

Senior Full-Stack Engineer · AI & AWS. I design and build serverless systems on AWS — and love explaining them simply.

Work with me