Nobody has started this yet — be first.
Business impact
The entire point of the bounded IngestQueue is that memory is capped regardless of traffic — but that guarantee assumes individual requests stay reasonably sized. ingest_batch accepts a list of events with no upper bound on length, so a single POST /events/batch call can force the server to fully parse and validate an arbitrarily large JSON array into memory before the handler even runs, well before backpressure ever gets a chance to apply. Settings.max_batch_request_size already exists specifically to cap this, but nothing reads it.
Problem
ingest_batch accepts events_in: list[EventIn] with no check against Settings.max_batch_request_size (default 5000) anywhere in the handler.
Current behavior
Posting a batch of 10 events against a configured max_batch_request_size=5 still returns 200 with all 10 accepted — ingest_batch never compares len(events_in) to settings.max_batch_request_size.
Expected behavior
A POST /events/batch request over max_batch_request_size events is rejected with a clear 4xx before the handler loops over events and calls queue.put() for each one; a batch at or under the limit is processed normally.
Steps to reproduce
pytest practice_tickets/tests/test_ticket_13_batch_size_cap.py -v — posts a 10-event batch against a configured max_batch_request_size=5 and confirms it is currently accepted with 200 instead of rejected.Why this matters
FastAPI has to fully parse and validate a JSON array into a list[EventIn] before your handler code runs at all; a request with, say, 5 million events forces the server to materialize 5 million EventIn Pydantic objects in memory just to find out the request should be rejected — by which point the damage is already done. The cap needs to stop the request as early as possible.
Suggested approach
Look at how ingest_batch currently starts (app/routers/events.py) and where settings.max_batch_request_size would need to be checked relative to len(events_in). You'll need access to Settings in this handler — app/dependencies.py::get_settings already exists and is used the same way elsewhere in this file. Think about whether checking length after FastAPI has already parsed the whole list into EventIn objects still achieves the goal, or whether a smaller list is needed to meaningfully cap peak memory.
Acceptance criteria
Verification
pytest practice_tickets/tests/test_ticket_13_batch_size_cap.py -v
Hints (0/2)
Try it without hints first — the reading is the exercise.
Working on this ticket
Work on a branch named for the ticket — that's what you'll submit.
Branch off your fork
Sign in to create it automatically, or do it yourself:
$git checkout -b feat/batch-request-size-capFix it and commit
Meet every acceptance criterion, and add a test that would have caught this.
Push the branch
$git push -u origin feat/batch-request-size-capSubmit it below
Paste your fork URL and the branch name, with a short write-up of the root cause.
Questions
Ask about anything unclear in the ticket — the maintainer and anyone who has solved it can answer. Please don't post full solutions.
Sign in to ask a question or reply.
Sign inhttp://localhost:8000localhost:5432curl localhost:8000/healthzcurl localhost:8000/readyzWork the tickets in practice_tickets/tickets/ (ordered easy → hard); each names one dedicated test in practice_tickets/tests/:
pytest practice_tickets/tests/test_ticket_01_persisted_count.py -v # a single ticket
./practice_tickets/run_tickets.sh # all 20, clean pass/fail summary
TICKET-17 needs a real Postgres to run at all (it checks which column a value lands in, which no fake/in-memory DB backend can meaningfully verify) — set TEST_DATABASE_URL=postgresql://<you>@localhost/ingest_test before running it or the full suite; without it, that one test is skipped, not failed.
Level 2
Implement a feature
Extend the system within its own patterns.