MemoryLayer
  • How it works
  • Arena
  • Benchmarks
  • Registry
  • Pricing
  • Docs
Log inGet started free
  • 01Arena
  • 02Benchmarks
  • 03Registry
  • 04Pricing
  • 05Docs
Log inGet started free

Benchmarks

We ran the tests.
Here's what happened.

Three experiments with real API calls and real dollars, graded by a judge that never saw which side it was scoring — including the places memory loses.

Models
claude-sonnet-5 · Claude Opus 4.8 · Gemini 2.5-flash
Corpus
shadcn-ui/ui · 859 symbols
Runs
3-run averages · caching on both sides

Results3 experiments

  1. 01Cost$0.0398→$0.0162per question — 59% less12,876 → 5,382 input tokens · 3 → 2 turns
  2. 02Recall2/40→39/40facts recalled after the chat closedClaude Opus 4.8 alone → Gemini 2.5-flash with memory
  3. 03Grounding3/6→4/6answers an independent judge acceptedtraining data → your ingested repo

Every run, prompt and answer is on this page — open any section's details.

01Cost

Same answers.
Less than half the bill.

One agent, one repo, 6 questions. The only thing we changed is whether it went looking through the filesystem or asked memory once.

Judged correct: 6/6 with filesystem tools, 6/6with memory — the saving isn't bought with worse answers.

Filesystem toolsrecall(explore)cost per question
  • semanticHow does this codebase express form validation and error messages?

    fs tools
    $0.0983
    recall
    $0.0144

    7.7 tool calls vs 1

  • semanticWhich components in this repo support keyboard shortcuts or display key bindings?

    fs tools
    $0.0606
    recall
    $0.0224

    4 tool calls vs 1.3

  • literalHow is the Dialog component structured and what primitive does it wrap?

    fs tools
    $0.0337
    recall
    $0.0152

    2.3 tool calls vs 1

  • semanticWhat components are available for visualizing tabular data or charts?

    fs tools
    $0.0285
    recall
    $0.0142

    2.7 tool calls vs 1

  • literalWhich file defines the cn class-name utility and what does it combine?

    fs tools
    $0.0112
    recall
    $0.0153

    1 tool call vs 1 · grep was already cheap here

  • literalWhat error message does the useSidebar hook throw when called outside a SidebarProvider, and what is SidebarProvider's default value for its `defaultOpen` prop?

    fs tools
    $0.0064
    recall
    $0.0154

    1 tool call vs 1 · grep was already cheap here

Where it loses

2 of the 6 cost more with memory. Both are trivial one-file lookups, where a single grep was always going to win — literal questions land at 11% saved, semantic ones at 73%. The gap opens exactly where the question gets harder, which is also where you were going to spend the money.

Token counts, turns and pricing
Questionfs in-tokensrecall in-tokensfs turnsrecall turns
What error message does the useSidebar hook throw when called outside a SidebarProvider, and what is SidebarProvider's default value for its `defaultOpen` prop?1,5305,11822
How is the Dialog component structured and what primitive does it wrap?10,9075,07032
Which file defines the cn class-name utility and what does it combine?3,5295,08922
Which components in this repo support keyboard shortcuts or display key bindings?19,8367,4773.32.3
How does this codebase express form validation and error messages?32,2664,8154.72
What components are available for visualizing tabular data or charts?9,1884,72332

Model claude-sonnet-5 · input tokens from Anthropic API usage.input_tokens (exact, real agentic loop) · priced at $3/M · 3-run average · both arms prompt-cached.

02Recall

Close the chat.
It still knows.

Four planning conversations, ten messages each — every message delivered as its own session, the way reopening a chat next week actually works. Then we asked for a summary and graded 40 specific facts.

Project kickoff

Gemini 2.5-flash + memory
10/10
Claude Opus 4.8 alone
0/10

Trip planning

Gemini 2.5-flash + memory
9/10
Claude Opus 4.8 alone
1/10

Kitchen renovation

Gemini 2.5-flash + memory
10/10
Claude Opus 4.8 alone
1/10

Product launch planning

Gemini 2.5-flash + memory
10/10
Claude Opus 4.8 alone
0/10
“I'd be happy to write this kickoff email, but I don't have any record of what we've discussed—this appears to be the start of our conversation, so I don't have the project details to summarize.”
Claude Opus 4.8, asked for the summary in a fresh session — captured verbatim

The control

Run Claude Opus 4.8 against itself — same prompt, same sessions, memory the only variable. It scores 40/40 with memory on and 2/40 with it off. The model was never the problem.

When it doesn't matter

When the entire transcript fits in one window, both sides score near-perfect and memory isn't the variable at all. It becomes the variable the moment the window ends — which, for anything real, is tomorrow.

