{"id":"04a74d31-ac97-4e64-8dae-8c497b42f2c0","shortId":"XAJN9j","kind":"skill","title":"granian","tagline":"Use when deploying ASGI, WSGI, or RSGI apps with Granian, editing granian CLI commands, worker or thread settings, SSL, HTTP/2, backpressure, or replacing uvicorn for production.","description":"# Granian Server Skill\n\nGranian is a high-performance Rust-based ASGI/WSGI/RSGI server. Built on Rust's hyper and tokio for maximum performance, it is the preferred server for all production deployments over uvicorn.\n\nFor Litestar integration, see `flow:litestar` → deployment section (`GranianPlugin` provides zero-config integration).\n\n## Quick Reference\n\n### CLI Usage\n\n```bash\n# Basic ASGI (Litestar, Starlette, FastAPI)\ngranian app:main --interface asgi --host 0.0.0.0 --port 8000\n\n# RSGI (Granian-native, highest performance)\ngranian app:main --interface rsgi --host 0.0.0.0 --port 8000\n\n# WSGI (Flask, Django)\ngranian app:main --interface wsgi --host 0.0.0.0 --port 8000\n```\n\n### Worker Configuration\n\n```bash\n# Production: match workers to CPU cores\ngranian app:main --interface asgi \\\n  --workers 4 \\\n  --threads 2 \\\n  --threading-mode runtime\n\n# Development: single worker with reload\ngranian app:main --interface asgi --workers 1 --reload\n```\n\n### Interface Options\n\n| Interface | Use For | Notes |\n|-----------|---------|-------|\n| `asgi` | Litestar, Starlette, FastAPI | Standard ASGI spec |\n| `rsgi` | Granian-native apps | Highest performance, Granian-specific |\n| `wsgi` | Flask, Django | Sync frameworks |\n\n### Binding and Paths\n\n```bash\ngranian app:main \\\n  --host 0.0.0.0 \\\n  --port 8000 \\\n  --url-path-prefix /api\n```\n\n### SSL Configuration\n\n```bash\ngranian app:main --interface asgi \\\n  --host 0.0.0.0 \\\n  --port 8443 \\\n  --ssl-certfile /etc/ssl/certs/app.crt \\\n  --ssl-keyfile /etc/ssl/private/app.key\n```\n\n### HTTP Version\n\n```bash\n# Support both HTTP/1.1 and HTTP/2 (recommended for production)\ngranian app:main --http auto\n\n# HTTP/2 only\ngranian app:main --http 2\n\n# HTTP/1.1 only\ngranian app:main --http 1\n```\n\n### Backpressure and Concurrency\n\n```bash\n# Limit max concurrent connections to prevent overload\ngranian app:main --backpressure 1000\n```\n\n### Logging\n\n```bash\n# Structured JSON logging with access log\ngranian app:main \\\n  --log-level info \\\n  --access-log \\\n  --log-access-fmt json\n```\n\n### Granian vs Uvicorn Comparison\n\n| Feature | Granian | Uvicorn |\n|---------|---------|---------|\n| Core language | Rust (hyper + tokio) | Python |\n| RSGI support | Yes (native) | No |\n| HTTP/2 native | Yes | No (via h2 package) |\n| Threading model | `workers` or `runtime` | GIL-bound workers |\n| Performance | Higher throughput | Moderate |\n| Memory footprint | Lower | Higher |\n| Production default | Preferred | Acceptable fallback |\n\n<workflow>\n\n## Workflow\n\n### Step 1: Install Granian\n\n```bash\npip install granian\n```\n\n### Step 2: Configure Interface Based on Framework\n\nChoose the interface flag matching the framework:\n\n- `--interface asgi` for Litestar, Starlette, FastAPI\n- `--interface rsgi` for Granian-native apps (highest performance)\n- `--interface wsgi` for Flask or Django\n\n### Step 3: Set Workers and Threads for Deployment Target\n\nMatch `--workers` to available CPU cores. Use `--threading-mode runtime` for async workloads (ASGI/RSGI). Use `--threading-mode workers` for CPU-bound sync workloads.\n\n```bash\n# Typical production formula\ngranian app:main \\\n  --interface asgi \\\n  --workers $(nproc) \\\n  --threads 2 \\\n  --threading-mode runtime\n```\n\n### Step 4: Add SSL for Production\n\nAlways terminate SSL at granian or a reverse proxy. Prefer granian-native SSL for containerized deployments without an external proxy.\n\n```bash\ngranian app:main \\\n  --ssl-certfile /run/secrets/tls.crt \\\n  --ssl-keyfile /run/secrets/tls.key\n```\n\n### Step 5: Test Under Load\n\nVerify configuration with a load test before going live. Tune `--backpressure` to match expected peak concurrency without exhausting system resources.\n\n</workflow>\n\n<guardrails>\n\n## Guardrails\n\n- **Use `--interface asgi` for ASGI frameworks** -- Litestar, Starlette, and FastAPI require `asgi`. Using `rsgi` with a pure ASGI app will fail at runtime.\n- **Match `--workers` to CPU cores for production** -- under-provisioned workers waste hardware; over-provisioned workers increase memory pressure without throughput gains.\n- **Use `--threading-mode runtime` for async workloads** -- runtime mode maps threads to the tokio runtime, giving better async scheduling than `workers` mode for I/O-heavy apps.\n- **Prefer Granian over Uvicorn for all production deployments** -- Granian provides higher throughput, lower memory use, and native HTTP/2 support with no additional packages.\n- **Set `--backpressure` to prevent overload under high traffic** -- without a limit, unbounded queuing leads to memory exhaustion and cascading timeouts.\n- **Set `--http auto` to support both HTTP/1.1 and HTTP/2** -- most load balancers and clients expect HTTP/1.1 fallback even when HTTP/2 is preferred.\n- **Never pin to `--http 2` alone in mixed-client environments** -- clients that do not support HTTP/2 will receive connection errors.\n\n</guardrails>\n\n<validation>\n\n### Validation Checkpoint\n\nBefore delivering a Granian deployment configuration, verify:\n\n- [ ] `--interface` matches the framework (asgi/rsgi/wsgi)\n- [ ] `--workers` is set to CPU core count (or a documented reason for deviation)\n- [ ] `--threading-mode runtime` is used for async (ASGI/RSGI) workloads\n- [ ] `--http auto` is set unless there is a specific reason to restrict HTTP version\n- [ ] `--backpressure` is set for production deployments\n- [ ] SSL flags are present for any publicly exposed production service\n- [ ] Granian is used instead of uvicorn (or a reason is documented)\n\n</validation>\n\n<example>\n\n## Example\n\n**Task:** Production deployment of a Litestar ASGI app on an 8-core host with SSL and structured logging.\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 zero-config integration with Litestar, use `GranianPlugin`:\n\n```python\nfrom litestar import Litestar\nfrom litestar.plugins.granian import GranianPlugin\n\napp = Litestar(\n    route_handlers=[...],\n    plugins=[GranianPlugin()],\n)\n```\n\nThen run via the Litestar CLI:\n\n```bash\nlitestar --app app:app run --host 0.0.0.0 --port 8000\n```\n\n</example>\n\n---\n\n## Official References\n\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](https://github.com/cofin/flow/blob/main/templates/styleguides/general.md)\n- [Python](https://github.com/cofin/flow/blob/main/templates/styleguides/languages/python.md)\n- Keep this skill focused on tool-specific workflows, edge cases, and integration details.","tags":["granian","flow","cofin","agent-skills","ai-agents","beads","claude-code","codex","cursor","developer-tools","gemini-cli","opencode"],"capabilities":["skill","source-cofin","skill-granian","topic-agent-skills","topic-ai-agents","topic-beads","topic-claude-code","topic-codex","topic-cursor","topic-developer-tools","topic-gemini-cli","topic-opencode","topic-plugin","topic-slash-commands","topic-spec-driven-development"],"categories":["flow"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/cofin/flow/granian","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add cofin/flow","source_repo":"https://github.com/cofin/flow","install_from":"skills.sh"}},"qualityScore":"0.455","qualityRationale":"deterministic score 0.46 from registry signals: · indexed on github topic:agent-skills · 11 github stars · SKILL.md body (6,799 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:07:37.387Z","embedding":null,"createdAt":"2026-04-23T13:03:59.520Z","updatedAt":"2026-05-18T19:07:37.387Z","lastSeenAt":"2026-05-18T19:07:37.387Z","tsv":"'/api':201 '/cofin/flow/blob/main/templates/styleguides/general.md)':864 '/cofin/flow/blob/main/templates/styleguides/languages/python.md)':868 '/emmett-framework/granian':840 '/etc/ssl/certs/app.crt':217,779 '/etc/ssl/private/app.key':221,783 '/project/granian/':843 '/run/secrets/tls.crt':468 '/run/secrets/tls.key':472 '0.0.0.0':93,108,120,194,211,761,833 '1':156,251,340 '1000':267 '2':140,244,348,429,640,767 '2000':775 '3':383 '4':138,435 '5':474 '8':746,765 '8000':95,110,122,196,835 '8443':213,763 'accept':336 'access':274,284,288,789,793 'access-log':283,788 'add':436 'addit':592 'alon':641 'alway':440 'app':9,88,103,115,133,151,175,191,206,234,241,248,264,277,373,422,463,517,570,743,756,814,828,829,830 'asgi':5,83,91,136,154,164,169,209,362,425,501,503,510,516,742,759 'asgi/rsgi':405,692 'asgi/rsgi/wsgi':670 'asgi/wsgi/rsgi':40 'async':403,551,563,691 'auto':237,616,695,773 'avail':394 'backpressur':22,252,266,488,595,708,774 'balanc':625 'base':39,351 'baselin':846 'bash':81,125,189,204,224,255,269,343,417,461,754,826 'basic':82 'better':562 'bind':186 'bound':323,414 'built':42 'cascad':612 'case':879 'certfil':216,467,778 'checkpoint':658 'choos':354 'cli':14,79,825 'client':627,645,647 'command':15 'comparison':294 'concurr':254,258,493 'config':75,799 'configur':124,203,349,479,664 'connect':259,655 'container':455 'core':131,298,396,526,676,747 'count':677 'cpu':130,395,413,525,675 'cpu-bound':412 'default':334 'deliv':660 'deploy':4,60,69,389,456,578,663,713,738 'detail':882 'develop':145 'deviat':683 'django':113,183,381 'document':680,734 'duplic':856 'edg':878 'edit':12 'environ':646 'error':656 'even':631 'exampl':735 'exhaust':495,610 'expect':491,628 'expos':721 'extern':459 'fail':519 'fallback':337,630 'fastapi':86,167,366,508 'featur':295 'flag':357,715 'flask':112,182,379 'flow':67 'fmt':289,794 'focus':872 'footprint':330 'formula':420 'framework':185,353,360,504,669 'gain':544 'general':860 'generic':851 'gil':322 'gil-bound':321 'github.com':839,863,867 'github.com/cofin/flow/blob/main/templates/styleguides/general.md)':862 'github.com/cofin/flow/blob/main/templates/styleguides/languages/python.md)':866 'github.com/emmett-framework/granian':838 'give':561 'go':485 'granian':1,11,13,28,31,87,98,102,114,132,150,173,179,190,205,233,240,247,263,276,291,296,342,346,371,421,444,451,462,572,579,662,724,755 'granian-n':97,172,370,450 'granian-specif':178 'granianplugin':71,804,813,819 'guardrail':498 'h2':314 'handler':817 'hardwar':534 'high':35,600 'high-perform':34 'higher':326,332,581 'highest':100,176,374 'host':92,107,119,193,210,748,760,832 'http':222,236,243,250,615,639,694,706,772 'http/1.1':227,245,620,629 'http/2':21,229,238,309,588,622,633,652 'hyper':46,301 'i/o-heavy':569 'import':808,812 'increas':539 'info':282,787 'instal':341,345 'instead':727 'integr':65,76,800,881 'interfac':90,105,117,135,153,158,160,208,350,356,361,367,376,424,500,666,758 'json':271,290,795 'keep':869 'keyfil':220,471,782 'languag':299 'language/framework':852 'lead':607 'level':281,786 'limit':256,604 'litestar':64,68,84,165,364,505,741,802,807,809,815,824,827 'litestar.plugins.granian':811 'live':486 'load':477,482,624 'log':268,272,275,280,285,287,753,785,790,792 'log-access-fmt':286,791 'log-level':279,784 'lower':331,583 'main':89,104,116,134,152,192,207,235,242,249,265,278,423,464,757 'map':555 'match':127,358,391,490,522,667 'max':257 'maximum':50 'memori':329,540,584,609 'mix':644 'mixed-cli':643 'mode':143,400,409,432,548,554,567,686,770 'model':317 'moder':328 'nativ':99,174,307,310,372,452,587 'never':636 'note':163 'nproc':427 'offici':836 'option':159 'over-provis':535 'overload':262,598 'packag':315,593 'path':188,199 'peak':492 'perform':36,51,101,177,325,375 'pin':637 'pip':344 'plugin':818 'port':94,109,121,195,212,762,834 'prefer':55,335,449,571,635 'prefix':200 'present':717 'pressur':541 'prevent':261,597 'principl':861 'product':27,59,126,232,333,419,439,528,577,712,722,737 'provid':72,580 'provis':531,537 'proxi':448,460 'public':720 'pure':515 'pypi.org':842 'pypi.org/project/granian/':841 'python':303,805,865 'queu':606 'quick':77 'reason':681,703,732 'receiv':654 'recommend':230 'reduc':855 'refer':78,837 'reload':149,157 'replac':24 'requir':509 'resourc':497 'restrict':705 'revers':447 'rout':816 'rsgi':8,96,106,171,304,368,512 'rule':853 'run':821,831 'runtim':144,320,401,433,521,549,553,560,687,771 'rust':38,44,300 'rust-bas':37 'schedul':564 'section':70 'see':66 'server':29,41,56 'servic':723 'set':19,384,594,614,673,697,710 'share':844,848 'singl':146 'skill':30,859,871 'skill-granian' 'source-cofin' 'spec':170 'specif':180,702,876 'ssl':20,202,215,219,437,442,453,466,470,714,750,777,781 'ssl-certfil':214,465,776 'ssl-keyfil':218,469,780 'standard':168 'starlett':85,166,365,506 'step':339,347,382,434,473 'structur':270,752 'styleguid':845,849 'support':225,305,589,618,651 'sync':184,415 'system':496 'target':390 'task':736 'termin':441 'test':475,483 'thread':18,139,142,316,387,399,408,428,431,547,556,685,766,769 'threading-mod':141,398,407,430,546,684,768 'throughput':327,543,582 'timeout':613 'tokio':48,302,559 'tool':875 'tool-specif':874 'topic-agent-skills' 'topic-ai-agents' 'topic-beads' 'topic-claude-code' 'topic-codex' 'topic-cursor' 'topic-developer-tools' 'topic-gemini-cli' 'topic-opencode' 'topic-plugin' 'topic-slash-commands' 'topic-spec-driven-development' 'traffic':601 'tune':487 'typic':418 'unbound':605 'under-provis':529 'unless':698 'url':198 'url-path-prefix':197 'usag':80 'use':2,161,397,406,499,511,545,585,689,726,803,847 'uvicorn':25,62,293,297,574,729 'valid':657 'verifi':478,665 'version':223,707 'via':313,822 'vs':292 'wast':533 'without':457,494,542,602 'worker':16,123,128,137,147,155,318,324,385,392,410,426,523,532,538,566,671,764 'workflow':338,877 'workload':404,416,552,693 'wsgi':6,111,118,181,377 'yes':306,311 'zero':74,798 'zero-config':73,797","prices":[{"id":"1c001ca0-472c-42c1-84b2-54e2aaff65cf","listingId":"04a74d31-ac97-4e64-8dae-8c497b42f2c0","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"cofin","category":"flow","install_from":"skills.sh"},"createdAt":"2026-04-23T13:03:59.520Z"}],"sources":[{"listingId":"04a74d31-ac97-4e64-8dae-8c497b42f2c0","source":"github","sourceId":"cofin/flow/granian","sourceUrl":"https://github.com/cofin/flow/tree/main/skills/granian","isPrimary":false,"firstSeenAt":"2026-04-23T13:03:59.520Z","lastSeenAt":"2026-05-18T19:07:37.387Z"}],"details":{"listingId":"04a74d31-ac97-4e64-8dae-8c497b42f2c0","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"cofin","slug":"granian","github":{"repo":"cofin/flow","stars":11,"topics":["agent-skills","ai-agents","beads","claude-code","codex","context-driven-development","cursor","developer-tools","gemini-cli","opencode","plugin","slash-commands","spec-driven-development","subagents","tdd","workflow"],"license":"apache-2.0","html_url":"https://github.com/cofin/flow","pushed_at":"2026-04-27T19:07:26Z","description":"Context-Driven Development toolkit for AI agents — spec-first planning, TDD workflow, and Beads integration.","skill_md_sha":"ca5ebc25e375fd441a9cf423c202ba04242a421d","skill_md_path":"skills/granian/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/cofin/flow/tree/main/skills/granian"},"layout":"multi","source":"github","category":"flow","frontmatter":{"name":"granian","description":"Use when deploying ASGI, WSGI, or RSGI apps with Granian, editing granian CLI commands, worker or thread settings, SSL, HTTP/2, backpressure, or replacing uvicorn for production."},"skills_sh_url":"https://skills.sh/cofin/flow/granian"},"updatedAt":"2026-05-18T19:07:37.387Z"}}