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

Last hour — read this, then stop

Updated 8 min read source
On this page11
  1. The three rules
  2. One line per answer
  3. Status codes that get confused
  4. Methods
  5. Postgres isolation
  6. Migrations on a busy table
  7. Index rules
  8. Retry or not
  9. Facts with dates
  10. Healthcare vocabulary
  11. Your numbers

Last hour — read this, then stop

One page for the hour before the call. Nothing here is new — it is the compressed form of Answers — say these out loud and 5 October — Senior Python Backend Engineer — prep map. After this, no new material.

The three rules

  1. 60 to 90 seconds, reasoned aloud. Context → options → decision → trade-off → result. A correct fifteen-second answer reads as mid-level.
  2. Never stop at “I don’t know”. “I haven’t used X, but I’ve done the same thing with Y, where the trade-off was…”
  3. Slow down. Twenty percent slower than feels natural. Short sentences. Close every answer: “So that’s how I’d approach it.”

One line per answer

The sentence each answer in Answers — say these out loud is built around.

  • Concurrency — asyncio for many waiting connections, threads for sync I/O libraries, processes for CPU-bound Python. Free-threading is official in 3.14, but opt-in.
  • Blocked loop — one blocking call stalls every request in the worker: p99 up everywhere, CPU idle. A def route, a thread, or an async driver.
  • Memory — refcounting frees at zero, the cycle collector handles cycles, RSS rarely shrinks — so peak usage sizes the process.
  • What’s new — 3.14: free-threading, subinterpreters, t-strings, lazy annotations. 3.15 on 9 October: lazy imports, frozendict, UTF-8 by default.
  • FastAPI or Django — FastAPI for I/O-heavy API services, Django when the ORM, admin and batteries carry the product. The framework stays at the edge.
  • REST design — nouns plus methods, meaningful status codes, one error shape, cursor pagination, additive changes, idempotency keys on POST.
  • Retrying a POST — a client-generated key; INSERT ... ON CONFLICT DO NOTHING decides the race; same key with a different body is a 422.
  • Slow query — pg_stat_statements to find, EXPLAIN (ANALYZE, BUFFERS) to understand, one fix, measure again.
  • Concurrent updates — Read Committed loses read-modify-write updates. A version column when rare, FOR UPDATE when hot, a constraint when possible.
  • Migrations — old and new code run together: expand/contract, CONCURRENTLY, NOT VALID then VALIDATE, batched backfills, always lock_timeout.
  • Flaky third party — adapter at the boundary; timeouts first; retry only transient errors, with backoff and jitter; circuit breaker; a queue if nobody waits.
  • Webhooks — HMAC over the raw body, acknowledge fast, dedupe on the event id with a unique constraint, reconcile by polling.
  • Service to service — sync only when the caller needs the answer; events for side effects; an outbox for the dual write; idempotent consumers.
  • Background jobs — idempotent tasks, acks_late, backoff, a DLQ someone reads, separate queues, scale on queue depth.
  • Mocking — stub what you do not own at the transport; never mock the database — real Postgres, rolled back per test.
  • Monolith or microservices — modular monolith first, split on a concrete pain, strangler fig, data last.
  • Scale 10× — the stateless tier scales out; the database is the ceiling: queries, pooling, cache, replicas, then partitioning.
  • Code review — correctness, design, operability, tests; tools own style; label blocking vs nit; small PRs.
  • Architecture decision — effort scales with the cost of reversal; options and trade-offs in an ADR; what we gave up, written down.
  • Incident — mitigate first, then diagnose; split coordination from investigation; blameless postmortem; detection time is the lever.
  • Patient data — encryption, per-request authorisation, an append-only audit log, minimisation, never in logs; a BAA or DPA with every vendor.
  • FHIR and HL7 — FHIR R4 over REST for anything new, HL7 v2 over MLLP in hospitals; conformance is to a profile; idempotent on the message id.
  • An LLM with patient data — a BAA with no retention, de-identification, or in-boundary inference — decided first; then an unreliable dependency like any other.

Status codes that get confused

Code Use it for
400 vs 422 unparseable request vs well-formed but invalid (FastAPI’s validation default)
401 vs 403 not authenticated vs authenticated but not allowed
404 instead of 403 a resource in another tenant — a 403 would confirm it exists
409 conflicts with current state: a stale version, a duplicate, a key still in flight
412 an If-Match precondition failed — the lost-update guard
429 rate limited; send Retry-After
202 accepted for async processing; return a status URL
502 / 503 / 504 bad upstream / unavailable / upstream timeout — retryable