Read one run end to end — “Project kickoff”
  1. session 01closed

    We're kicking off a new project, codename Atlas.

    Codename Atlas

  2. session 02closed

    It's a mobile app for our client, Northwind Traders.

    Client: Northwind Traders

  3. session 03closed

    The hard deadline is March 14th — that can't move.

    Deadline March 14th

  4. session 04closed

    Tech stack is React Native on the front end with a Go backend.

    Stack: React Native + Go

  5. session 05closed

    Core team is Priya as lead, Marco on backend, and Lena on design.

    Team: Priya, Marco, Lena

  6. session 06closed

    Budget is capped at $80,000, all-in.

    Budget $80,000

  7. session 07closed

    Key product constraint: it has to be offline-first.

    Constraint: offline-first

  8. session 08closed

    We decided to skip Android for v1 — iOS only to start.

    Decision: iOS only for v1

  9. session 09closed

    The main risk is the payment integration with Stripe.

    Risk: Stripe payment integration

  10. session 10closed

    Let's schedule a follow-up review for February 28th.

    Follow-up Feb 28th

session 11nothing carried over

Write the project kickoff email to the team summarizing everything we've discussed.

Gemini + MemoryLayer10/10 facts

Subject: Project Kickoff: Atlas - Northwind Traders Mobile AppHi Team,Excited to officially kick off our new project, Atlas, for Northwind Traders!This project involves developing an offline-first mobile application for iOS (v1). We have a hard deadline of March 14th, which is non-negotiable.Our core team consists of:* Priya (Project Lead)* Marco (Backend Developer)* Lena (Designer)The technical stack will be React Native for the frontend and Go for the backend. The total project budget is capped at $80,000.A critical product constraint is the offline-first functionality. Our primary risk area identified is the Stripe payment integration.Let's plan our first follow-up review for February 28th.Looking forward to a successful project!Best regards,

Claude Opus 4.80/10 facts

I'd be happy to write this kickoff email, but I don't have any record of what we've discussed—this appears to be the start of our conversation, so I don't have the project details to summarize.To write an accurate email, could you share:- Project name and goal — what are we kicking off?- Team members / roles — who should be addressed or mentioned?- Key dates — kickoff meeting, milestones, deadlines?- Scope highlights — main deliverables or workstreams?- Next steps / action items — what do you want people to do after reading?- Any tools or logistics — Slack channel, project board, meeting cadence?Even a few bullet points or a rough brain-dump would work—I can shape it into a polished, concise email from there.If you'd like, I can also send you a fill-in-the-blank template right now that you can complete, and I'll refine it. Just let me know which you'd prefer.

03Grounding

Your repo — not its
memory of someone else's.

We ingested a real checkout of shadcn-ui/ui and asked 6 questions about files that exist in this tree. An independent judge checked every answer against the actual source.

Gemini 2.5-flash + code(ingest)
Claude Opus 4.8, training data only

The narrow one

We're not going to dress this up.shadcn/ui is famous enough that a frontier model already half-knows it, so the margin is one answer. What it can't know is which paths exist in your checkout — and on a private repo it has nothing at all to guess from, which is the case a public benchmark can't stage.

Every answer and the judge's reasoning

In this repository, which file defines the `cn` class-name utility, and what two libraries does it combine?

Gemini 2.5 + recall(explore:true)correct

The `cn` class-name utility is defined in `/private/tmp/shadcn-ui/apps/v4/registry/new-york-v4/lib/utils.ts`. It combines `tailwind-merge` (via `twMerge`) and `clsx`.

The candidate correctly identifies the file path (with appropriate repo prefix), correctly names the two libraries (clsx and tailwind-merge), and accurately describes how they are combined (clsx then twMerge).

Claude Opus 4.8correct

