{"id":19892136,"url":"https://github.com/maxpert/phanpy","last_synced_at":"2025-10-09T05:35:34.285Z","repository":{"id":66864054,"uuid":"404758413","full_name":"maxpert/phanpy","owner":"maxpert","description":"Phanpy is dead simple JSON streaming HTTP interface over Postgres to execute your queries.","archived":false,"fork":false,"pushed_at":"2023-09-29T13:18:20.000Z","size":99,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-09-18T23:08:56.138Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/maxpert.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-09-09T14:41:13.000Z","updated_at":"2024-05-09T23:32:09.000Z","dependencies_parsed_at":null,"dependency_job_id":"e73a3add-1c52-4bc1-b376-3a502ad23b16","html_url":"https://github.com/maxpert/phanpy","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/maxpert/phanpy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxpert%2Fphanpy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxpert%2Fphanpy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxpert%2Fphanpy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxpert%2Fphanpy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/maxpert","download_url":"https://codeload.github.com/maxpert/phanpy/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxpert%2Fphanpy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279000741,"owners_count":26082932,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-09T02:00:07.460Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-12T18:21:41.573Z","updated_at":"2025-10-09T05:35:34.268Z","avatar_url":"https://github.com/maxpert.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Phanpy\n\nPhanpy is dead simple JSON streaming HTTP interface over Postgres to execute your queries.\n\n\u003e Disclaimer: This is an experimental software. Use in production at your own risk.\n\n## Motivation\n\nUnlike [PostgREST](https://postgrest.org/en/v8.0/index.html) Phanpy only embraces the philosophy of \nproviding an HTTP interface to Postgres and embraces SQL queries and parameters as first class citizens. \n\n## Zero Abstraction\nPhanpy takes SQL for what it is; a well understood, well document, and well practiced language \nwith precise controls that no other DSL has matched so far. That's why projects like Spark, Cassandra etc. adopted\nvarious dialects of SQL. All queries are prepared and executed as is!\n\n## Tutorial\n\nPhanpy requires only two environment variables:\n - `ENV` enviroment of running `prod` means production where it uses production loggers, everything else is development\n - `DB_URL` a full URL according to [pgx](https://github.com/jackc/pgx) \n    specifications e.g. `postgresql://\u003cuser\u003e:\u003cpassword\u003e@localhost:5432/\u003cdatabase\u003e?statement_cache_capacity=128\u0026statement_cache_mode=prepare\u0026pool_max_conns=16`\n\nAfter launching `phanpy` you can use cURL to run your queries:\n\n```bash\ncurl -v --data '{\"query\": \"SELECT * FROM generate_series(1, 1000000)\", \"params\": [], \"timeout\": 30}' http://localhost:8080/\n```\n\n## Performance\n\nHere is the example query payload used to generate upto 400 rows at random, with random ordering and some text payload.\n\n```json\n{\n  \"query\": \"SELECT md5(random()::text) AS some_data, * FROM generate_series(1, (random() * $1)::int) ORDER BY RANDOM()\",\n  \"params\": [400],\n  \"timeout\": 30\n}\n```\n\nBenchmarking with [vegeta](https://github.com/tsenart/vegeta) here are rough benchmarks with everything running on \n(2015 Macbook pro, 2.2 GHz 8 core with 16 GB RAM) same machine (all vegeta, postgres, phanpy):\n\n```bash\n➜  phanpy git:(master) cat vegeta.txt | vegeta attack -rate=1000 -duration=30s | vegeta report\nRequests      [total, rate, throughput]         30000, 1000.03, 999.78\nDuration      [total, attack, wait]             30.007s, 29.999s, 7.478ms\nLatencies     [min, mean, 50, 90, 95, 99, max]  400.425µs, 9.288ms, 6.457ms, 17.67ms, 28.689ms, 59.23ms, 166.477ms\nBytes In      [total, mean]                     422840350, 14094.68\nBytes Out     [total, mean]                     4710000, 157.00\nSuccess       [ratio]                           100.00%\nStatus Codes  [code:count]                      200:30000\nError Set:\n```\n\nDuring all of this maximum memory was reported under 50MB RSS; avg runtime stats looked something like this:\n\n```json\n{\n  \"acquire_count\": 101490,\n  \"acquire_duration\": 508260937427,\n  \"acquired_conns\": 16,\n  \"empty_acquire_count\": 12972,\n  \"idle_conns\": 0,\n  \"max_conns\": 16,\n  \"stats\": {\n    \"time\": 1631159177493892000,\n    \"go_version\": \"go1.17\",\n    \"go_os\": \"darwin\",\n    \"go_arch\": \"amd64\",\n    \"cpu_num\": 8,\n    \"goroutine_num\": 213,\n    \"gomaxprocs\": 8,\n    \"cgo_call_num\": 133,\n    \"memory_alloc\": 13717472,\n    \"memory_total_alloc\": 21575081440,\n    \"memory_sys\": 44714768,\n    \"memory_lookups\": 0,\n    \"memory_mallocs\": 374057114,\n    \"memory_frees\": 373986984,\n    \"memory_stack\": 2424832,\n    \"heap_alloc\": 13717472,\n    \"heap_sys\": 35323904,\n    \"heap_idle\": 16744448,\n    \"heap_inuse\": 18579456,\n    \"heap_released\": 6774784,\n    \"heap_objects\": 70130,\n    \"gc_next\": 21642400,\n    \"gc_last\": 1631159177475508000,\n    \"gc_num\": 2348,\n    \"gc_per_second\": 20.843679212802737,\n    \"gc_pause_per_second\": 42.506663,\n    \"gc_pause\": [\n      0.19,\n      0.232078,\n      0.310384,\n      0.175009,\n      0.151908,\n      0.178259,\n      0.181853,\n      \"more ...\"\n    ]\n  },\n  \"total_conns\": 16\n}\n```\n\n## Named queries\n\nOften in production it will require you to have clear visibility on various queries you are running. Unlike everything\nunder single path (e.g. `/graphql`) this will not only let you integrate existing tools to measure latency, it will\nalso let you do predefine well written queries and optimize them with tooling.\n\nRight now named queries can be defined in `queries.yml` file under current working directory (or file path in \n`NAMED_QUERIES` environment variable). Here is an example:\n\n```yaml\n- name: get_series\n  query: SELECT md5(random()::text) AS hash, * FROM generate_series(1, $1) ORDER BY RANDOM()\n  timeout: 10\n```\n\nNow you can run this named query using:\n\n```bash\ncurl -v --data '[40000]' http://localhost:8080/query/get_series\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaxpert%2Fphanpy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmaxpert%2Fphanpy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaxpert%2Fphanpy/lists"}