Senior review 2 — Python backend, messaging and AWS — prep map
The themes for a senior Python backend role on a Matrix-based messaging product (October 2026): FastAPI and PostgreSQL at the core, Docker and Nginx in front, a Matrix homeserver with push and calls, AWS and Cloudflare around it. Read top to bottom; tick an item once you can explain and defend it under questioning, not merely when you have read it.
The recruiter flagged Nginx/OpenResty, ElastiCache and Route 53 as gaps. Synapse/Matrix, Sygnal and TURN/VoIP are the least common skills on the list and the likeliest “do you have experience with…” questions, so they are marked core too.
Bold is the main read for an item, an Article where one exists. Created 2026-10-15 from existing notes; the seven items no note covered (Matrix and Synapse, Sygnal, FCM, VoIP, STUN/TURN, OpenResty, Cloudflare) were written as new Articles the same day, and their summaries name what each demonstrates, including the local runs.
Priority: 🔴 core (asked, or flagged as a gap) · 🟡 important · 🟢 breadth
🔴 Step 1 — Python and FastAPI
- Python at senior level — the object model and reference counting, the GIL and what 3.14’s free-threaded build changes,
__eq__/__hash__contracts, decorators and context managers as API design, what is new in 3.14Memory modelThe GIL__eq__vs__hash__DecoratorscontextlibPython 3.14 features - Async endpoints —
defvsasync defroutes and AnyIO’s thread limiter, a blocking call freezing the loop, offloading withto_thread, timeouts and cancellation that actually stop workFastAPI asyncrun_in_executor and to_threadCancellation and timeoutsasyncio vs threads - Pydantic models — request and response models, validation modes (
before/after), settings, the v2 performance model and where validation belongsPydantic models in FastAPIPydantic in practiceValidation modes - Dependency injection —
Dependsas a graph resolved per request, yield dependencies and cleanup order, overriding in tests, why a request-scoped DB session can hold a connection too longDependencies and injectionConnection poolingTesting FastAPI - Middleware —
@app.middleware("http")vs pure ASGI middleware, whatBaseHTTPMiddlewarecosts, order of execution, CORSMiddlewareException handlingCORS in depth - Background tasks —
BackgroundTasksdies with the process; when work needs a broker (Celery, SQS) and retries; what a deploy does to in-flight workBackgroundTasks vs CeleryAsync I/O and background workTransactional outbox - REST APIs: design and maintenance — resource modelling, safe and idempotent methods, PUT vs PATCH, versioning and pagination, contract-first design, evolving an API without breaking clientsREST principlesPUT vs PATCHVersioning and paginationContract-first API designIdempotency keys
- Code reviews — what review is for (and what CI should catch instead), giving and receiving feedback, review size and latency, typing and linting as review supportPre-commit and code reviewPR workflowRefactoringType checking strategy
🔴 Step 2 — PostgreSQL
- Indexes — B-tree mechanics, composite column order, partial and covering indexes, GIN/GiST/BRIN, and why a planner ignores an indexIndexesIndex typesWhy your index is not used
- Transactions and isolation levels — MVCC, what READ COMMITTED, REPEATABLE READ and SERIALIZABLE each prevent, lost updates and write skew,
SELECT ... FOR UPDATE, retries on serialization failureTransactions and isolationIsolation anomalies across databasesSQL transactions - Query optimization — reading
EXPLAIN (ANALYZE, BUFFERS), estimates vs actuals,pg_stat_statementsto find what to fix, N+1 from the ORM, pool sizing by Little’s lawEXPLAIN ANALYZEpg_stat_statementsN+1Connection pooling - Migrations — expand and contract,
CREATE INDEX CONCURRENTLY, adding a NOT NULL column without a rewrite, lock timeouts, Alembic in a deploy pipelineZero-downtime migrationsAlembicPostgreSQL architecture
🟡 Step 3 — MongoDB
- Document modeling, indexes, aggregation, and when to choose it over SQL — embed vs reference by access pattern, compound and multikey indexes with the ESR rule, the aggregation pipeline, write and read concerns, and the honest case for PostgreSQL with JSONB insteadMongoDBCompound and multikey indexesAggregation pipelineTransactions and concernsSQL vs NoSQL
🔴 Step 4 — Docker
- Dockerfiles — layers and cache order,
COPYvsADD, a non-root user,.dockerignore, what makes images large and builds slowImage layersImage vs containerADD vs COPY - Multi-stage builds — build and runtime stages, copying only the artifact, slim vs distroless bases, multi-architecture imagesMulti-stage buildsMulti-arch builds
- docker-compose — services, healthchecks and
depends_onconditions, volumes, profiles, what compose is not (an orchestrator)Docker ComposeVolume types - Networking — bridge, host and none networks, service discovery by name, published vs exposed ports, why
localhostinside a container is not the hostNetworks: bridge, NAT, hostScaling in Docker
🔴 Step 5 — Nginx and OpenResty (flagged)
- Reverse proxy — the worker and event model,
locationmatching order, theproxy_passtrailing-slash rule, headers to forward (X-Forwarded-*), Nginx in front of Gunicorn/UvicornNginx architectureLocation matchingproxy_pass trailing slashGunicorn deploy - Load balancing —
upstreammethods (round robin,least_conn,ip_hash,hash), passive health checks, keepalive to upstreamsUpstream load balancingLoad balancers - SSL termination — a modern TLS config, HSTS, OCSP stapling, certificate renewal, what the backend loses when TLS ends at the proxyTLS configurationTLS, HTTPS and certificates
- Rate limiting —
limit_reqas a leaky bucket,burstandnodelay, keying by something other than IP, the real client IP behind a CDN,limit_connRate limitingSecrets and rate limiting - WebSocket proxying — the
UpgradeandConnectionheaders,proxy_read_timeoutfor long-lived connections, sticky routing — the setup a Matrix homeserver’s sync traffic depends onWebSocket proxyingWebSocket scalingWebSocket vs alternatives - OpenResty — Nginx plus LuaJIT: Lua in the request phases (
access_by_luafor auth and limits,balancer_by_lua,log_by_lua), cosockets vs anything that blocks the worker,lua_shared_dictacross workers (fixed size, LRU when full),ngx.ctxper request;resty.limit.reqkeyed by API key (its leaky-bucket arithmetic run: 20 requests at 10 r/s burst 5 → 6 served with 0-0.5 s delays, 14 rejected) and per-instance limits; edge JWT checks and header trust; vsauth_requestOpenResty: Lua inside NginxNginx rate limitingNginx architectureNginx alternatives
🔴 Step 6 — Matrix messaging stack (niche, flagged)
- Matrix and Synapse — rooms as replicated event DAGs (PDUs vs EDUs,
prev_events,auth_events, state keyed by type and state_key); how a server trusts a relayed event (run with canonicaljson/signedjson: a rewritten body keeps the event ID and signature but fails the content hash and is shown redacted; a changed sender breaks both); state resolution and room version 12 (State Resolution v2.1, Project Hydra);/synclong polling and Simplified Sliding Sync; federation discovery, 8448 and.well-known; Synapse 1.163 workers over Redis,/syncrouted per user, initial syncs isolated;state_groups_stategrowthMatrix and SynapseWebSocket proxyingShort vs long pollingConsensus and leader election - Sygnal (push gateway) — why the homeserver does not call FCM itself (the app publisher’s credentials); pusher registration and
app_id; the/_matrix/push/v1/notifycontract run locally: the full format sends the message body to Google or Apple,event_id_onlysends only IDs and counts, andrejectedpushkeys must be deleted; encrypted rooms and client-side push rules; Sygnal 0.17 config (FCM v1 service account, APNs.p8token auth); expired certificates, sandbox vs productionSygnal: the Matrix push gatewayFCM and APNsNotification fan-out - Firebase Cloud Messaging — registration tokens per install; HTTP v1 with a service-account JWT exchanged for a 1-hour OAuth token, and APNs ES256 provider tokens from a
.p8key (both generated locally with PyJWT); notification vs data messages, priority and deprioritisation,mutable-content, collapse keys, ~4 KB payloads; errors as instructions (UNREGISTERED→ delete), firebase-admin 7send_each; token hygiene (270-day Android expiry); the legacy API shut down from July 2024FCM and APNsSygnalNotification fan-outNotification center
🔴 Step 7 — Real-time: VoIP, STUN and TURN (flagged)
- VoIP over WebRTC — signalling as
m.call.*room events (invite, candidates, answer, select_answer, negotiate, hangup), media never through the homeserver; every device rings andparty_idpicks one; invitelifetime, glare by the smallercall_id, batched candidates (and the IP addresses they put in room history);GET /voip/turnServerand Synapse’sturn_shared_secret; group calls: mesh uploads N-1 streams, so MatrixRTC with a LiveKit SFU andlk-jwt-serviceVoIP calls on MatrixSTUN, TURN and coturnWebRTC and WebTransport - STUN vs TURN, and coturn — NAT mapping types decide whether a direct path exists (run: one socket, two STUN providers, two different public ports → symmetric NAT, TURN needed); ICE candidates host, server-reflexive, relay; TURN relay bandwidth cost; time-limited REST credentials (HMAC of
expiry:user); a coturn config with TLS on 443, relay range, quotas anddenied-peer-ipfor private, link-local and metadata ranges, and the 2026 CVEs that bypassed it with IPv4-mapped IPv6 (upgrade to 4.16+); placement, metrics, “no audio” debuggingSTUN, TURN and coturnNATVoIP calls on MatrixTCP vs UDP
🟡 Step 8 — AWS (ElastiCache and Route 53 flagged)
- EC2 — instance families and sizing, AMIs and launch templates, security groups vs NACLs, instance profiles instead of keysEC2AWS interview essentials
- ElastiCache (flagged) — Redis/Valkey vs Memcached, cluster mode on and off, endpoints, failover and what a client sees during it, connection pools on Kubernetes, cache-aside, sessions and pub/subElastiCacheFailover and serverlessWhat is RedisCache consistency
- Route 53 (flagged) — hosted zones, alias vs CNAME at the zone apex, routing policies (weighted, latency, failover, geolocation), health checks, TTLs during a cutoverRoute 53DNS
- Secrets Manager — storing and rotating credentials, the rotation Lambda, caching secrets in the app, Parameter Store as the cheaper optionSecrets ManagerRotation and Parameter Store
- CloudWatch — logs, metrics and alarms, metric filters, alarms on percentiles, the cost traps (high-cardinality custom metrics, log ingestion)CloudWatchCost and advanced patternsSLOs and burn rates
- S3 — presigned URLs for direct uploads and downloads, bucket policies vs IAM, Block Public Access, storage classes and lifecycle rulesS3File uploadsCDN and signed URLs
🟡 Step 9 — Cloudflare (edge)
- Cloudflare — proxied vs DNS-only and the anycast edge (run: this site’s names resolve inside Cloudflare’s 15 IPv4 and 7 IPv6 ranges;
Server,CF-Ray,CF-Cache-Statusheaders); SSL modes (Flexible’s redirect loop, Full (strict) with an Origin CA certificate); what is cached by default (extensions, not HTML or JSON, never withSet-Cookie); restoring the client IP fromCF-Connecting-IPfor trusted ranges only; locking the origin (firewall, Authenticated Origin Pulls, Tunnel); 52x errors and the 125 s timeout; Matrix behind it: 8448 is not proxied, so.well-knowndelegation to 443, TURN stays DNS-onlyCloudflare in front of your originCDNDNSLoad balancing and CDN
🟡 Step 10 — Non-functional: reliability, security, performance, scaling
- Monitoring — SLIs and SLOs, burn-rate alerts over two windows, the three pillars, tracing across servicesSLOs and error budgetsThree pillarsOpenTelemetry
- Caching — cache-aside and its races, invalidation, stampedes, what not to cacheCache consistencyCache stampedeHTTP semantics and caching
- Horizontal scaling — stateless services, sticky sessions and why to avoid them, load balancing, read replicas and their lagStateful vs statelessLoad balancing and CDNReplication and consistency
- Secrets handling — where secrets live and why workload identity beats any stored secret, rotation, never in images or logsSecrets and configurationSecrets ManagerSecrets and rate limiting
- Reliability and performance under load — timeouts, retries with backoff and jitter, circuit breakers, connection pools, profiling before optimizingTimeouts, retries, backoffCircuit breakers and bulkheadsConnection poolingMemory profiling