Skip to main content
Vaelor

Comparison

Vaelor vs Serena

Serena 1.7.0 · Vaelor v1.72.8 · verified 2026-10-07

Short answer

Serena is an IDE for your agent. Vaelor is a memory of your codebase.

Serena

Symbol-level tools the agent drives: find references, then rename, replace or insert in place. [1]

v1.7.0 · MIT

Vaelor

A graph of the codebase the agent questions: who calls this, what breaks, what the last review said. [9]

v1.72.8 · Apache-2.0

I build Vaelor, so read this with that in mind. The two overlap on who-references-this-symbol; everywhere else they do different jobs.

Which to pick

Pick Serena if…

  • Your agent mostly changes code: rename, move, replace a body. [1]
  • Your language is outside Vaelor’s 16. [1] [9]
  • You work in a JetBrains IDE and want its refactorings or debugger. [1]
  • You want no database and no index to keep.

Pick Vaelor if…

  • You ask “what breaks if I change this” beyond one hop. One call replaced 27 on the function measured below. [9]
  • You want review verdicts to follow a symbol from one pull request to the next. [9]
  • You want a production alert resolved to a file:function. [9]
  • You would rather not install language servers: one binary parses with tree-sitter. [9]

Use both when…

The agent checks the blast radius first, then changes the code: Vaelor impact_analysis before, Serena’s rename, review_pr after. Two MCP entries. I have not run them together in one session.

What each one does

What Serena and Vaelor do, row by row
Capability Serena Vaelor
Find references Yes: Exact, per symbol [1] Yes: Callers and callees [9]
Callers of callers Partly: One call per level Yes: One call, depth 5 [9]
Rename, move, replace Yes: Through the language server [1] Partly: Structural rewrite, no rename [9]
Debugger Partly: JetBrains plugin only [1] No: No
Notes the agent keeps Yes: Markdown memories [2] Partly: Review learnings per symbol; needs PostgreSQL [9]
Alert to code No: No Yes: Alert to file:function [9]
Languages 40+ [1] [3] 16 [9]
Changes your files By design; runs shell commands [7] Only when told to apply; review_pr can comment [9]
Install uv tool install serena-agent [1] [3] Binary or Docker; database optional [9]
License MIT at 1.7.0; next branch GPL [1] [4] [5] [6] Apache-2.0 [10]

Measured: who calls ParseFile?

One question: what calls ParseFile within five hops? Repository: Vaelor at v1.65.16. Serena 1.7.0 answered through gopls, Vaelor 1.72.8 as a bare binary. [11] Compared symbol by symbol.

  • 249 = 249 symbols within five hops, same distances
  • 27 : 1 calls for the production callers
  • 94K : 1.8K characters returned to the agent
  • 6 s : 27 s cold start to the complete answer, best runs
Callers of ParseFile, hop by hop, and what each tool needs to find them
  1. Hop 1: 6 production symbols and 98 tests. Serena needed 1 call to reach it.
  2. Hop 2: 5 production symbols and 18 tests. Serena needed 6 calls to reach it.
  3. Hop 3: 6 production symbols and 15 tests. Serena needed 5 calls to reach it.
  4. Hop 4: 9 production symbols and 32 tests. Serena needed 6 calls to reach it.
  5. Hop 5: 10 production symbols and 50 tests. Serena needed 9 calls to reach it.

Check the tier

Vaelor’s answer has a tier field. enhanced matched the type checker. basic, the first answer on a new checkout, can miss callers (195 of 249 here): repeat the call until it says enhanced. The list shows at most 100 direct callers and names the rest.

Where Serena costs more

Callers of callers take one call per symbol: 27 here, 190 with the tests, each returning code context. That is the price of exact, local operations, and the same references make its rename safe.

All measured numbers

Scroll the table sideways to see every column.

Metric Serena 1.7.0 Vaelor 1.72.8 Note
Direct callers 104 (121 call sites in 33 files) 104 (100 listed) The 100 listed are all in Serena’s 104
Production symbols within 5 hops 36 36 All identical
All symbols within 5 hops 249 249 (245 listed) The 245 listed are identical; the 4 left out are named
Tool calls, production callers 27 1 —
Tool calls, complete walk with tests 190 1 —
Characters returned 93,574 over 27 calls about 1.8 KB inline; the full result, about 70 KB, as a file Serena includes the code around each reference
First call 9 to 33 s (language server start) 6 to 7 s on a checkout seen before; 12 to 18 s on a new one A new checkout first gets tier: basic; the complete answer follows in about 30 to 40 s
Later calls about 2 to 3 s 0.6 s —
Walk time 27 to 78 s for 27 calls; 203 s for 190 6 to 7 s on a seen checkout; about 30 to 40 s on a new one Serena: three runs. Vaelor: five and three runs