Methods

Method Safe Idempotent
GET, HEAD yes yes
PUT, DELETE no yes
PATCH no depends on the body
POST no no — give it a key

Postgres isolation

Level What it means in Postgres
Read Committed (default) each statement sees what was committed before it started; read-modify-write in the app can lose updates
Repeatable Read one snapshot per transaction; a concurrent update to the same row raises a serialization error — retry
Serializable also detects write skew; retry on serialization failure (SQLSTATE 40001)

MySQL InnoDB defaults to Repeatable Read — the other half of the classic question.

Migrations on a busy table

Operation Safe?
add a nullable column, or one with a constant default yes — metadata only (constant defaults since PG 11)
add a column with a volatile default, such as gen_random_uuid() no — rewrites the table
SET NOT NULL directly scans under an exclusive lock — CHECK ... NOT VALID, VALIDATE, then SET NOT NULL
CREATE INDEX blocks writes — use CONCURRENTLY, outside a transaction
add a foreign key NOT VALID first, then VALIDATE CONSTRAINT
change a column’s type usually a rewrite — a new column and a backfill instead
rename or drop a column fast, but breaks running code — expand/contract
any DDL SET lock_timeout first, and retry on timeout

Index rules

  • Equality columns first, the range column last — a composite index is sorted by the tuple.
  • A function, a cast or a leading % on the column defeats the index; an expression index fixes the function case.
  • Foreign keys are not indexed automatically — an unindexed FK makes deleting a parent scan the child table.
  • When a query matches more than roughly 5-10% of the table, a sequential scan is the right plan.
  • A low-cardinality filter wants a partial index; INCLUDE columns enable index-only scans.
  • Every index taxes every write; pg_stat_user_indexes with idx_scan = 0 finds the dead ones.

Retry or not

Retry Do not retry
connection errors and timeouts, on idempotent calls 4xx other than 429
502, 503, 504 500 without thought — often a deterministic bug
429, honouring Retry-After a write without an idempotency key

Exponential backoff with full jitter, a low attempt cap, retries owned by one layer, deadlines propagated. A retry is load.

Facts with dates

Fact As of 2026-10
Python 3.14 current; 3.15.0 final due 9 October 2026 (rc3 shipped 2 October)
Free-threading officially supported in 3.14 (PEP 779); an opt-in python3.14t build
FastAPI threadpool 40 threads by default, shared by sync routes and sync dependencies
pymalloc objects up to 512 bytes; anything larger goes to the system allocator
Django 6.1 current, 5.2 the LTS
PostgreSQL 18 current — async I/O, uuidv7(), virtual generated columns
Problem Details RFC 9457, which replaced RFC 7807 in 2023
FHIR R4 is what is deployed; R5 has limited adoption; R6 is in ballot
EU AI Act transparency obligations and GPAI enforcement apply from 2 August 2026; high-risk obligations delayed to Dec 2027 / Aug 2028

Healthcare vocabulary

Term One line
PHI protected health information — health data tied to an identifiable person
HIPAA US rules for covered entities and their business associates: privacy, security, breach notification
BAA business associate agreement — required with every vendor that touches PHI: cloud, LLM API, error tracker
GDPR Art. 9 EU: health data is a special category — it needs an Art. 9 condition on top of a lawful basis, plus minimisation, DPIAs, erasure rights
DPA GDPR’s controller-processor contract (Art. 28) — the BAA’s European counterpart
Audit log who accessed which record, and when — append-only, kept for years, a functional requirement
De-identification Safe Harbor (remove the 18 identifiers) or Expert Determination
FHIR REST and JSON resources — Patient, Observation, Encounter; profiles make them strict
HL7 v2 pipe-delimited hospital messages over MLLP, with ACK/NAK; resent on timeout
LOINC / SNOMED CT / ICD-10 / RxNorm lab tests / clinical terms / diagnoses / medications

Your numbers

Fill these in before the call. An answer with one of them in it lands; an answer without one sounds read from a page.

  • Years: “over five years” — the resume says 5+, so say exactly that
  • Your best query fix: [before] → [after], and the cause: [ ]
  • Your busiest service: [requests per second, or users]
  • Your biggest table: [rows]
  • An incident: [what broke, how long, how you found out, what changed]
  • A mentoring result: [who, what changed, how you could see it]
  • A decision you drove: [the options, the choice, what it cost]