In the shadcn/ui repository (and in projects scaffolded by it), the `cn` utility is defined in:`lib/utils.ts`(In the monorepo itself, the corresponding template/source lives under a path like `apps/www/lib/utils.ts` or `packages/cli`'s registry templates, but the canonical file path referenced throughout the project and generated into user projects is `lib/utils.ts`.)The `cn` function combines these two libraries:1. `clsx` — for conditionally constructing className strings.2. `tailwind-merge` (specifically its `twMerge` function) — to intelligently merge Tailwind CSS classes and resolve conflicting utility classes.The typical implementation is:```tsimport { clsx, type ClassValue } from "clsx"import { twMerge } from "tailwind-merge"export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs))}```

The candidate correctly identifies the file as lib/utils.ts, accurately names both libraries (clsx and tailwind-merge), and provides the exact implementation shown in the ground truth source code.

Which file holds the Dialog component here, and what primitive does it wrap?

Gemini 2.5 + recall(explore:true)correct

The `Dialog` component is located in `/private/tmp/shadcn-ui/apps/v4/registry/new-york-v4/ui/dialog.tsx` and wraps `DialogPrimitive.Root`.

The candidate correctly identifies that the Dialog component is in dialog.tsx and wraps DialogPrimitive.Root, as shown in the ground truth file.

Claude Opus 4.8incorrect

In the shadcn/ui repository, the Dialog component is provided as a template that you add to your own project via the CLI. The component file is located at:`apps/www/registry/default/ui/dialog.tsx`(There is also a "new-york" style variant at `apps/www/registry/new-york/ui/dialog.tsx`.)Primitive it wraps: The Dialog component wraps Radix UI's Dialog primitive, imported from `@radix-ui/react-dialog`:```tsximport * as DialogPrimitive from "@radix-ui/react-dialog"```The file re-exports styled versions built on top of the Radix primitives, such as:- `Dialog` → `DialogPrimitive.Root`- `DialogTrigger` → `DialogPrimitive.Trigger`- `DialogPortal` → `DialogPrimitive.Portal`- `DialogOverlay` → `DialogPrimitive.Overlay`- `DialogContent` → `DialogPrimitive.Content`- `DialogClose` → `DialogPrimitive.Close`- `DialogTitle` → `DialogPrimitive.Title`- `DialogDescription` → `DialogPrimitive.Description`Note: Repository structure has changed over time. In more recent versions of the repo, the registry was reorganized, and the file may live under a path such as `apps/www/registry/new-york/ui/dialog.tsx` or within the updated `apps/v4/registry/...` structure. I'd recommend verifying the exact current path directly in the repository, since I can't guarantee the live directory layout at this moment.

The candidate claims the import is from '@radix-ui/react-dialog', but the ground truth file shows the import is 'Dialog as DialogPrimitive from "radix-ui"' (not '@radix-ui/react-dialog').

Where is the Select component defined in this repo, and what does it use for its trigger icon?

Gemini 2.5 + recall(explore:true)incorrect

The Select component's parts, such as `SelectTrigger`, `SelectContent`, and `SelectItem`, are defined in `/private/tmp/shadcn-ui/apps/v4/registry/new-york-v4/ui/select.tsx`.The `SelectTrigger` component itself, as defined in the provided symbols, does not explicitly render an icon. It is designed to

The candidate claims SelectTrigger does not explicitly render an icon, but the ground truth shows it explicitly renders a ChevronDownIcon as the trigger icon.

Claude Opus 4.8correct

# shadcn/ui Select ComponentIn the shadcn/ui repository, the Select component is defined in the registry, which is the source of truth for the components users copy into their projects.## File Path```apps/www/registry/default/ui/select.tsx```(There's also a "new-york" style variant at `apps/www/registry/new-york/ui/select.tsx`.)## Trigger IconThe `SelectTrigger` component uses an icon from `lucide-react` for its dropdown indicator. Specifically, it uses the `ChevronDown` icon, wrapped inside `SelectPrimitive.Icon`:```tsximport { ChevronDown } from "lucide-react"const SelectTrigger = React.forwardRef<...>(({ className, children, ...props }, ref) => ( <SelectPrimitive.Trigger ...> {children} <SelectPrimitive.Icon asChild> <ChevronDown className="h-4 w-4 opacity-50" /> </SelectPrimitive.Icon> </SelectPrimitive.Trigger>))```The component is built on top of Radix UI's `@radix-ui/react-select` primitive.---⚠️ A note on accuracy: The shadcn/ui repo structure has evolved over time (e.g., paths, and some versions have used icons from `@radix-ui/react-icons` like `CaretSortIcon` instead of lucide's `ChevronDown`). I'd recommend verifying the exact path and icon against the current state of the repository, since I can't guarantee these details are up to date.

The candidate correctly identifies that the Select component uses ChevronDownIcon from lucide-react as the trigger icon, and correctly shows it wrapped in SelectPrimitive.Icon with the asChild prop, matching the ground truth file content.

Where is the Tooltip component defined in this repo, and what Radix package does it depend on?

Gemini 2.5 + recall(explore:true)correct

The `Tooltip` component is defined in `/private/tmp/shadcn-ui/apps/v4/registry/new-york-v4/ui/tooltip.tsx`. It depends on `TooltipPrimitive.Root`, which is part of the Radix UI Tooltip package.

The candidate correctly identifies the file location (with appropriate repo prefix), correctly names the Radix package as 'Radix UI Tooltip', and accurately describes the dependency on TooltipPrimitive.Root from the radix-ui import.

Claude Opus 4.8incorrect

In the shadcn/ui repository, the Tooltip component is defined at:`apps/www/registry/default/ui/tooltip.tsx`It depends on the Radix UI package `@radix-ui/react-tooltip`.A few notes for accuracy:- The shadcn/ui repo uses a registry structure, so the component also exists in the "new-york" style variant at `apps/www/registry/new-york/ui/tooltip.tsx`. The two variants share the same underlying Radix dependency but differ slightly in styling.- The import in the file looks like: ```tsx import * as TooltipPrimitive from "@radix-ui/react-tooltip" ```Since the repository's exact directory layout has changed over time (it has been refactored, and paths like `packages/shadcn` and registry reorganizations have occurred), I'd recommend verifying the current path directly on GitHub if you need the precise location for the latest version, as I can't guarantee the file structure hasn't shifted since my knowledge cutoff.

The candidate claims the import is `import * as TooltipPrimitive from "@radix-ui/react-tooltip"` but the actual import in the file is `import { Tooltip as TooltipPrimitive } from "radix-ui"`

What error message does the useSidebar hook throw when called outside a SidebarProvider, and what is SidebarProvider's default value for its `defaultOpen` prop?

Gemini 2.5 + recall(explore:true)correct

The `useSidebar` hook throws the error message "useSidebar must be used within a SidebarProvider." when called outside a `SidebarProvider`. The `SidebarProvider`'s `defaultOpen` prop has a default value of `true`.File path: `/private/tmp/shadcn-ui/apps/v4/registry/new-york-v4/ui/sidebar.tsx`

Both claims are factually accurate: the useSidebar hook throws 'useSidebar must be used within a SidebarProvider.' (line 44), and the defaultOpen prop defaults to true (line 50).

Claude Opus 4.8correct

# AnswerIn the shadcn/ui repository, the `useSidebar` hook and `SidebarProvider` are defined in the sidebar component file.## File Path```apps/www/registry/new-york/ui/sidebar.tsx```(and correspondingly `apps/www/registry/default/ui/sidebar.tsx`)## Error MessageThe `useSidebar` hook throws the following error when called outside of a `SidebarProvider`:```useSidebar must be used within a SidebarProvider.```This is implemented roughly as:```tsxfunction useSidebar() { const context = React.useContext(SidebarContext) if (!context) { throw new Error("useSidebar must be used within a SidebarProvider.") } return context}```## `defaultOpen` Default ValueThe `SidebarProvider`'s `defaultOpen` prop defaults to `true`:```tsxconst SidebarProvider = React.forwardRef< HTMLDivElement, React.ComponentProps<"div"> & { defaultOpen?: boolean open?: boolean onOpenChange?: (open: boolean) => void }>( ( { defaultOpen = true, // ... }, ref ) => { // ... })```---Note: The exact registry path may vary slightly depending on the repository version, as shadcn/ui has undergone restructuring over time (e.g., paths under `apps/www/registry/`). You may want to verify against the current state of the repository, as more recent versions may organize this under styles like `apps/v4/registry/` or similar.

The candidate correctly identifies the error message as 'useSidebar must be used within a SidebarProvider.' and the defaultOpen default value as true, both of which match the ground truth source code exactly.

Which file defines the Badge component here, and how are its variants declared?

Gemini 2.5 + recall(explore:true)incorrect

The `Badge` component is defined in `/private/tmp/shadcn-ui/apps/v4/registry/new-york-v4/ui/badge.tsx`. Its variants are declared using `cva` within the `badgeVariants` function, which is then applied to the component.

The candidate incorrectly states variants are declared using `cva` within a function called `badgeVariants`, when actually `badgeVariants` IS the result of calling `cva()` directly—it's a constant, not a function.

Claude Opus 4.8incorrect

# Shadcn/ui Badge Component## File PathThe Badge component is defined in:```apps/www/registry/default/ui/badge.tsx```There's also a New York style variant located at:```apps/www/registry/new-york/ui/badge.tsx```> Note: In the shadcn/ui model, components are distributed via a registry (copy-paste into your own project). When installed into a consumer project, the file typically lands at `components/ui/badge.tsx`.## How Variants Are DeclaredThe variants are declared using `cva` (class-variance-authority), which is the standard pattern across shadcn/ui components. The typical structure looks like this:```tsximport * as React from "react"import { cva, type VariantProps } from "class-variance-authority"import { cn } from "@/lib/utils"const badgeVariants = cva( "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", { variants: { variant: { default: "border-transparent bg-primary text-primary-foreground hover:bg-primary/80", secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", destructive: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80", outline: "text-foreground", }, }, defaultVariants: { variant: "default", }, })export interface BadgeProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof badgeVariants> {}function

The candidate's code example shows incorrect variant values (e.g., 'hover:bg-primary/80' and focus styles) that don't match the ground truth file, which has different Tailwind classes and additional variants like 'ghost' and 'link' that the candidate's example omits.

Next

Your model isn't the problem.

Its memory is. One namespace, every agent, every chat, every teammate.

Get started free

install

npm i -g @raajvamsy/memorylayer

then memorylayer setup

Read the docs →