Timings come from one laptop (Intel Core i9-9880H, 16 threads, 16 GB), Serena on 2026-10-06 and Vaelor on 2026-10-07, with other programs running (load average 8 to 18). They are an order of magnitude, not a benchmark.

Reproduce the Serena side

Python 3.11+, uv, Go with gopls on PATH. Check out v1.65.16 of the Vaelor repository, then set language_servers: [go] in the project’s .serena/project.yml (Serena creates it on first start). This walks callers one symbol per call, tests included, and writes every symbol it reaches with its distance:

import asyncio, json, sys
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

PROJECT, OUT = sys.argv[1:3]
rows = lambda txt: [(f, s["name_path"]) for f, kinds in json.loads(txt).items() for lst in kinds.values() for s in lst]

async def main():
    params = StdioServerParameters(command="uvx", args=["--from", "serena-agent==1.7.0", "serena", "start-mcp-server", "--project", PROJECT, "--context", "ide-assistant"])
    seen = {("internal/parser/parser.go", "ParseFile"): 0}
    frontier, calls = [("internal/parser/parser.go", "ParseFile")], 0
    async with stdio_client(params) as (r, w), ClientSession(r, w) as s:
        await s.initialize()
        for depth in range(1, 6):
            nxt = []
            for f, n in frontier:
                calls += 1
                res = await s.call_tool("find_referencing_symbols", {"name_path": n, "relative_path": f, "max_answer_chars": 2000000})
                for key in rows("".join(c.text for c in res.content if getattr(c, "text", None))):
                    if key not in seen:
                        seen[key] = depth
                        nxt.append(key)
            frontier = nxt
    json.dump({"calls": calls, "seen": [[f, n, d] for (f, n), d in seen.items()]}, open(OUT, "w"))
    print(calls, "calls,", len(seen) - 1, "symbols")

asyncio.run(main())

Run it with uv run --with mcp python walk.py /path/to/vaelor-v1.65.16 walk.json.

Reproduce the Vaelor side

Build the engine at v1.72.8 (make build; Go 1.26+ and a C compiler), start it with MCP_PORT=18897 OUTPUT_DIR=/tmp/vout ./bin/vaelor, and call impact_analysis over MCP with the path of the v1.65.16 checkout and depth: 5. The inline response is condensed to counts; the full lists are in the file it names under OUTPUT_DIR.

import asyncio, sys
from mcp import ClientSession
try:
    from mcp.client.streamable_http import streamable_http_client as streamablehttp_client
except ImportError:  # the client was renamed between mcp releases
    from mcp.client.streamable_http import streamablehttp_client

async def main():
    async with streamablehttp_client("http://127.0.0.1:18897/mcp") as streams:
        async with ClientSession(streams[0], streams[1]) as s:
            await s.initialize()
            r = await s.call_tool("impact_analysis", {"repo": sys.argv[1], "symbol": "ParseFile", "depth": 5})
            print("".join(c.text for c in r.content if getattr(c, "text", None)))

asyncio.run(main())

The first call builds the index. On a checkout the Go build cache has not seen, it can return "tier":"basic"; repeat the call until the response says "tier":"enhanced". The drivers and raw outputs are in docs/measurements/serena-vs-vaelor-2026-10-06/.

What I could not verify

  • I build Vaelor. The Serena column is what its documentation says, read on 2026-10-06, and 1.7.0 was still its latest release on 2026-10-07. I did not read its source. [1]
  • One repository, one function, one language (Go), on a laptop that was in use. Serena’s JetBrains backend and its development branch (2.0.0.dev0, GPL) were not run. [5] [6]
  • gopls is my reference for static references; neither tool sees reflection or runtime dispatch. [11]
  • Serena’s own evaluation lets the agent grade itself over about twenty tasks. I did not rerun it. [8]

Sources

Every claim about Serena in this page is checked against these. Accessed 2026-10-07.

  1. [1] Serena README at v1.7.0 github.com
  2. [2] Serena docs: memories and onboarding (v1.7.0) github.com
  3. [3] Serena docs: language support (v1.7.0) github.com
  4. [4] Serena LICENSE on main (per-component licensing, last MIT release) github.com
  5. [5] Serena pyproject.toml on main (2.0.0.dev0, GPL-3.0-or-later) github.com
  6. [6] serena-agent 1.7.0 on PyPI (MIT) pypi.org
  7. [7] Serena docs: security considerations (v1.7.0) github.com
  8. [8] Serena docs: evaluation methodology (v1.7.0) github.com
  9. [9] Vaelor README at v1.72.8 github.com
  10. [10] Vaelor LICENSE at v1.72.8 (Apache-2.0) github.com
  11. [11] gopls, the Go language server (v0.23.0 used here) pkg.go.dev