Tech check / 5october ver 2 / 04_last_hour.md

Last hour, version 2 — read this, then stop

Updated 7 min read source
On this page12
  1. The three rules
  2. One line per new answer
  3. Typing
  4. Async
  5. Git
  6. Brokers
  7. Infrastructure as code
  8. PostgreSQL vs MySQL
  9. Kinds of test
  10. Regulated vocabulary this ad adds
  11. Facts with dates
  12. Your numbers

Last hour, version 2 — read this, then stop

One page for the hour before the second call: this ad’s new ground, compressed. The shared tables — status codes, Postgres isolation, migration locks, index rules, retry rules, healthcare vocabulary — are in version 1’s last-hour sheet and apply unchanged.

The three rules

  1. Precise about practice. Name the tool, the setting and the reason.
  2. Honest about gaps. “Not in production” — then the mechanism, then the closest thing you did.
  3. 60 to 90 seconds, reasoned aloud. Slow down; close every answer.

One line per new answer

The sentence each answer in Answers, version 2 — say these out loud is built around. The carried-over answers have theirs in version 1.

  • Type hints — annotate every boundary; Protocol for seams; Pydantic at the edge, dataclasses inside; strict mypy in CI, package by package; nothing enforced at runtime.
  • Async patterns — TaskGroup when tasks can fail; a semaphore acquired inside the coroutine; asyncio.timeout() on every wait; re-raise CancelledError; keep task references.
  • Project layout — one pyproject.toml; uv with a committed lockfile; src/ layout; packages by feature; typed settings from the environment; gates in CI.
  • FastAPI, Django or Flask — FastAPI for typed async APIs, Django for batteries, Flask for small sync services; the framework stays at the edge.
  • Evolving an API — additive by default; breaking means a new version plus Deprecation and Sunset; the committed spec is diffed in CI.
  • Postgres vs MySQL — InnoDB’s clustered index, transactional DDL only in Postgres, Read Committed vs Repeatable Read, utf8mb4.
  • Contract testing — the consumer records what it needs, the provider’s CI verifies it; it catches what a schema check can’t; for third parties, recordings plus a sandbox canary.
  • Git workflow — trunk-based; branches of a day or two; flags for unfinished work; protected main; squash merges; --force-with-lease.
  • Brokers — queue (RabbitMQ, SQS) or log (Kafka); Pub/Sub is managed fan-out; at-least-once everywhere, so idempotent consumers and an outbox.
  • Containers — multi-stage, slim, non-root, lockfile layer first; liveness touches nothing, readiness checks dependencies; graceful SIGTERM.
  • Branch to production — a gate at every step; one image promoted through environments; expand/contract migrations; rollback is the previous image; flags separate deploy from release.
  • IaC — declare, preview, apply; Terraform’s state is the risk; Pulumi is the same model in Python; CloudFormation manages state for you, and SAM is CloudFormation.
  • Instrumentation — OpenTelemetry auto-instrumentation; RED metrics with bounded labels; the trace id in every log; tail sampling in the collector; no PHI anywhere.
  • Performance — measure p99 first; find where the time goes; N+1, blocking calls, sequential I/O, pool size; prove it with a load test.
  • Regulated environments — controls that emit their own evidence; audit logging no code path can skip; IEC 62304 adds safety classes, traceability and SOUP.
  • AI tools — mechanical work yes, judgement no; tests first, small diffs, CI as the gate; no patient data in tools outside the boundary.

Typing

Need Use
an interface for a seam — a repository, a client Protocol; an ABC only when you want shared implementation
a generic function or class def first[T](xs: list[T]) -> T — PEP 695, Python 3.12+
untrusted input at the edge a Pydantic model, validated at runtime
a plain internal record @dataclass(frozen=True, slots=True)
the shape of JSON you don’t own TypedDict
a closed set of values Literal[...] or an Enum
an exhaustive match assert_never() in the fallthrough
typing a decorator ParamSpec
“anything” object if you only pass it along; Any switches checking off

