Senior review — Python backend / AI engineer — prep map
Every theme from the technical-review feedback, brought to senior+ depth one article at a time (October 2026). Read top to bottom; tick an item once you can explain and defend it under questioning, not merely when you have read it. Bold is the article written or rewritten for this review; the rest add depth. Items were reviewed and approved between 2026-10-09 and 2026-10-15 (Elasticsearch, multi-agent systems and RAG at scale were added on the 15th); the summaries name what each article demonstrates, including the measured runs.
Priority: 🔴 core (asked, or flagged for depth) · 🟡 important · 🟢 breadth
🔴 Step 1 — Web & Networking
- You enter a URL — what happens next? — the walk from Enter to first paint, priced in round trips, and where each hop breaksWhat happens when you enter a URLDNSHTTPS handshake and keep-aliveCDN
- Protocols — HTTP/1.1 → 2 → 3, head-of-line blocking at each layer, why QUIC runs on UDPHTTP versions: 1.1, 2 and 3TCP vs UDPTLS and certificates
- OSI model — what each layer’s header lets a box see and decide; MTU vs MSS; L4 vs L7 and what the backend loses behind an L7 balancerOSI and TCP/IP modelsTCP vs UDPLoad balancersProxies
- HTTP and HTTP methods — safe, idempotent and cacheable as RFC 9110 defines them; conditional requests; what may be cached and for how long; request smugglingHTTP semantics and cachingHTTP basicsStatus codesCDN
- Idempotent methods (PUT as create-or-update, PATCH not guaranteed idempotent) — what idempotent really means, why the patch format decides, how preconditions make writes safe to retryPUT vs PATCH: which writes are safe to retryIdempotencyIdempotency keysTransactional outbox
- RESTful principles — Fielding’s constraints with what each buys and costs; why intermediaries need the uniform interface; resource modelling, non-CRUD actions, safe GET, long-running workREST principlesRichardson maturity and HATEOASStateful vs statelessVersioning and pagination
- WebSockets — the handshake and what the server can still refuse; frames, masking as a proxy-cache defence, close codes and the 1006 trap; when a WebSocket beats SSE or pollingThe WebSocket protocolConnection managementWebSocket vs alternativesScaling
- Short polling vs long polling — four options as one decision; the cost at 100,000 clients; a parked request on async vs sync servers; the cursor that stops missed events; proxy timeouts that set the holdShort polling vs long pollingWebSocket vs alternativesSocket.IOWebhooks
- SSE (Server-Sent Events) — the wire format and the browser’s exact parsing rules; when EventSource reconnects, resumes and gives up; resume from
Last-Event-ID; how a closed tab reaches your generator; buffering and idle timeouts at every hopServer-Sent EventsThe browser sideWebSocket vs alternativesShort vs long polling - RPC vs gRPC: what each is, the difference — RPC as a stub that makes a remote call look local, and why it leaks (latency, partial failure, no shared memory, independent deploys); XML-RPC, JSON-RPC 2.0 (MCP, Ethereum), Thrift, gRPC, Connect; gRPC as one HTTP/2 stream per call with status in trailers, field numbers, deadlines that propagate, 17 status codes, retry policy; measured: Protobuf 2.9x smaller and ~10x faster than stdlib json, under 2-3x vs orjson, 1.5x after gzip; ClusterIP pinning, reused field numbers, 4 MB limitRPC and gRPCAPI protocols comparedProtobufLoad balancing and gRPC-Web
🔴 Step 2 — Auth
- OAuth — front channel vs back channel; why auth code + PKCE is the one user flow (RFC 9700); OIDC on top; redirect URIs,
state, mix-up and code injection; sender-constrained tokens; a BFF for browser appsOAuth 2.0 and OpenID ConnectOIDC and OAuth flowsID, access and refresh tokensSSO attack vectors - JWT — what a valid signature does not prove (
aud,iss,exp,typ, stale claims); pinned algorithms;kidandjkuas attacker input; key caching and rotation; when an opaque token is the better choiceJWT pitfallsJWT basicsSigning algorithmsClaims - Access vs refresh tokens — two tokens, two jobs, and the refresh as the checkpoint; where each is checked; lifetimes and what they cost; browser storage stated correctly, with RFC 10017’s three architectures; a refresh endpoint without the usual bugsAccess and refresh tokensID, access and refresh tokensToken storage in the browserOAuth 2.0 and OIDC
- Refresh token rotation — families and reuse detection; who gets logged out, and the idle-victim gap; parallel tabs and lost responses; atomic compare-and-set rotation with a grace window; provider settings; DPoP as the alternativeRefresh token rotationAccess and refresh tokensRevocation and logoutOAuth 2.0 and OIDC
- Logout and token blacklisting — the strategies by latency and cost; a
jtidenylist whose TTL outlives the leeway; a per-user cutoff for logout everywhere; a denylist small enough to keep in every process; closing live sockets; logging out at the IdPJWT revocation and logoutRefresh token rotationJWT vs sessionsSingle logoutSession management - WebSocket authentication — what a browser handshake can carry; refusing before vs after
accept()(the 1006 trap) and a close-code policy; cookies with anOrigincheck, one-time tickets, the subprotocol trick; staying authenticated for hoursWebSocket and SSE authenticationWebSocket securityThe WebSocket protocolRevocation and logout - SSE auth —
EventSourcesends no headers; cookies and CORS (withCredentials); the one-time ticket that automatic reconnects spend; ending a stream at session expiry;fetchstreaming withAuthorization, as MCP requiresWebSocket and SSE authenticationServer-Sent EventsThe browser sideAccess and refresh tokens
🔴 Step 3 — Python language features
- Mutable vs immutable data types — what immutability means in CPython and what it buys (no copies, cached hashes, immortal objects);
+=dispatch and the tuple that raises and mutates; hashability; frozen dataclasses andfrozendict; shared-state failuresMutable vs immutable types__eq__vs__hash__Shallow vs deep copyArgument passing - Iterables vs iterators — what a
forloop really compiles to; iterable vs iterator, and the__getitem__protocolisinstancemisses; single-pass objects (files,map,zip) vs dict views;next(it, default), sentineliter,length_hint; mutating a collection mid-loopIterables and iteratorsGenerator exhaustionMutation during iterationitertools - Iterators and the
__next__dunder method — the contract: stay exhausted,__iter__returns self,StopIterationstays inside; broken iterators; lookup on the type and__iter__ = None; what a Python__next__costs; the async protocolIterables and iteratorsAsync coroutinesBehavioral patterns: Iterator - Generators and their benefits — what a suspended generator holds; what laziness buys, measured (memory, early exit, pipelines);
close(),GeneratorExitand when cleanup really runs; the pinned frame; PEP 479; when a generator is the wrong choiceGeneratorsyield fromsemanticscontextlibitertools - Decorators — what
@does at definition time (import time) and at call time;functools.wrapsand__wrapped__; arguments, async andParamSpec; class-based decorators on methods; cost per layer; production traps (import-time side effects,lru_cacheon methods, decorator order)DecoratorsDecorators with argumentsfunctools.wrapsParamSpec - Context managers — what
withexpands to and what__exit__decides (propagate, suppress, replace); where the guarantee stops (__enter__failing);@contextmanagerrules;ExitStackandpop_all; async cleanup under cancellation; leaks found with-X devContext managers and contextlibExceptions swallowed in finallyGeneratorsCancellation and timeouts
🔴 Step 4 — Python memory and internals
- Stack and heap memory — every object on the heap, frames hold references; where frames live (3.11 data stack, 3.12 no C stack for Python calls); the two recursion limits; why threads cost stacks and coroutines do not; what frames keep aliveStack and heap in PythonMemory modelArgument passingasyncio vs threads
- Memory model: allocation, reference counting, garbage collection — the object header; reference counting and why
getrefcountvaries by version; immediate, cascading freeing and where it is deferred; immortal objects; refcounting without the GIL; finalizersPython memory modelStack and heapweakrefGIL - Garbage collector — how cycles are found without a root set; thresholds by version and the 3.14.0-3.14.4 incremental collector that 3.14.5 reverted; what is tracked; pause cost measured with
gc.callbacks;gc.freeze()for prefork servers; leaks the collector cannot seePython memory model: the cycle collectorMemory profilingweakref - Memory management: heap, arenas, pools, blocks — the four allocator layers; blocks, 16 KiB pools and 1 MiB arenas (3.10+); why a process does not shrink (fragmentation, measured); mimalloc on the free-threaded build; inspecting and working around itThe allocator: arenas, pools, blocksMemory modelMemory profiling
__slots__ - Memory management in Python, deep — one object end to end; which number to read (RSS, USS, PSS,
tracemalloc, cgroup); four causes measured on Linux: a leak (lru_cacheon a method, found by snapshot diff), a plateau (glibc kept 201 MiB,malloc_trim→ 41), per-thread arenas (MALLOC_ARENA_MAX), copy-on-write after fork (46 MiB per worker, 0 withgc.freeze()); exit 137 in containers;__slots__128 → 88 B; a 7-step playbookPython memory in productionMemory modelThe allocatorMemory profiling
🔴 Step 5 — Concurrency and async
- GIL — why it exists and how threads take turns (5 ms switch interval, convoy effect); what it never protected, measured; the free-threaded 3.14t build: scaling, single-thread cost, how it works, the GIL coming back; subinterpreters; choosing a modelThe GIL and free-threaded PythonThreads vs processesSynchronization primitivesMemory model
- Concurrency vs parallelism — structure vs execution; the same work four ways, measured (gather, threads on both builds, processes); where I/O parallelism comes from; cooperative vs preemptive; Amdahl and Little for sizingConcurrency and parallelismCPU vs I/O tasksasyncio vs threadsThe GIL
- CPU-bound vs I/O-bound workloads — classify by CPU time vs wall time; “I/O” that is really CPU (json holds the GIL, hashlib and zlib release it, measured); contention as a third class; pickling cost in process pools; pool defaults and
PYTHON_CPU_COUNT; fork vs forkserverCPU-bound versus I/O-boundrun_in_executor and to_threadWhen to use processesThe GIL - Threads vs processes vs asyncio — shared vs isolated memory; what each costs to start and to hold 10,000 of, measured; moving data between processes; what a failure takes down; the decision tree with free-threading and subinterpreters; how they combine in one serviceThreads and processesCPU vs I/O: the modelsWhen to use processesProcessPoolExecutor
- When to use threads vs async code — who decides to switch; memory, start-up and switch cost, measured; blocking calls; where races and exceptions live; cancellation (threads cannot be cancelled); debugging stuck threads vs tasks; bridging both ways; colourasyncio and threadsrun_in_executor and to_threadTaskGroupConcurrency vs parallelism
- asyncio, coroutines and
async def— the coroutine object; driving one by hand withsend()andthrow(); whatawaitcompiles to; why one blocking call freezes the loop; the exact errors; detecting coroutine functions; running async from syncCoroutines and async defEvent loop internalsGeneratorsasync def returns a coroutine - Event loop internals — the loop’s state and one turn; how a Task drives a coroutine (Future, wake-up,
send); lazy vs eager tasks;call_soon_threadsafeand why; selector vs proactor;get_event_loopin 3.14; what uvloop really buysEvent loop internalsCoroutines and async defCancellation and timeoutsDebugging async - I/O blocking — what blocking means at the OS level; blocking vs non-blocking and readiness vs completion; non-blocking sockets and selectors; epoll and kqueue vs select; what cannot be made non-blocking (files, DNS, C libraries); blocking and the GILBlocking and non-blocking I/OEvent loop internalsrun_in_executor and to_threadTCP vs UDP
- Blocking the loop:
async defvsdef, ThreadPoolExecutor — how FastAPI decides loop or thread; 50 requests four ways, measured; two thread pools (AnyIO’s 40 tokens vs the loop’s executor); the Little’s-law ceiling; hidden pool consumers; loop lag vs pool saturation; the limiter set in lifespanFastAPI and the event looprun_in_executor and to_threadrun_in_threadpoolBlocking in async -
concurrent.futures— launching parallel tasks — one API, three executors (threads, processes, interpreters), measured; Futures and where exceptions go;mapvsas_completed;chunksize(48 s vs 0.06 s); cancellation limits, fail-fastwait,terminate_workers; bridging to asyncioconcurrent.futuresProcessPoolExecutorrun_in_executor and to_threadThreads and processes -
asyncio.gathervsTaskGroup— where each exception goes; one failure under both, measured; how TaskGroup cancels and waits; stopping a group early (3.14 recipe, 3.15cancel()); partial failure with a bounded semaphore; the weak-reference task leakTaskGroup and structured concurrencyCancellation and timeoutsanyio and TrioEvent loop internals - Sync primitives: Lock, semaphores and others — what the GIL did and did not make safe, measured on 3.14 and 3.14t; Lock vs RLock, fairness, timeouts,
wait_for; races across anawaitand loop-bound asyncio primitives;Queue.shutdown(); deadlocks and locks held at forkSynchronization primitivesasyncio and threading queuesThe GILRedlock critique - Free-threading (3.14t): features and costs — measured costs (4× on 8 threads, ~15% single-thread, +12% per object, shared list 23× slower than per-thread); biased refcounting, per-object locks, mimalloc and delayed freeing, stop-the-world GC; lost increments; a shared generator segfaulting in 6 of 10 runs; extensions re-enabling the GIL; when to switchFree-threaded PythonThe GILSynchronization primitivesconcurrent.futures
- Async Python, deep: everything together — the stack from
async defto the socket and a map of Step 5; async generator cleanup andaclosing(measured order); contextvars copied into tasks; eager tasks (1.335 → 0.587 s); debug mode and runtime warnings; 3.14python -m asyncio pstreeon a live process; uvloop 1.2×; the seven production failures rankedAsync Python, end to endEvent loop internalsTaskGroupCancellation and timeouts - Tricky: why two awaits for one HTTP request? — the first await returns at the headers, the body is still on the wire (0.00 s vs 2.04 s, measured); deciding before downloading, streaming with
iter_chunked; httpx and requests read eagerly; noaiohttp.post; connection release and pool exhaustionTwo awaits for one HTTP requestBlocking vs non-blocking I/OEvent loop internalsBlocking in async
🔴 Step 6 — Databases
- SQL — NULL and three-valued logic; LEFT JOIN turned INNER by a WHERE filter, seen in the plan; GROUP BY and functional dependency; the fan-out trap in aggregates; semi- and anti-joins,
NOT INvsNOT EXISTS(0 vs 50 rows, 1.5 s vs 53 ms); normalization and when to break it; OFFSET vs keyset; logical clause orderSQL fundamentalsHow a query is processedWindow functions and CTEsCTEs and recursive queries - PostgreSQL — process per connection (27,122 vs 388 tps without pooling);
shared_buffersand per-nodework_mem; heap, MVCC tuple versions, HOT updates, TOAST; VACUUM and the xmin horizon, measured; WAL and replication; what changed in 18; vs MySQL InnoDBPostgreSQL architectureVACUUM and autovacuumWAL and checkpointsConnection pooling - MongoDB — the document as the unit of atomicity and the 16 MB limit; lost updates from read-modify-write (18 of 100) vs
$inc; embed vs reference;$jsonSchemavalidation and null vs missing; COLLSCAN vs IXSCAN, measured; write concern majority and rollback on failover; transactions and their cost; PyMongo async replacing MotorMongoDBTransactions and concernsIndexesReplica sets and shardingNoSQL decision guide - Indexes in PostgreSQL: types in detail, pros and cons — the capability matrix from the server; six access methods with measured size, build and insert cost; B-tree surprises (collation and
LIKE, 2,704-byte cap, PG18 skip scan); hash only wins on long keys; GIN operator matching,jsonb_path_ops, the pending list; GiST exclusion constraints; SP-GiST; BRIN and correlation (266 vs 57,201 buffers)Index typesHow a B-tree index worksWhy your index is not usedpgvector in production -
EXPLAIN/EXPLAIN ANALYZE— inside-out reading, loops multiply, time is inclusive (a real 1-vs-49,975 misestimate: 150,466 vs 1,082 buffers afterANALYZE); join strategies and hash batches; spills, lossy bitmaps, Memoize, workers not launched, JIT cost; fast in EXPLAIN but slow in the app: generic plans,SERIALIZE, the client;auto_explain; no hints, and the escape hatchesReading a query planHow a query is processedWhy your index is not usedIndex types -
pg_stat_statements— setup and how queries are grouped (constants to$1, PG18 IN-list squashing, one text split by parameter types); rank by total, not mean (a 1 ms update cost 4.6 s); six rankings; blind spots: N+1 is 21 ms in the DB and 1.1 s in the client, cancelled statements leave no entry; cumulative counters and deltas; logs and traces as the complementpg_stat_statementsReading a query planN+1Incident response and runbooks - ACID — how each letter is delivered: rollback as a status bit (1M rows rolled back in 0.2 ms, cost moved to VACUUM), the aborted state after an error vs MySQL, savepoint costs; per-row vs deferred constraints and cross-row invariants; isolation interleaves; durability as a setting (
synchronous_commitoff: 3× TPS, 600 ms at risk), failover loss; implicit transactions in psycopgTransactions and ACIDWAL and checkpointsPostgreSQL architectureSQLAlchemy transactionsCAP, ACID and BASE - Transaction isolation levels — snapshots and when they are taken (first statement, not BEGIN); READ COMMITTED: read skew (250 vs 200), silent lost update, the re-check after a wait; REPEATABLE READ: first-updater-wins
40001, write skew; SERIALIZABLE via SSI and SIRead locks, retries by SQLSTATE; FOR UPDATE on a missing row double-books; row lock modes; retry storms, long reports, deadlocksTransaction isolation levelsTransactions and ACIDAdvisory locksSQLAlchemy transactions - Concurrent transaction anomalies — the anomalies by name (P0-P4, A5A/A5B, Adya’s G-codes); a PostgreSQL vs InnoDB matrix, all run; InnoDB’s snapshot vs current reads (100, 100, then 160), silent lost updates, phantoms hidden from reads but not writes, gap locks and deadlocks; SQLite’s
SQLITE_BUSY_SNAPSHOT; Oracle and SQL Server; porting traps; optimistic vs pessimistic SERIALIZABLEIsolation anomalies across databasesTransaction isolation levelsMySQLSQLite - N+1 problem:
select_related,prefetch_related— counted on Django 6.1 (101 → 1 and 2); INNER vs LEFT OUTER JOIN; what keeps a prefetch (.count()) and what discards it (.filter(): 102);Prefetch(to_attr=); when the JOIN ships 10× more data; 6.1 fetch modes (FETCH_PEERSfixes forward FKs, not reverse/M2M;FETCH_RAISE);only(), huge prefetches, async; detection in tests, APM andpg_stat_statementsN+1 in DjangoN+1 across ORMsSQLAlchemy loading strategiesDRF performance - SQL injection — the attack run (login bypass, UNION extraction); what the driver sends: psycopg 3 binds server-side, psycopg2 escapes client-side (CVE-2025-1094); stacked statements; what cannot be a parameter and
sql.Identifier; t-strings in psycopg 3.3; ORM escape hatches and Django’s user-controlled-keys CVEs; LIKE wildcards; second-order; MongoDB operator injection; least privilege and detectionSQL injectionOWASP Top 10Python 3.14 featuresMongoDB - Elasticsearch — a derived, eventually consistent index of shards;
hash(routing) % primariesfixes the primary count; write path (translog, refresh, flush, merge) and near-real-time search (get sees it, search does not;wait_forblocks to the next refresh); query-then-fetch and the 10,000 window; BM25 statistics per shard (4.169 on one shard, 2.471 on five);if_seq_noand external versions for sync from Postgres, deletes forgotten aftergc_deletes; shard and node sizing, disk watermarks; Postgres full-text firstElasticsearch overviewQuery DSL and scoringPython client and pitfallsTransactional outbox
🟡 Step 7 — Frameworks and backend architecture
- FastAPI
Depends: the dependency graph — how the tree is built and classified; resolution order (app, router, decorator, params) and sequential awaiting (2 × 100 ms = 0.22 s); the cache key (callable + security scopes + teardown scope); teardown after the response since 0.118, so a failing commit returns 201 (500 withscope="function"); the version history; overridesDependencies and injectionFastAPI and the event loopSecurity and authenticationDependency injection - Django and Django REST Framework — the request path traced (negotiation, auth, permissions, throttles, handler, object permissions only in
get_object()); the list leak; 401 vs 403 from the first auth class;atomicdoes not stop lost updates (90 vs 50;select_for_update,F());on_commit; async limits in Django 6.1; serializer cost vsvalues()Django and DRF: the request pathPermissionsAsync DjangoN+1 in Django - Monolithic backend applications — one artifact, not one process; a boundary measured (59 ns vs 0.9 ms over HTTP, JSON cost); availability and p99 across synchronous chains; scaling a monolith per Deployment; Conway’s law and deploy-contention metrics; a modular monolith enforced by import-linter and per-module schemas; extraction order; distributed monolith, retry storms, Prime Video and SegmentMonolith vs microservicesData consistency patternsTransactional outboxFeature-sliced structure
- Service layer vs classic MVC in Django — which entry points run
save(),clean()and signals (forms only forclean();update()andbulk_create()skip all); invariants as database constraints; service functions owning the transaction,select_for_update,on_commit(an email for a rolled-back order); selectors returning QuerySets (51 vs 1 queries); the placement table; repositories and hexagonal as tradesService layer vs fat modelsDjango and DRFRepository and Unit of WorkClean architecture - Celery and background job processing — when a task is acknowledged: with
acks_latea failure is acked, an OOM-killed child is lost unlesstask_reject_on_worker_lost; the Redis visibility-timeout duplicate, which appears when a worker starts (deploys); every cause of running twice or never; prefetch (6 reserved + 2 active); runtime guards;result.get()in a task; monitoring queue ageWhat is CeleryIdempotencyDead-letter queueAsync I/O and background work - Redis — one command thread, I/O threads off by default; what blocks everyone (
KEYSstalledPING249 ms,DEL179 ms vsUNLINK0.3 ms); pipelining 25×; encodings and the 513-field jump (4.5 → 22 KB); Redis 8 built-ins and the AGPL change; locks on failover, fork memory, big and hot keysWhat is RedisPersistence and memoryClustering and HARedlock critiqueValkey - Idempotency keys and “at most once” delivery — two concurrent requests, one key, run on PostgreSQL 18:
FOR UPDATEgives a 500, a committed claim gives 409 then replay, a claim inside the request transaction blocks and double-charges after a crash; atomic phases and derived provider keys; which 4xx to retry; Stripe replay and expiry; delivery semantics per hop and when at-most-once is rightIdempotency keysIdempotent paymentsKafka delivery semanticsTransactional outbox - Dependency inversion vs dependency injection — principle vs technique: which way source dependencies point vs who wires objects; ports owned by the domain;
Protocolchecked by mypy (andruntime_checkablepassing a broken adapter); DI without DIP caught by an import-linter layers contract; DIP without DI (service locator); composition root,Depends, fixtures, containersDependency inversion vs injectionSOLIDDependency injectionFastAPI Depends - *DDD, TDD, BDD and the other -driven approaches — design approaches vs ways of working; the map by what comes first; TDD and BDD in one red-green run (pytest-bdd); a DDD aggregate guarding an invariant; where each goes wrong (testing mocks, unread Gherkin, DDD on CRUD, untraceable events); risk-driven design as the answer to “how much”X-driven: the mapDomain-driven designBDD and specification by exampleTest pyramid and strategy
🟡 Step 8 — Docker
- Images vs containers — layers, config and digests (tags move); a container as a host process with namespaces, cgroups and a writable layer;
docker diff, copy-up of a whole 5.6 MB file for one byte, data gone onrm; volumes vs bind mounts vs tmpfs; limits the runtime cannot see; PID 1 ignoring SIGTERM (137) vs--initor a handlerDocker image vs containerImage layersScaling in DockerPython memory in production - Docker Compose —
depends_onorders start, not readiness (3 of 3 connection refused); healthcheck +service_healthy, a migrations gate withservice_completed_successfully; restarts later need app retries; override files append lists (!override); Postgres 18’s new volume path; obsoleteversion, CLI v5; secretsDocker ComposeVolume typesScaling in DockerImage vs container - Layers and build caching — cache keys:
COPYby content (touchstays cached),RUNby command text (RUN datecached forever); config instructions are 0 B; order dependencies before source; cache mounts (8 downloads vs 1); deleted files and secrets stay in layers; a tested uv multi-stage build (--no-editable,--lockednot--frozen); mid-line comments break buildsLayers and build cachingMulti-stage buildsVirtualenvs and lockfilesImage vs container -
ADDvsCOPY—ADDextracts local tars (not zips), downloads URLs (mode 0600) and clones Git;--checksumfails on changed content whereRUN curlstays cached;COPYoptionsADD vs COPYLayers and build cachingMulti-stage builds - Multi-arch builds — the image index (8 platforms, a digest each; pin the index); QEMU emulation 33× slower on CPU, 13× on wheel installs; cross-platform stages on
$BUILDPLATFORM(204.6 s → 19.5 s); native runners andimagetools create;exec format error, hard-codedFROM --platform, attestations, registry cleanup; Graviton economicsMulti-arch buildsLayers and build cachingImage vs container
🟡 Step 9 — Cloud (AWS) and monitoring
- ECS, Fargate — task vs execution role and the IMDS trap on EC2; a deployment stuck half rolled out (a
curlhealth check in an image without curl, grace periods, circuit breaker); scaling workers on backlog per task, scaling to zero; built-in blue/green with hooks (2025);awslogsnon-blocking default drops logs; Service Connect; Fargate cold starts (no image cache, SOCI); App Runner closed, ECS Express ModeAmazon ECSAWS FargateImage vs container - CloudWatch — what EC2 does not report (memory, disk space) and real resolutions; retention roll-ups; custom metrics and EMF, tiered pricing (100k metrics $12k/month, 1M $64.5k) and high-cardinality dimensions; log ingestion costs and Logs Insights per GB scanned; alarm evaluation (M of N, missing data and the alarm that never fires, rates and percentiles); X-Ray SDK end of support → OpenTelemetryAmazon CloudWatchCost and advanced patternsThree pillars
- Cognito — user pool vs identity pool; ID vs access token (no
audon access tokens), the seven backend checks; ALBauthenticate-cognitoend to end (signedx-amzn-oidc-data,signer, ALB-only security group, 7-day session, two-step logout); sign-out vs offline validation, rotation; pre-token V1/V2/V3; plans, M2M per-token pricing, quotas, multi-region (2026); identity-pool S3 prefixesAmazon CognitoCognito for Python backendsOAuth 2 and OIDCJWT pitfalls - Grafana — a panel as server-side queries,
$__intervaland dashboard load maths;$__rate_intervaland the scrape-interval setting, Prometheus 3 left-open ranges; histogram quantiles; alert states (Recovering, No Data), the dead exporter that never pages, routing defaults, where rules live; HA (ha_peers, shared DB); provisioning semantics, Git Sync; Alloy, Loki streams and structured metadata, exemplarsGrafanaPrometheusSLO, SLI, SLACorrelation IDs - Observability — what metrics, logs, traces and profiles store and cost;
traceparent, trace ids in logs, exemplars, stable semconv renames; p99 490 ms vs 2 s timeouts (the hidden 0.3%, bucket interpolation 0.298 → 0.486, averaged p99s, failures the server never sees); who monitors the pipeline (span-queue drops, Collector counters); a worked cost for 50 services; SDK vs eBPF; wide eventsThree pillarsOpenTelemetryGrafanaSampling strategiesSLO, SLI, SLA
🔴 Step 10 — System design
- Core of system design — eight phases on a clock (diagram by minute 25); NFRs as mechanisms (99.99% needs multi-AZ failover, RPO = 0 costs a cross-AZ RTT per commit, RTO as a sum); Little’s law (120 in flight vs
max_connections = 100, PgBouncer), backlog drain, tail at scale (63% at N=100), cost as a number; a data model checked against access patterns; the failure walk (cache at 0% = 100x DB reads); open-model load tests; a worked 45-minute webhook transcriptThe frameworkCapacity estimationLatency numbersTimeouts and retriesWorked designs - Distributed systems — partial failure (a timeout is the only detector; two generals, FLP); wall vs monotonic clocks, Lamport (a receive stamped before its send), vector, HLC, TrueTime; majorities and odd cluster sizes; Raft (terms, votes, commit, ReadIndex); a paused lease holder overwriting its successor, stopped by a fencing token; etcd, KRaft, Kubernetes Leases, Patroni, Sentinel; advisory-lock leaders (2 h 11 min on keepalive defaults), the epoch rowConsensus and leader electionReplication and consistencyRedlock critiqueAdvisory locks
- Microservices — running them once split: readiness that empties a Service, deadline propagation, retries multiplying (27x at 3 tiers) and chain availability; identity across hops (spoofable
X-User-Id, forwarded or exchanged tokens, mTLS); outbox and idempotent consumers; expand/contract under version skew, Pact, schema registry; 502s on deploy and thepreStopsleep; traces through queues; gateway vs meshMicroservices in productionMonolith vs microservicesData consistency patternsResilience patterns - Caching — four patterns and where each goes stale (write-through is not “never stale”); the read/write race delete-on-write leaves open (run: cache=old, db=new) and the replica-lag variant; leases (run: late SET rejected), versioned Lua CAS, double delete, CDC, TTL as the bound; negative caching, hit-ratio arithmetic, a stale-read rate; in-process vs RESP3 client-side caching vs CDN; versioned key prefixes on deployCache consistencyCache stampedeRedis persistence and memoryDistributed cache design
- Design: LLM usage statistics (tokens, model, latency; ACID, observability, caching, idempotency) — one gateway as the capture point; provider usage traps (
input_tokensexcludes cache, cache write 1.25x/2x and read 0.1x/0.05x, cumulative stream counts) and a stream cut off mid-answer; integer micro-dollars and a versioned price table; dedup by event id vs retries as real calls; budgets by reserve-then-settle in one conditionalUPDATE; hourly reconciliation with the provider’s usage API; TTFT and cardinality; three meanings of cachingLLM usage meteringIdempotent paymentsThe frameworkThree pillars - Design: image/file processing app (storage, virus protection, async workflow, not blocking users) — uploads straight to S3 by pre-signed POST (size enforced by the policy); a state machine with conditional transitions and status polling; quarantine, GuardDuty for S3 tags (only
NO_THREATS_FOUNDis clean) and a deny-unless-clean bucket policy; hostile-file processing (magic bytes, pixel caps, re-encode, EXIF GPS); content-hash output keys, SQS visibility timeout and DLQ; user content on a separate domain; storage as the cost lineFile processing pipelineJob schedulerXSS and CSRFThe framework
🟡 Step 11 — AI
- OpenAI API — Responses (primary) vs Chat Completions (portable), Assistants shut down 2026-08-26;
previous_response_idstill bills every prior token,store=False; strict structured outputs and refusals; the Responses tool loop and the silent non-strict fallback; named stream events vs the empty-choicesusage chunk;input_tokensincludes cache, reasoning counts againstmax_output_tokens, paid cache writes; Batch/Flex; 429s at 40% TPM,insufficient_quota, 12 nested retries, no idempotency keyThe OpenAI API in practiceThe Claude Messages APIThe chat APIFunction calling and structured output - SSE as the streaming protocol for LLM responses — re-stream the provider inside the response generator (runnable fake provider and
fastapi.ssebackend); one event schema of your own, errors in-band, never bill from stream usage; Stop measured one hop further (7 delivered, 8 generated); the detached pump that billed 33 tokens for 7 seen; coupled vs decoupled runs and a grace-period cancel; token sizes leaking answers (Weiss et al. 27%, Whisper Leak)Streaming LLM responsesServer-Sent EventsThe OpenAI APILLM usage metering - LangChain, LangGraph and the modern agent stack — LangGraph 1.2.15 is the runtime (there is no 1.3), LangChain 1.4.5 is
create_agent+ middleware; supersteps over versioned channels, reducers (InvalidUpdateError), pending writes, durability modes; interrupts re-run the node (run: side effect twice) andexcept Exceptionswallows the pause; Postgres checkpointer ops, no TTL,delete_thread, the serializer as a code-execution boundary;thread_idas a capability, double texting, recursion limits of 10,007/9,999; choosing among own loop + MCP, LangGraph, OpenAI Agents SDK, Pydantic AI, Claude Agent SDKLangChain, LangGraph and the agent stackLangGraph in depthThe agent loopDurable execution and HITL - Multi-agent systems — usually the wrong first answer; sub-agent as a tool, isolated context; supervisor, pipeline, parallel with reducer; 0.9^5 = 0.59 reliability; typed handoff with
gaps; Anthropic +90.2% at about 15x chat tokens vs Cognition’s shared-context rule; one budget plusTaskGroupcancellation (run: runaway stops its siblings); inter-agent injection, conflicting parallel writes; trace the tree, keep a single-agent baselineMulti-agent patternsMulti-agent frameworksLangGraph multi-agent and subgraphsAgent protocols - RAG on large data volumes — size it in chunks (200M x 1024 dims: 820 GB float32, 26 GB binary; 80B embedding tokens is cheap in dollars, days in wall-clock); quality drops as the corpus grows (run: exact top-1 0.97 at 10k, 0.57 at 1M, 0.98 filtered to one source), so filter, route, dedupe, retrieve documents first; int8 / binary with rescoring, Matryoshka, DiskANN, and the task metric vs overlap; shard by key, fan-out tail latency, every shard returns k,
partialflag; bulk load then build, resumable embed workers, re-embed needs two indexesRAG at scaleANN indexes and HNSWHybrid search and rerankingIngestion and index sync
🟢 Step 12 — Other domains
- Blockchain — what a chain guarantees to a backend; Merkle proofs (20 hashes for 1M transactions, run); finality per chain (Bitcoin ~6 blocks, Ethereum
finalized~13 min, rollups); UTXO vs account nonces, stuck nonces and fee bumps; EIP-1559 fees, integer base units; crediting deposits exactly once under a reorg (simulated: duplicates, a vanished deposit, confirmations shallower than the reorg); KMS/HSM signing, MPC vs multisig; stablecoin freezes, OFAC, Travel Rule, MiCA, GENIUS ActBlockchain fundamentalsIdempotency keysTransactional outboxConsensus and leader election - Web scraping — API first, then the site’s own JSON, HTML, a browser last; client defaults that bite (no timeout, no redirects, UTF-8 fallback); RFC 9309 robots.txt and Python’s parser getting it backwards before 3.14 (run on 3.12/3.13/3.14); a per-host bounded fetch loop with
Retry-After; conditional GET, content hashes, idempotent upserts, WARC; Playwright cost; anti-bot layers and soft 200 blocks; the legal landmarks (Van Buren, hiQ, Meta v. Bright Data, GDPR)Web scraping and browser automationTimeouts, retries, poolingSSRFIngestion and index sync - Fintech — money as integer minor units (
int(19.99 * 100)is 1998;sum()is compensated since 3.12), ISO 4217 decimals, banker’s rounding; largest-remainder allocation with a property test; journals and postings balanced by a deferred constraint trigger, idempotent byUNIQUE (source, external_id); overdraws under READ COMMITTED and three fixes, hot accounts; reversing journals, hash chains, WORM; three-way reconciliation and breaksDouble-entry ledgerIdempotent paymentsIsolation anomaliesBlockchain fundamentals - Frontend development — streaming an LLM answer into React: EventSource semantics (fixed
retry:, a 401 closes it forever, GET only); a blank-line-only parser that emits nothing against CRLF servers (run in Node) vs a spec-shaped one; an abortable hook that batches tokens per animation frame, aborts on unmount, handles in-banderrorand flags missingdoneas truncated; what Stop does down to the provider; quadratic markdown re-renders; cancel vs resumeStreaming an LLM answer into ReactStreaming LLM responses (backend)Server-Sent EventsAbort and race conditions