Litelm: LiteLLM Without the Bloat — I Measured It
Litelm hit Hacker News frontpage this morning with a claim that sounds too clean: litellm's routing and translation core in ~2,900 lines and two dependencies. Litellm, the de facto standard for calling LLMs through one Python interface, ships 183,000 lines and an 82 MB site-packages footprint. If the core really is that small, a lot of us have been dragging a proxy server into every lambda function for three years. So I installed both and measured everything.
The numbers: 59x less code, 512x less disk
I cloned kennethwolters/litelm (commit today, MIT) and pip-installed both packages into the same venv. Counting every .py file under each package:
# lines of Python
litelm: 3,121 total
litellm: 183,437 total
# installed size in site-packages
litelm: 160K
litellm: 82M
That's 59x less source and 512x less disk. The 82 MB includes the full proxy server, caching layers, budget manager, an MCP client, an evals framework — and, my favorite artifact, a blog_posts.json sitting inside the litellm package. Your completion library ships a content marketing archive. Bloat isn't always dead code; sometimes it's someone else's growth strategy.
Import time: the bloat tax is real but smaller than it looks
Warm import in a fresh interpreter, Python 3.14, measured with -X importtime:
litelm: 2.21s (2.11s of that is the openai SDK itself)
litellm: 4.93s
Here's the honest finding the README won't tell you: litelm's 2.1 seconds is almost entirely the openai SDK loading its enormous types tree. Litelm's own code adds ~0.3s on top. Litellm's overhead beyond the same SDK is ~3.1s. So the true ratio of library overhead is about 10x in litelm's favor, not 2.4x. In a cold-start-sensitive environment (serverless, CLI tools, agent sandboxes spun up per task) both numbers hurt, but litellm hurts three times more.
The call path works — and it's ~1.2ms faster per call
I ran both libraries' mock-response path twenty times each after warmup, since that exercises routing, message translation, and response construction without touching the network:
litelm call overhead: median 0.00ms mean 0.01ms
litellm call overhead: median 1.21ms mean 1.61ms
Identical API surface: litelm.completion("openai/gpt-4o", messages=[...], mock_response="MOCK-OK") returns the same ModelResponse shape litellm does, and streaming returns proper chunks. Swap is genuinely a find-and-replace on the import. What you lose: the Router (fallbacks, load balancing), caching, cost tracking, token counting, image/audio endpoints. My take: most apps that "use litellm" use it for exactly the litelm surface, and keep their fallback logic in config anyway. If you need the Router, litellm is still the tool. But 82 MB and a 1.2ms-per-call tax for a proxy you never started is a bad trade.
Test suite: 262 pass, with a catch
The repo's tests are real — not README-level smoke tests. Plain install: 258 passed, 4 failures in Anthropic error mapping. I traced them: the tests import anthropic, which is an optional extra. After pip install litelm[anthropic]: 261 passed, 1 trivial async-client teardown failure. That's a healthy suite for a 3,000-line project. One caution: Bedrock and Cloudflare handlers are unverified against real endpoints per the README's own table, so don't route production traffic there yet.
Bottom line
Litelm's claim survives contact with measurement. The litellm core really is ~3k lines; everything else is a platform bundled into your dependency tree. For library authors the lesson is sharper: litellm won the market by accreting features, and litelm is the reminder that the accretion is optional. Install litelm for the call path, keep litellm pinned only where you actually run its Router or proxy. And check what's inside your site-packages — 82 MB of proxy server and someone's blog posts is not a dependency, it's a tenant.
- kennethwolters/litelm — GitHub repository and README — September 2026
- litelm on PyPI (v0.5.2) — PyPI
- litellm on PyPI (v1.100.1) — PyPI
- Hacker News frontpage, "Litelm: LiteLLM Without the Bloat" — September 2026