Async

Situation Pattern
several tasks, any of which may fail async with asyncio.TaskGroup() — siblings cancelled, ExceptionGroup raised, caught with except*
a few independent reads, all-or-nothing asyncio.gather
at most N at once Semaphore(N), acquired inside the coroutine
a deadline around a block async with asyncio.timeout(5):
a sync library await asyncio.to_thread(fn)
CPU-bound work a process pool or a worker — never the loop
fire-and-forget keep a reference in a set; discard it when done
cleanup on cancel catch CancelledError, clean up, re-raise

Git

Merge button Result Use it when
merge commit keeps the branch, adds a merge commit long-lived or shared branches, libraries
squash and merge one commit per pull request on main trunk-based services — one-command revert
rebase and merge linear history, every commit kept small PRs whose commits each mean something

--force-with-lease, never --force. Never rebase a branch someone else is building on. GitFlow is for versioned software; services go trunk-based.

Brokers

Kafka RabbitMQ SQS Pub/Sub
model a retained log a queue with routing a managed queue a managed topic with subscriptions
after consumption stays; each consumer group has an offset deleted on ack deleted by the consumer acked per subscription
ordering per partition, by key per queue, with one consumer FIFO queues, per message group per ordering key
replay yes, within retention no no seek to a snapshot or a timestamp
fits events with many readers, streams commands, jobs, routing AWS jobs with no ops GCP fan-out

Infrastructure as code

Terraform Pulumi CloudFormation / SAM
language HCL Python, TypeScript, Go and others YAML or JSON
state a file you host and lock Pulumi Cloud or your own backend managed by AWS
clouds any any AWS only
preview / apply plan / apply preview / up change set / deploy
a failed apply partial; fix forward partial; fix forward automatic rollback

PostgreSQL vs MySQL

PostgreSQL MySQL (InnoDB)
table storage a heap; every index points into it clustered on the primary key
default isolation Read Committed Repeatable Read
DDL inside a transaction yes — a failed migration rolls back no — implicit commit
online schema change CONCURRENTLY, NOT VALID online DDL, else gh-ost or pt-online-schema-change
encoding trap — utf8 is three bytes; use utf8mb4

Kinds of test

Kind Proves Cost
unit the logic is right, in isolation milliseconds
integration your code works against the real database, broker, cache seconds; needs Docker
contract, consumer-driven the provider still gives each consumer what it needs fast; needs shared contract files
schema (OpenAPI) responses match the declared spec fast; only as good as the spec
end-to-end the whole path works slow and flaky — keep a handful

Regulated vocabulary this ad adds

Term One line
ISO 27001 certifies an information security management system
SOC 2 Type I / II an auditor’s report on controls — designed, on one date (I) / operating, over months (II)
IEC 62304 the lifecycle standard for medical-device software
Safety class A, B or C by the worst harm a failure could cause; it sets how much rigour applies
SOUP software of unknown provenance — every third-party library, listed with its version and assessed
Traceability requirement → design → test, in both directions

Facts with dates

Fact As of 2026-10
Kafka 4.x; ZooKeeper was removed in 4.0, so KRaft is the only mode
Terraform BSL licence since 2023; OpenTofu is the open-source fork
Kubernetes Gateway API is GA and the recommended path for HTTP routing; Ingress is feature-frozen
OpenTelemetry traces, metrics and logs are all GA
Python tooling uv for environments and locks; Ruff for lint and format; mypy the safe answer, pyright stricter, ty the newcomer
Python 3.14 is current; 3.15.0 final is due 9 October 2026

Your numbers

Version 1’s list holds — see it there. Add three for this ad:

  • A performance fix: [before] → [after], and the cause: [ ]
  • How long your CI pipeline took, and what you did to speed it up: [ ]
  • The size of a typical pull request on your last team: [ ]