Repository navigation
perf: send query responses up to 3x faster by reusing mapped ASTs and their JSON - #43
Merged
Merged
Conversation
… their JSON - An interned query keeps its server-named AST, so a query built again maps once. - An AST keeps its JSON text; the query endpoint joins each query's text instead of stringifying and scanning the whole response. - js_stringify_bytes finds array-index keys in one scan instead of ten. - The builder looks up a relationship's base query without a closure, and keys a column-to-scalar condition as one flat tuple. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merging this PR will improve performance by 48.68%1 warning
Performance Changes
Tip Curious why performance improved? Comment Comparing |
jnsdls
added a commit
that referenced
this pull request
Oct 28, 2026
…benchmarks (#46) ## Summary The docs had fallen behind #39 (1.11.3), #40 (interning) and #43 (cached mapped ASTs). This brings them level and adds current benchmark ratios. ```diff README.md + "Queries are shared": interned queries, mapped AST and JSON reused; treat as immutable - dangling "wire and SQL tiers run against every adapter" line + **Adapters.** bullet in the compatibility list + build/map in the CPU case list + Py/TS ratio table at ec0768a, 1.11.3, Apple Silicon laptop docs/compat.md + known difference: logging (stdlib `logging`, not upstream's LogSink) re-wrap the interned-queries paragraph docs/plan.md - "small bun runner" -> Node runner in harness/ - "first pin is 1.10.0" -> was 1.10.0; current pin in ZERO_VERSION + status: phases 1-7 done; phase 8 publishes on tag, npm watch not built CONTRIBUTING.md "Bumping Zero" + README version, docstring tag/commit, compat_scope line remap, + `python -m bench.capture`, record new differences bench/__init__.py + build and map groups ``` ## Evidence Nothing on screen changes; docs only. - Every API name the README names is exported from `zero_server`. The version is 1.11.3 everywhere it's pinned (`ZERO_VERSION`, both `package.json` files, the compose image, the docstrings). - The ratio table comes from a full local `uv run python -m bench` (exit 0) at ec0768a. Postgres cases: Python within 10% of npm or faster. Query endpoint with JSON: 1.3–1.7x. `build`/`map`: 6–14x, but microseconds per call. - `ruff check` and `ruff format --check` pass on `bench/`. ## Merge Danger **Door:** two-way **Blast Radius:** docs README is the PyPI long description, so the next release's page shows the new table. The ratios are from one laptop and will drift; the table names the commit and the machine. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- codesmith:footer --> --- <a href="https://app.blacksmith.sh/agent-labs-dev/codesmith/zero-python/pr/46?autoLogin=true&ref=codesmith_pr_footer"><picture><source media="(prefers-color-scheme: dark)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v3.svg"><source media="(prefers-color-scheme: light)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-light-v3.svg"><img alt="View with [code]smith" src="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v3-3x.png" width="162" height="28"></picture></a> <a href="https://backend.blacksmith.sh/track/enable-autofix?expires=1795816999&installation_model_id=434381&pr_number=46&ref=codesmith_pr_footer&repository=agent-labs-dev%2Fzero-python&return_to=https%3A%2F%2Fgithub.com%2Fagent-labs-dev%2Fzero-python%2Fpull%2F46&signature=c4188e5be40817be60bd25370789884b1853df2c8efe7ef6c8707f41d6f4f79f"><picture><source media="(prefers-color-scheme: dark)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-light.svg"><img alt="Autofix with [code]smith" src="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png" width="190" height="28"></picture></a> <sup>Need help on this PR? Tag <code>@codesmith-bot</code> with what you need.</sup> <!-- codesmith:autofix:disabled --> <!-- /codesmith:footer --> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Merged
jnsdls
added a commit
that referenced
this pull request
Oct 28, 2026
Bumps the version to 0.0.4 in `pyproject.toml`, `uv.lock` and `zero_server.__version__`. Nothing else changes. Since 0.0.3, `main` has gained support for `@rocicorp/zero` 1.11.3 (#39), orjson for request parsing and response writing (#37), query reuse that builds queries up to 2.7x faster (#40), reused mapped ASTs and JSON that send query responses up to 3x faster (#43), updated docs (#46) and dependency bumps. After merge, tag `v0.0.4` on main to publish to PyPI. Local run: 786 passed, 100% coverage. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- codesmith:footer --> --- <a href="https://app.blacksmith.sh/agent-labs-dev/codesmith/zero-python/pr/47?autoLogin=true&ref=codesmith_pr_footer"><picture><source media="(prefers-color-scheme: dark)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v3.svg"><source media="(prefers-color-scheme: light)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-light-v3.svg"><img alt="View with [code]smith" src="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v3-3x.png" width="162" height="28"></picture></a> <a href="https://backend.blacksmith.sh/track/enable-autofix?expires=1795817623&installation_model_id=434381&pr_number=47&ref=codesmith_pr_footer&repository=agent-labs-dev%2Fzero-python&return_to=https%3A%2F%2Fgithub.com%2Fagent-labs-dev%2Fzero-python%2Fpull%2F47&signature=bf55280b5bd9ccc8d24e9874ca54b3b0973db3ee2b748438e15b920b024f233f"><picture><source media="(prefers-color-scheme: dark)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-light.svg"><img alt="Autofix with [code]smith" src="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png" width="190" height="28"></picture></a> <sup>Need help on this PR? Tag <code>@codesmith-bot</code> with what you need.</sup> <!-- codesmith:autofix:disabled --> <!-- /codesmith:footer --> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Follow-up to #39/#40. Upstream 1.11.3 normalizes ASTs at every builder step, which made the query path slower. This wins it back on the query endpoint, mostly by not doing the same work twice for a query the builder already interned.
ASTs are already immutable by contract (
ast.py: "no code changes a node once built"), so caching their mapped form and their text is safe.AST._textis acompare=False,init=Falseslot and is reset in_copy.Evidence
Wall clock,
python -m bench, same machine, this branch againstmain(ca665da):query_jsonnow timesquery_response_bytes, which is what the Starlette route sends.test_queries_match_upstream:query_response_bytes(actual) == JSON.stringify(upstream response), byte for byte, over the Hypothesis program corpus (floats, surrogates, errors,userIDset/unset).uv run pytest: 784 passed, 100% coverage.python -m tests.compat: 54 upstream modules, every port module fully exercised. ruff, ty clean.The caches pay off when a query repeats (same name, same args), which interning already makes the common case. A query with args that vary per request still maps and stringifies once per distinct query.
Merge Danger
Door: two-way
Blast Radius: query endpoint
Response bytes are unchanged (proven against upstream). Mapped ASTs are now shared between responses for the same interned query, so code that mutates a returned AST would corrupt later responses. Nothing in the SDK does that.
🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmith-botwith what you need.