django-startup-time
Django startup time
Full background — the four mechanisms (lazy router, model registration, receiver wiring, boot GC window), the regression guards, how to add code without regressing them, how to measure, and the detailed trap write-ups: docs/internal/django-startup-time.md. That doc is the single source of detail; this skill is the trigger and the checklist.
The guards live in posthog/test/test_startup_import_budget.py. When one fails, defer the import — don't remove an entry to dodge it. Conversely, when you deliberately defer a significant heavy lib off setup, add it to FORBIDDEN_AT_SETUP (after confirming it's absent from a bare django.setup()). New imports nobody has named yet are caught by test_no_new_heavy_imports_at_setup: any package not in posthog/test/setup_import_baseline.txt costing ≥100ms at setup fails the build — defer it; baseline only what every process genuinely needs at setup.
Defaults when adding backend code
- New app/product: register models from
models/__init__.py, wire receivers fromAppConfig.ready(), keepready()light. - New receiver: wire it at the owning
AppConfig.ready(), from a dedicated light module (activity_logging.py,signals.py) — never via the API/viewset module, even if it looks light today; those accumulate heavy imports andready()silently inherits them. - New heavy dependency (vendor SDK, Temporal/AI/ClickHouse, pandas/pyarrow/scipy): import it function-locally on the path that uses it with
# noqa: PLC0415, never at module scope. - Schema types on a setup-path module: enums from
posthog.schema_enums(cheap); pydantic models fromposthog.schemaonly inside the method that uses them. No module-levelfrom posthog.tasks...on setup paths —CeleryQueuelives inposthog.celery_queues. - New viewset/route: it no longer loads at setup — don't rely on import side effects; routes go in
rest_router.py, not the__init__.pyshim. - Any deferral relocates cost — ask which process pays now, on what path, and whether that path is latency-sensitive (background workers paying lazily: fine; web workers paying on first requests: usually not).
Traps to check before you commit
One line each — the doc has the full write-up and the fix recipe for every entry.