The performance of the edges. No solutions.md before submitting.
Exercise 1 — The pool's arithmetic
- Compute your connection budget: gunicorn (workers × threads × replicas), Celery workers (concurrency), beat, commands. Write it as a table with the total and compare against
SHOW max_connections. - Configure CONN_MAX_AGE + psycopg 3's pool (min 2 / max 10) and measure with
pg_stat_activitybefore and after the k6 plateau (36): how many connectionsidle? How manyactive? - The controlled disaster: in a test environment, lower
max_connectionsto 20 and launch the 200-VU plateau. Which error appears and where (app, worker, both)? Document the EXACT symptom for 47's runbook.
Exercise 2 — The cursor
- Implement cursor pagination on the events listing (encode/decode of the uuid,
limitwith a ceiling of 100) and the contract test: 3 consecutive pages with no overlap,next_cursor: nullat the end, stable order. - The honest measurement: with a 2M-row seed, measure (EXPLAIN ANALYZE, 09) page 1 vs page 1000 with offset and with cursor: paste both plans. How much does deep offset cost?
- The moving window: insert 5 events between reading page 2 and requesting page 3 with offset: does anything repeat or get skipped? Repeat with the cursor: what happens? Paste both evidences.
- The removed
total: rewrite the front contract (35) withouttotaland add the test that the response NO LONGER carries it. Which endpoint DOES keep a total and why (the admin with filters? cached, 38?)?
Exercise 3 — The client's limits
- Add the
limitceiling (min(limit, 100)) and the test:?limit=100000returns 100 items WITHOUT an error (or a 400? decide and justify: silent or explicit, 13). - The bandwidth attack: with k6 (36), launch 50 VUs continuously requesting
limit=100and compare p95/DB bandwidth againstlimit=20. Which ceiling protects more? Write the decision in the API docs.
Exercise 4 — Compression
- Measure the 400-event listing: bytes uncompressed, with gzip 4, with gzip 9, and the CPU time of each level (37's cProfile or timeit). Where is the trade-off zone?
- Configure gzip in nginx (or gunicorn if there is no proxy):
gzip_comp_level 4,gzip_min_length 1024,gzip_types application/json. Test with curl--compressed: theContent-Encodingheader and the real bytes. - The cache and Vary: with 38's ETag active, serve one compressed response and one uncompressed for the same resource: does the cache confuse them without
Vary: Accept-Encoding? Demonstrate it with the 304 test (the client without gzip support must receive it UNcompressed).
Exercise 5 — The edges report
- Write
docs/perf/2027-09-bordes.md: the pool's arithmetic, the cursor's plan (before/after of page 1000), the limit ceiling, and the compression decision with numbers. - The project's rule for EVERY new listing: cursor by default, limit ceiling, no COUNT, gzip at the proxy. Where do you make that rule live (a mixin/base view? a parametrized contract test over all listings?)? Implement it.
Submit
Paste the connections table, the EXPLAIN plans of page 1000, the moving window's evidence and the edges report. Next: Lesson 40 — Docker (module 9).