{"id":"09c0cbfb-5cd5-4a2f-8bda-60a89727f04f","shortId":"vHATxQ","kind":"skill","title":"litestar-granian","tagline":"Auto-activate for litestar_granian imports, GranianPlugin, GranianConfig, granian CLI commands, worker/thread tuning, HTTP/2, SSL, backpressure, or ASGI server config in a Litestar app. Use when serving Litestar with Granian in development or production. Not for FastAPI, Django, ","description":"# litestar-granian\n\n`litestar-granian` is the first-party plugin that integrates the [Granian](https://github.com/emmett-framework/granian) Rust-based ASGI server with Litestar. Adding `GranianPlugin()` to a Litestar app makes `litestar run` launch Granian instead of uvicorn — same CLI, much higher throughput, native HTTP/2, and lower memory.\n\nFor Litestar apps, **always prefer `litestar-granian` over plain `granian` CLI**: the plugin wires Granian into Litestar's lifespan, signal handling, CLI flags, and dev-mode reload logic.\n\n## Code Style Rules\n\n- Use PEP 604 unions: `T | None`, never `Optional[T]`\n- Consumer Litestar apps that wire `GranianPlugin` MAY use `from __future__ import annotations` — canonical Litestar apps do.\n- Async all I/O — sync handlers block Granian's async runtime and starve workers.\n\n## Quick Reference\n\n### Zero-config plugin install\n\n```python\nfrom litestar import Litestar\nfrom litestar_granian import GranianPlugin\n\napp = Litestar(\n    route_handlers=[...],\n    plugins=[GranianPlugin()],\n)\n```\n\n```bash\n# Same CLI as before; now backed by Granian\nlitestar --app app:app run --host 0.0.0.0 --port 8000\n\n# Dev with reload\nlitestar --app app:app run --reload\n```\n\n### Tuned plugin install\n\n`GranianPlugin` itself takes no configuration — it registers the `litestar run` CLI command and wires Granian's loggers into Litestar's logging config. All tuning (`workers`, `threads`, `http`, `backpressure`, SSL, structured access logs) happens on the `litestar run` command line or via environment variables at deploy time.\n\n```python\nfrom litestar import Litestar\nfrom litestar_granian import GranianPlugin\n\napp = Litestar(\n    route_handlers=[...],\n    plugins=[GranianPlugin()],\n)\n```\n\n```bash\n# Production-tuned launch (8 cores, runtime threading mode, HTTP/2, bounded backpressure)\nlitestar --app app:app run \\\n    --workers 8 \\\n    --threads 2 \\\n    --threading-mode runtime \\\n    --http auto \\\n    --backpressure 2000 \\\n    --log-access \\\n    --log-access-format json\n```\n\n### Production with SSL\n\n```bash\nlitestar --app app:app run \\\n    --workers 8 \\\n    --threads 2 \\\n    --threading-mode runtime \\\n    --http auto \\\n    --backpressure 2000 \\\n    --ssl-certificate /etc/ssl/certs/app.crt \\\n    --ssl-keyfile /etc/ssl/private/app.key\n```\n\n### Granian vs Uvicorn for Litestar\n\n| Feature | Granian (`litestar-granian`) | Uvicorn |\n| --- | --- | --- |\n| Core | Rust (hyper + tokio) | Python |\n| HTTP/2 | Native | Requires `h2` |\n| Throughput | Higher | Moderate |\n| Memory | Lower | Higher |\n| Litestar plugin | First-party (`GranianPlugin`) | None — generic ASGI |\n| `litestar run` integration | Yes — drop-in replacement | Default if no plugin |\n| Production default | **Preferred** | Fallback only |\n\n<workflow>\n\n## Workflow\n\n### Step 1: Install\n\n```bash\npip install litestar-granian\n```\n\n### Step 2: Register the Plugin\n\nAdd `GranianPlugin()` to the `Litestar(plugins=[...])` list. No other code change is required for dev — `litestar run` now uses Granian.\n\n### Step 3: Tune for Deployment\n\nPass tuning flags to the `litestar run` command for production. Match `--workers` to CPU cores, set `--threading-mode runtime` for async workloads, enable `--http auto`, set `--backpressure` to bound queue depth.\n\n### Step 4: Add SSL or Reverse Proxy\n\nEither terminate TLS at Granian (`--ssl-certificate` / `--ssl-keyfile`) or behind a load balancer. Inside a container without an external proxy, prefer Granian-native SSL.\n\n### Step 5: Verify\n\nRun the app, confirm the startup banner mentions Granian, and load-test before going live. Tune `workers` / `backpressure` to match peak load without exhausting memory.\n\n</workflow>\n\n<guardrails>\n\n## Guardrails\n\n- **Use `litestar-granian` for Litestar apps**, not the bare `granian` CLI — the plugin integrates with Litestar lifespan, dev-reload, signal handling, and CLI flags.\n- **Never mix `GranianPlugin` with manual `granian` invocations** — the plugin owns the server lifecycle. Pick one.\n- **Match `workers` to CPU cores** for production. Under-provisioned wastes hardware; over-provisioned bloats memory.\n- **Use `threading_mode=\"runtime\"`** for async (Litestar) workloads. `workers` mode is for CPU-bound sync code.\n- **Set `http=\"auto\"`** unless you have a documented reason to restrict HTTP version. Pure HTTP/2 breaks HTTP/1.1 clients.\n- **Set `backpressure`** in production — without a bound, traffic spikes lead to unbounded queuing and OOM.\n- **Use `GranianPlugin` over `uvicorn`** for all Litestar deployments — higher throughput, native HTTP/2, lower memory.\n- **Never `async def` blocked by sync I/O** — Granian's event loop must stay free; sync DB/HTTP calls inside `async def` starve workers.\n\n</guardrails>\n\n<validation>\n\n### Validation Checkpoint\n\nBefore delivering a Litestar + Granian deployment, verify:\n\n- [ ] `GranianPlugin` is in `app.plugins`\n- [ ] No competing manual `granian app:app` invocations in scripts/Dockerfile\n- [ ] `litestar run --workers` matches CPU cores (or has a documented deviation)\n- [ ] `--threading-mode runtime` is set on the launch command\n- [ ] `--http auto` is set on the launch command\n- [ ] `--backpressure` is set for production\n- [ ] SSL flags or a documented reverse proxy handle TLS for any public service\n- [ ] No `uvicorn` in production deps (or a justification is documented)\n\n</validation>\n\n<example>\n\n## Example\n\n**Task:** Production Litestar app with `GranianPlugin`, tuned for an 8-core host with SSL and structured access logging.\n\n```python\n# app.py\nfrom litestar import Litestar, get\nfrom litestar_granian import GranianPlugin\n\n\n@get(\"/health\")\nasync def health() -> dict[str, str]:\n    return {\"status\": \"ok\"}\n\n\napp = Litestar(\n    route_handlers=[health],\n    plugins=[GranianPlugin()],\n)\n```\n\n```bash\n# Production launch — same CLI, now Granian-backed\nlitestar --app app:app run --host 0.0.0.0 --port 8443\n```\n\nFor Dockerfile / process manager invocations, prefer the same Litestar CLI command rather than calling `granian` directly.\n\n</example>\n\n---\n\n## Reference: Granian CLI (when not using the plugin)\n\nIf you need to run Granian directly (e.g., for non-Litestar code paths), the standard `granian` CLI flags are the same ones the Litestar plugin forwards from `litestar run`:\n\n```bash\ngranian app:main \\\n  --interface asgi \\\n  --host 0.0.0.0 \\\n  --port 8443 \\\n  --workers 8 \\\n  --threads 2 \\\n  --threading-mode runtime \\\n  --http auto \\\n  --backpressure 2000 \\\n  --ssl-certfile /etc/ssl/certs/app.crt \\\n  --ssl-keyfile /etc/ssl/private/app.key \\\n  --log-level info \\\n  --access-log \\\n  --log-access-fmt json\n```\n\nFor Litestar apps, prefer the plugin path described above.\n\n## Cross-References\n\n- **[litestar](../litestar/SKILL.md)** — Litestar app initialization, plugins, and lifespan.\n\n## Official References\n\n- <https://github.com/litestar-org/litestar-granian>\n- <https://github.com/emmett-framework/granian>\n- <https://pypi.org/project/granian/>\n\n## Shared Styleguide Baseline\n\n- Use shared styleguides for generic language/framework rules to reduce duplication in this skill.\n- [General Principles](../litestar-styleguide/references/general.md)\n- [Python](../litestar-styleguide/references/python.md)\n- [Litestar](../litestar-styleguide/references/litestar.md)\n- Keep this skill focused on tool-specific workflows, edge cases, and integration details.","tags":["litestar","granian","skills","litestar-org","advanced-alchemy","agent-skills","agentskills","ai-agents","claude-code-plugin","claude-code-skills","gemini-cli-extension","htmx"],"capabilities":["skill","source-litestar-org","skill-litestar-granian","topic-advanced-alchemy","topic-agent-skills","topic-agentskills","topic-ai-agents","topic-claude-code-plugin","topic-claude-code-skills","topic-gemini-cli-extension","topic-htmx","topic-inertia","topic-litestar","topic-mcp","topic-python"],"categories":["litestar-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/litestar-org/litestar-skills/litestar-granian","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add litestar-org/litestar-skills","source_repo":"https://github.com/litestar-org/litestar-skills","install_from":"skills.sh"}},"qualityScore":"0.453","qualityRationale":"deterministic score 0.45 from registry signals: · indexed on github topic:agent-skills · 7 github stars · SKILL.md body (7,313 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T19:13:53.955Z","embedding":null,"createdAt":"2026-05-18T13:20:57.487Z","updatedAt":"2026-05-18T19:13:53.955Z","lastSeenAt":"2026-05-18T19:13:53.955Z","tsv":"'/emmett-framework/granian':948 '/emmett-framework/granian)':61 '/etc/ssl/certs/app.crt':341,904 '/etc/ssl/private/app.key':345,908 '/health':790 '/litestar-org/litestar-granian':945 '/litestar-styleguide/references/general.md':970 '/litestar-styleguide/references/litestar.md':974 '/litestar-styleguide/references/python.md':972 '/litestar/skill.md':934 '/project/granian/':951 '0.0.0.0':202,822,886 '1':400 '2':300,329,409,892 '2000':308,337,900 '3':434 '4':471 '5':506 '604':128 '8':284,298,327,768,890 '8000':204 '8443':824,888 'access':247,311,314,775,914,918 'access-log':913 'activ':6 'ad':69 'add':413,472 'alway':96 'annot':146 'app':28,74,95,137,149,181,197,198,199,209,210,211,273,293,294,295,322,323,324,510,541,696,697,762,800,817,818,819,881,923,936 'app.plugins':691 'app.py':778 'asgi':22,65,380,884 'async':151,159,459,598,658,675,791 'auto':5,306,335,463,612,723,898 'auto-activ':4 'back':193,815 'backpressur':20,244,291,307,336,465,526,629,730,899 'balanc':492 'banner':514 'bare':544 'base':64 'baselin':954 'bash':187,279,320,402,807,879 'behind':489 'bloat':591 'block':156,660 'bound':290,467,607,634 'break':625 'call':673,838 'canon':147 'case':985 'certfil':903 'certif':340,484 'chang':423 'checkpoint':680 'cli':14,84,104,115,189,227,546,559,811,834,843,866 'client':627 'code':123,422,609,861 'command':15,228,254,445,721,729,835 'compet':693 'config':24,168,238 'configur':221 'confirm':511 'consum':135 'contain':495 'core':285,357,452,580,706,769 'cpu':451,579,606,705 'cpu-bound':605 'cross':931 'cross-refer':930 'db/http':672 'def':659,676,792 'default':389,394 'deliv':682 'dep':752 'deploy':261,437,650,686 'depth':469 'describ':928 'detail':988 'dev':119,205,427,554 'dev-mod':118 'dev-reload':553 'develop':36 'deviat':711 'dict':794 'direct':840,855 'django':42 'dockerfil':826 'document':617,710,739,757 'drop':386 'drop-in':385 'duplic':964 'e.g':856 'edg':984 'either':477 'enabl':461 'environ':258 'event':666 'exampl':758 'exhaust':532 'extern':498 'fallback':396 'fastapi':41 'featur':351 'first':52,375 'first-parti':51,374 'flag':116,440,560,736,867 'fmt':919 'focus':978 'format':315 'forward':875 'free':670 'futur':144 'general':968 'generic':379,959 'get':783,789 'github.com':60,944,947 'github.com/emmett-framework/granian':946 'github.com/emmett-framework/granian)':59 'github.com/litestar-org/litestar-granian':943 'go':522 'granian':3,9,13,34,45,48,58,79,100,103,108,157,178,195,231,270,346,352,355,407,432,481,502,516,538,545,566,664,685,695,786,814,839,842,854,865,880 'granian-back':813 'granian-n':501 'granianconfig':12 'granianplugin':11,70,140,180,186,217,272,278,377,414,563,644,688,764,788,806 'guardrail':534 'h2':365 'handl':114,557,742 'handler':155,184,276,803 'happen':249 'hardwar':587 'health':793,804 'higher':86,367,371,651 'host':201,770,821,885 'http':243,305,334,462,611,621,722,897 'http/1.1':626 'http/2':18,89,289,362,624,654 'hyper':359 'i/o':153,663 'import':10,145,174,179,266,271,781,787 'info':912 'initi':937 'insid':493,674 'instal':170,216,401,404 'instead':80 'integr':56,383,549,987 'interfac':883 'invoc':567,698,829 'json':316,920 'justif':755 'keep':975 'keyfil':344,487,907 'language/framework':960 'launch':78,283,720,728,809 'lead':637 'level':911 'lifecycl':573 'lifespan':112,552,940 'line':255 'list':419 'litestar':2,8,27,32,44,47,68,73,76,94,99,110,136,148,173,175,177,182,196,208,225,235,252,265,267,269,274,292,321,350,354,372,381,406,417,428,443,537,540,551,599,649,684,701,761,780,782,785,801,816,833,860,873,877,922,933,935,973 'litestar-granian':1,43,46,98,353,405,536 'live':523 'load':491,519,530 'load-test':518 'log':237,248,310,313,776,910,915,917 'log-access':309 'log-access-fmt':916 'log-access-format':312 'log-level':909 'logger':233 'logic':122 'loop':667 'lower':91,370,655 'main':882 'make':75 'manag':828 'manual':565,694 'match':448,528,576,704 'may':141 'memori':92,369,533,592,656 'mention':515 'mix':562 'mode':120,288,303,332,456,595,602,714,895 'moder':368 'much':85 'must':668 'nativ':88,363,503,653 'need':851 'never':132,561,657 'non':859 'non-litestar':858 'none':131,378 'offici':941 'ok':799 'one':575,871 'oom':642 'option':133 'over-provis':588 'own':570 'parti':53,376 'pass':438 'path':862,927 'peak':529 'pep':127 'pick':574 'pip':403 'plain':102 'plugin':54,106,169,185,215,277,373,392,412,418,548,569,805,848,874,926,938 'port':203,823,887 'prefer':97,395,500,830,924 'principl':969 'process':827 'product':38,281,317,393,447,582,631,734,751,760,808 'production-tun':280 'provis':585,590 'proxi':476,499,741 'public':746 'pure':623 'pypi.org':950 'pypi.org/project/granian/':949 'python':171,263,361,777,971 'queu':640 'queue':468 'quick':164 'rather':836 'reason':618 'reduc':963 'refer':165,841,932,942 'regist':223,410 'reload':121,207,213,555 'replac':388 'requir':364,425 'restrict':620 'return':797 'revers':475,740 'rout':183,275,802 'rule':125,961 'run':77,200,212,226,253,296,325,382,429,444,508,702,820,853,878 'runtim':160,286,304,333,457,596,715,896 'rust':63,358 'rust-bas':62 'scripts/dockerfile':700 'serv':31 'server':23,66,572 'servic':747 'set':453,464,610,628,717,725,732 'share':952,956 'signal':113,556 'skill':967,977 'skill-litestar-granian' 'source-litestar-org' 'specif':982 'spike':636 'ssl':19,245,319,339,343,473,483,486,504,735,772,902,906 'ssl-certfil':901 'ssl-certif':338,482 'ssl-keyfil':342,485,905 'standard':864 'startup':513 'starv':162,677 'status':798 'stay':669 'step':399,408,433,470,505 'str':795,796 'structur':246,774 'style':124 'styleguid':953,957 'sync':154,608,662,671 'take':219 'task':759 'termin':478 'test':520 'thread':242,287,299,302,328,331,455,594,713,891,894 'threading-mod':301,330,454,712,893 'throughput':87,366,652 'time':262 'tls':479,743 'tokio':360 'tool':981 'tool-specif':980 'topic-advanced-alchemy' 'topic-agent-skills' 'topic-agentskills' 'topic-ai-agents' 'topic-claude-code-plugin' 'topic-claude-code-skills' 'topic-gemini-cli-extension' 'topic-htmx' 'topic-inertia' 'topic-litestar' 'topic-mcp' 'topic-python' 'traffic':635 'tune':17,214,240,282,435,439,524,765 'unbound':639 'under-provis':583 'union':129 'unless':613 'use':29,126,142,431,535,593,643,846,955 'uvicorn':82,348,356,646,749 'valid':679 'variabl':259 'verifi':507,687 'version':622 'via':257 'vs':347 'wast':586 'wire':107,139,230 'without':496,531,632 'worker':163,241,297,326,449,525,577,601,678,703,889 'worker/thread':16 'workflow':398,983 'workload':460,600 'yes':384 'zero':167 'zero-config':166","prices":[{"id":"557b8869-376a-447f-ad21-8a32c8bcb451","listingId":"09c0cbfb-5cd5-4a2f-8bda-60a89727f04f","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"litestar-org","category":"litestar-skills","install_from":"skills.sh"},"createdAt":"2026-05-18T13:20:57.487Z"}],"sources":[{"listingId":"09c0cbfb-5cd5-4a2f-8bda-60a89727f04f","source":"github","sourceId":"litestar-org/litestar-skills/litestar-granian","sourceUrl":"https://github.com/litestar-org/litestar-skills/tree/main/skills/litestar-granian","isPrimary":false,"firstSeenAt":"2026-05-18T13:20:57.487Z","lastSeenAt":"2026-05-18T19:13:53.955Z"}],"details":{"listingId":"09c0cbfb-5cd5-4a2f-8bda-60a89727f04f","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"litestar-org","slug":"litestar-granian","github":{"repo":"litestar-org/litestar-skills","stars":7,"topics":["advanced-alchemy","agent-skills","agentskills","ai-agents","claude-code-plugin","claude-code-skills","gemini-cli-extension","htmx","inertia","litestar","mcp","python","sqlspec"],"license":"mit","html_url":"https://github.com/litestar-org/litestar-skills","pushed_at":"2026-05-13T16:04:09Z","description":"Opinionated first-party agent skills, plugins, subagents, slash commands, and MCP servers for the Litestar framework ecosystem — publishable to Claude Code, Gemini CLI, Codex CLI, Cursor, OpenCode, and VS Code/Copilot from a single repo.","skill_md_sha":"3dacbebd9b70925ea1194fad5868eca859eda508","skill_md_path":"skills/litestar-granian/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/litestar-org/litestar-skills/tree/main/skills/litestar-granian"},"layout":"multi","source":"github","category":"litestar-skills","frontmatter":{"name":"litestar-granian","description":"Auto-activate for litestar_granian imports, GranianPlugin, GranianConfig, granian CLI commands, worker/thread tuning, HTTP/2, SSL, backpressure, or ASGI server config in a Litestar app. Use when serving Litestar with Granian in development or production. Not for FastAPI, Django, non-Litestar apps, or uvicorn-specific configuration."},"skills_sh_url":"https://skills.sh/litestar-org/litestar-skills/litestar-granian"},"updatedAt":"2026-05-18T19:13:53.955Z"}}