Blog

How Many Tokens Is a Codebase? 60 Repositories Measured

CeamKrier

Measured on September 11, 2026 and kept as measured. FileConcat has changed since; what it reads today is listed in the formats list.

Key findings3 findings
About 240K
Tokens in a typical public repository once it is bundled whole. The middle half of the sample spans a factor of 20, so there is no typical size to plan around.
4 in 10
Repositories that fit a 128K context window. Fewer than half fit 200K, and about 7 in 10 fit a million.
About a fifth
Share of a fresh clone's tokens the default filters remove, mostly test files dropped by their names. A clone has no node_modules to remove.
2026-09-11 / 60 public repositories in 10 languages

Every tool that turns a folder into LLM context says it removes the noise. None says how much noise there was or what is left after. So we bundled 60 public repositories whole, with the same engine the tool ships, and counted.

01 of 12

How many tokens is a codebase, exactly?

About 240,000 for a typical public repository, but the figure is the real answer: the sizes run from tens of thousands of tokens to millions.

60 public repositories, smallest to largest60 rows / log scale
128K window23 of 60200K window26 of 601M window43 of 602M window50 of 60
1k100k10M

Each row is one repository. A window fits every row ending left of its line.

The smallest bundles come from single-purpose libraries with a handful of source files. The largest, certd/certd, is a monorepo with a web front end, a server and one deployment plugin per hosting provider, at over five million tokens.

The lines on the figure are context windows. A window big enough for the typical repository is not big enough for the ones people actually struggle with.

Fitting is not being read

Every repository here that needs a million-token window lands exactly where the published accuracy studies measured the worst retrieval. Getting the bundle to fit is the easy half.

Liu et al. 2023 / Chroma 2025 / see the references

02 of 12

How much do the default filters remove?

About a fifth of a fresh clone's tokens, and most of that is test files dropped by their names.

A clone has no node_modules, no build output and no local env files, because none of that is committed. What a filter can remove from it is only what somebody named: lockfiles, vendored directories and test files. Before our defaults started dropping test files by name, they removed only a few percent. On a working folder with its dependencies installed the same filters remove far more. We did not measure that, and we are not going to guess it.

What stays is mostly your own source, about 70% of the tokens. Documentation, configuration, images in a text format such as SVG, and the tests the naming rule misses share the rest. If your question is about behaviour rather than about the test suite, those remaining tests are yours to remove.

Ask any tool which unit its reduction is counted in, ours included. Hidden files are one in eight of the files our defaults remove, and one in sixty of the tokens.

03 of 12

Count your own folder

The numbers above are a distribution. Yours is one point in it, and the only one that decides anything.

  • Count it before you pick a model. A typical repository fits almost anywhere. One in six is still past the 2M line after the defaults, the largest window on the figure.
  • Decide what belongs in this question. A default can only drop what is named. Whether the documentation or the rest of the tests belong is a choice about what you are asking.
  • Trust the count you are shown. Measuring this found four defects in our own tool, all fixed before these numbers were taken. The one you would notice is the token count, which now lands within a percent of what a paste really costs on four in five of the repositories, against one before.

Drop a folder here and the same engine runs on your machine: nothing is uploaded to us, the whole thing runs in your browser. If the destination is a ChatGPT Project, whose limit is a file count, the bundle takes one of its slots; the per-plan caps are on the ChatGPT Projects page.

Run the funnel on your own folder

Files in, text out, what the defaults keep, and what it costs to send. Nothing is uploaded.

04 of 12

What nobody had measured yet

We checked what is already published before measuring. Two kinds of claim exist and neither answers the question.

The first is tool marketing. Repomix, the most widely used tool in this category, documents its Tree-sitter compression as "~70% token reduction" in its own README. That is a claim about an optional compression mode, measured against the tool's own uncompressed output, not a claim about how much of a repository is worth sending. Gitingest and the rest publish no figure at all.

The second is the long-context literature, which measures what happens to a model as input grows but never says how big a repository is in the first place. Liu et al. found that performance "is often highest when relevant information occurs at the beginning or end of the input context, and significantly degrades when models must access relevant information in the middle of long contexts". Chroma's 2025 evaluation across 18 models found that "across all experiments, model performance consistently degrades with increasing input length". Both are about the cost of a large context. Neither tells you whether your repository produces one.

Nobody has published the funnel: files in, text out, filters applied, tokens produced, over a sample large enough to show a distribution. That is what this is.

05 of 12

The 60 repositories, and how they were picked

The sample was pre-registered. One GitHub search query per cell, written before any result was seen, and the first two results taken in the order they came back. No repository was added, dropped, or swapped after seeing what it measured.

language:<L> size:<band> stars:100..5000 pushed:>2026-03-07
archived:false is:public mirror:false template:false
sort=stars order=desc

Ten languages: TypeScript, JavaScript, Python, Go, Rust, Java, C#, PHP, Ruby, C++. Three size bands from GitHub's own size field, in KB: small 0.1 to 2 MB, medium 2 to 20 MB, large 20 to 200 MB. Two repositories per cell, 60 in total. Every one of them cloned at depth 1 on 2026-09-07, with the commit recorded, and every rerun since has measured those same 60 commits.

The star ceiling is the filter doing the most work. A floor of 100 keeps abandoned experiments out. A ceiling of 5,000 keeps the sample from becoming a list of exceptional mega-projects and curated link collections, which are not what anyone drops into a context window. The full list, the query, the replacement rule for a failed clone, and the biases are in packages/cli/scripts/repo-sample-2026-09-07.txt.

Two repositories in the draw turned out to be documentation collections rather than codebases. They were kept, because removing them after seeing them would turn a query into a choice. They are named in the results, at the top of the documentation share, exactly where they were predicted to land.

06 of 12

How we counted the tokens

Every decision in the measurement comes from the shipped engine. There is no second implementation of the classifier, the filter, or the tokenizer, because a reimplementation measures a tool nobody uses.

dataset60 public GitHub repositories drawn by a pre-registered GitHub search query, 10 languages x 3 size bands x 2 repositories
sample39,107 files walked, 37,293 text eligible, 28,409 kept by the defaults, 55,092,425 tokens assembled
measured2026-09-11, on the 60 commits first cloned on 2026-09-07
build@fileconcat/core 2.0.0, the commit that added 3rdparty and bun.lock to the default ignore list
tokenizero200k_base via @dqbd/tiktoken, the o1-preview-2024-09-12 encoding, run over the assembled XML bundle
scriptpackages/cli/scripts/measure-repo-funnel.ts, with analyze-repo-funnel.ts for the cuts
excludesWorking folders, private repositories, model accuracy, and any language outside the ten sampled. A fresh clone carries no build output, so generated and vendored shares are a floor.
  1. 1

    Clone at depth 1 and record the commit

    A shallow clone, so the measurement describes repository content and not version control history.

  2. 2

    Walk every file, including hidden ones

    .git is excluded because it is the version control database rather than repository content. Counting it would drown every other number.

  3. 3

    Decide what is text the way the product decides

    Content signature routing first, then the encoding classifier. Documents such as PDF and DOCX go through the same parser registry the CLI uses, so a PDF that yields text counts as text.

  4. 4

    Apply the defaults, and record which one fired

    Hidden files, the default ignore list, and any .gitignore in the tree. Each excluded file is attributed to the first rule that removed it.

  5. 5

    Assemble the bundle and tokenize it whole

    The artifact is built with the product's own assembler, in the default XML style, and tokenized in full. This is what a reader pastes into a model, wrapper and file tree included.

The category map (source, tests, documentation, configuration, assets, lockfiles, generated, vendored) is ours and is a judgment call, not a standard. Nothing in a repository declares that a path is a test. The rules are ordered and first match wins, because a vendored test is vendored and a lockfile is a lockfile before it is JSON configuration. Print the full map with pnpm --filter @fileconcat/cli measure-funnel --rules. Assets are images in a text encoding such as SVG: the defaults keep them, and until the map was revised on 2026-09-10 for the tool comparison they were counted as source. Every composition figure below is cut under the current map.

07 of 12

What 60 repositories actually weigh

The spread

The median bundle is 236,218 tokens, the 10th percentile 34,860 and the 90th 3,044,662. Half the repositories in our sample sit between 60,831 and 1,201,507 tokens. That is a factor of 20 inside the middle half alone.

The largest is certd/certd, an SSL certificate renewal tool whose monorepo carries a web front end, a server and one deployment plugin per hosting provider, at 5,535,907 tokens. The smallest bundles come from single-purpose libraries with a handful of source files. In the first two runs the largest was KDE/ghostwriter at 9,373,193, and 8,633,558 of that was a vendored 3rdparty directory our defaults did not know the name of; it is 861,866 tokens now, and the fix is in the list of our own defects below.

20x

Between the 25th and 75th percentile. Not the whole range, the middle half. There is no typical codebase size to plan around, which is why a rule of thumb fails here and a measurement does not.

60,831 to 1,201,507 tokens / 60 public repositories / 2026-09-11

The funnel

All 60 repositories, pooled
files in the clone39,107
minus 1,814, binary, or no readable text (4.6%)
text the engine can read37,293
minus 8,884, hidden, default ignore list, or gitignore (23.8%)
kept by the defaults28,409
unit changes, files to tokens
55,092,425
tokens of context
from 28,409 files
1,939 tokens per file, average
Claude Sonnet 523.6% of the window0.34 USD per send

The model tail describes the median repository rather than the pooled total: 236,218 tokens is 23.6% of Claude Sonnet 5's 1,000,000 token window, and costs about $0.34 to send once at the catalogue's cheapest listed provider on 2026-09-11.

Two things in that funnel are smaller than people expect.

A fresh clone is almost entirely text. 37,293 of 39,107 files, 95.4% pooled and a median of 97.1% per repository. Binary assets are rarer in a repository than in a working folder, and the engine reads more formats than "text file" usually means.

22.7%

All the defaults take off a fresh clone, and more than half of it is the test suite. The rest of what a filter is famous for removing was never committed, so if you were counting on filtering to get a repository under a context window, this is the number that says it will not.

median across 60 fresh clones / 3.5% before tests were dropped by name

The defaults remove a fifth, and unevenly. A median of 73.7% of files survive. The token distribution is heavily skewed: the 25th percentile loses 2.2% and the 90th loses 70.0%. Thirty-nine of 60 repositories lost more than 10%. Two lost nothing at all.

This is a floor, not the reduction you will see

A fresh clone has no node_modules, no dist, no build output and no local env files, because none of that is committed. The generated and vendored shares measured here are the smallest they can be. On a working folder the same filters remove far more. We cannot measure that from clones, and we are not going to estimate it.

The same exclusion, counted two ways

Here is the result that changed how we describe our own product.

The same exclusion, counted two ways
hidden filesfired in 58 of 60
12.4%
share of excluded files
1.6%
share of excluded tokens
default ignore listfired in 52 of 60
87.0%
share of excluded files
97.8%
share of excluded tokens
a .gitignore in treefired in 6 of 60
0.6%
share of excluded files
0.5%
share of excluded tokens

Count files and one exclusion in eight is a dotfile. Count tokens and it is one in sixty.

A tool that says "removed 40% of files" and a tool that says "removed 40% of tokens" have not told you the same thing, and neither has told you which one they meant.

The .gitignore row is the one we did not expect. Honoring .gitignore is a feature we built and describe; on a fresh clone it fires in 6 repositories out of 60, because the things a .gitignore names are the things that were never committed.

What the bundle is made of

Composition by token, all 60 repositories, per-file counts9 categories
48%
kept, 53,603,450 tokens25,273,232 excluded
source38,137,34248%
docs4,626,9616%
assets3,840,5965%
config3,528,2724%
tests3,470,2794%
excluded by default
tests, by name9,525,69712%
vendored9,164,59812%
lockfiles4,892,6736%
build output1,690,2642%

Of the tokens that reach the bundle, 70.7% are source, 8.6% documentation, 7.1% assets in a text encoding, 6.5% configuration and 6.4% tests. The hatched segments never arrive, and the largest of them is the test suite the defaults drop by file name.

Pooled shares hide the variation, and the variation is the useful part:

Category25th percentileMedian75th percentileHighest
source48.7%71.8%88.4%96.6%
tests0.0%0.7%6.6%85.1%
docs2.8%8.2%21.2%99.5%
config0.1%0.9%3.1%97.5%
assets0.0%0.0%1.8%86.7%

The tests row is what survives the naming rule, and its tail is the rule's limit: one repository in ten is still more than a third tests, and jarro2783/cxxopts is 85.1% tests, because its suite lives under names the convention does not cover. If you are pasting a repository to ask about behaviour rather than to review the suite, that remainder is yours to remove, because a test is legitimate source code and only the named part of it can be dropped by a default.

The two documentation repositories the sample drew are the top of the docs column exactly as predicted: gopl-zh/gopl-zh.github.com at 99.5% and SwiftOldDriver/iOS-Weekly at 99.2%.

By language

Six repositories per language is a spread check, not a league table. Read the shape, not the ranking.

LanguageMedian kept, filesMedian bundle tokensMedian source shareMedian tests share
TypeScript70.3%82,76270.5%1.4%
JavaScript80.8%139,08848.7%0.2%
Python71.1%144,92082.7%0.0%
Go64.2%244,36551.5%0.1%
Rust82.2%579,33174.0%0.8%
Java78.4%478,60564.1%4.3%
C#84.0%380,20481.6%0.3%
PHP69.0%106,92275.8%4.5%
Ruby72.3%246,29451.5%12.1%
C++68.3%790,55391.7%0.2%

Go keeps the fewest files, because a _test.go sits beside most source files and the defaults drop it by name. The C++ repositories are nearly ten times the size of the TypeScript ones and almost entirely source. Ruby's median repository still carries the highest test share after the naming rule, which is the rule's limit showing: what it does not name, it does not remove.

Against a context window

The four dashed lines on the figure above are these: 23 of 60 fit 128,000 tokens (38.3%), 26 fit 200,000 (43.3%), 43 fit 1,000,000 (71.7%) and 50 fit 2,000,000 (83.3%).

More than half of these repositories do not fit in a 200,000 token window. A million-token window takes 72% of them, which is the number that makes the long-context literature above relevant rather than academic: the repositories that need the big window are exactly the ones sitting deep inside it, where measured accuracy is worst.

08 of 12

Four things we found wrong in our own tool

The measurement was built to describe repositories. It described our product instead: three times on the day, and once more when the same sample was walked beside three other tools. All four are fixed, and every number on this page comes from the fixed build, rerun on the same 60 commits.

1. The default ignore list was missing go.sum

In the run before the fix, 95 lockfiles reached bundles carrying 886,586 tokens, and every one of them was a go.sum. testcontainers-go alone shipped 789,477 tokens of dependency checksums, roughly three times the median repository's entire bundle, in a file whose contents no model can use.

Fourteen other lockfile names were already on the list. This one was an omission, not a decision. go.sum is now excluded and go.mod is explicitly kept, because the manifest is the part a reader wants. Pipfile.lock and gradle.lockfile went in alongside as siblings of the same oversight, though neither appeared in this sample and we claim nothing about them.

2. The token counter was not counting the artifact

The readout tokenized the file contents joined together. The XML root, the per-file tags, the header and the file tree are all sent to the model and all charged for, and none of them were in the number.

Measured over the sample, the wrapper is a median 2.5% of the bundle, 5.1% at the 75th percentile, and 18.6% on sintaxi/harp, where 147 small files mean the tags outweigh what they wrap. The counter now counts the same string the preview shows and the copy button copies.

3. Above 1 MiB the count was a guess with the wrong ratio

Tokenizing a multi-megabyte bundle in a browser is slow enough to freeze a tab, so above 1 MiB of text the tool stopped tokenizing and forecast the count as characters divided by four. That ratio is English prose. It was applied to Chinese, to minified assets, to anything.

Twenty-seven of the 60 repositories cross that threshold. Scored against the real count of the same bundles, the old figure was a median 11.6% off, 48.2% off at the 90th percentile, and 62.5% low on SCIR-HI/Huatuo-Llama-Med-Chinese, where a character is closer to one token than to four. Five of those 27 repositories were within 5% of the truth.

The fix keeps the reason the threshold exists and drops the assumption: 64 evenly spaced 4 KiB slices are tokenized for real, and the count is scaled by the ratio those slices show. The cost is a flat 256 KiB of tokenizing, whatever the bundle's size. How that budget is spent was tuned against the truth rather than picked, on the four repositories the first configuration did worst on:

SlicesMean absolute errorWorst case
16 x 16 KiB8.14%17.0%
32 x 8 KiB2.82%8.7%
64 x 4 KiB1.30%1.9%
128 x 2 KiB0.79%1.3%

The error is coverage, not sample volume: the same 256 KiB spread over more positions reads a heterogeneous bundle far better. 64 x 4 KiB is the shipped setting rather than the marginally better 128 x 2 KiB, because every slice cuts two tokens in half at its edges, a bias that grows with the slice count, and the gain past that point sits inside the noise of a four-repository comparison.

Across the same 27 estimated repositories, the shipped setting is a median 0.8% off, 2.1% at the 90th percentile, and 3.2% at worst. All 27 are now within 5% of the truth, against 5 of 27 before. Counting the whole sample, including the 33 repositories small enough to be tokenized exactly, 49 of 60 readouts are now within 1% of what a paste actually costs. Before both fixes, one was.

4. Two more names were missing: bun.lock and 3rdparty

On 2026-09-10 the same 60 commits were walked beside Repomix, gitingest and code2prompt for the tool comparison, which reads what each tool carries path by path, and two of our omissions were only visible from the outside. bun.lock reached our bundle in four repositories, 490,966 tokens of resolved dependency graph between them, and on KDE/ghostwriter a directory named 3rdparty put 8,633,558 tokens of vendored code into a bundle of 9,374,075. vendor had been on the list from the start; the other name the same thing travels by was not. Both went in on 2026-09-10, third_party and thirdparty beside them as spellings, and the rerun on 2026-09-11 moved those five repositories and no other: ghostwriter to 861,866 tokens, the four bun.lock repositories by between 20,499 and 400,854 each, and the remaining 55 reproduce to the token.

09 of 12

Limitations

  • A fresh clone is not a working folder. No node_modules, no build output, no local env files. The generated and vendored shares are a floor and the real reduction on a developer's machine is larger. We did not measure it, and we are not going to guess it.
  • The sample spreads over language and size, not popularity. Sorting by stars descending under a 5,000 star ceiling means every repository sits near that ceiling. A well-known project carries more CI configuration, more tests and more lockfiles than a private work repository, so the non-source share here likely overstates what a solo developer's folder looks like.
  • Six repositories per language. Enough to show that ecosystems differ, not enough to rank them.
  • The category map is ours. Nothing in a repository declares a path to be a test or generated. The rules are published and ordered, and a different reasonable map would move the composition figures.
  • The tokenizer is OpenAI's. o200k_base via the o1-preview-2024-09-12 encoding. Claude and Gemini tokenize differently, so every token figure here is an approximation for those targets. That is true of the product's own readout as well.
  • The composition split is per-file, the bundle figure is the whole artifact. They differ by the wrapper and by the joins between files, which is why the composition bar's total is slightly below the bundle total of 55,092,425. Do not mix the two.
  • The measured wrapper is a floor. The shipped tool adds one more header line naming the image and binary files it left out, capped at ten paths. The measurement never fills that list, so a repository carrying binaries pays a slightly larger wrapper than the 2.5% median here.
  • This measures what reaches the model, not what helps it. Whether a filtered bundle produces better answers than a raw one is a separate experiment that needs a model in the loop. It is not this one.

10 of 12

Reproduce it

Everything needed is in the repository. The sample list is tracked next to the script that consumes it, so the selection is auditable rather than described.

git clone https://github.com/CeamKrier/file-concat
cd file-concat && pnpm install
pnpm --filter @fileconcat/cli measure-funnel --repos scripts/repo-sample-2026-09-07.txt
pnpm --filter @fileconcat/cli analyze-funnel

Add --pin <a previous run's JSON> to the first command to measure the commits that run measured instead of each repository's current HEAD, which is how the reruns below were made.

The first command writes a JSON record with a row per repository: the three stages, the token figures, the per-category split with kept and excluded separated, which rule excluded each file, and the skip counts. The second prints every cut quoted on this page but two, and both are marked where they appear: the go.sum figures describe the run before that fix, which the fixed build cannot produce again, and the slice tuning table comes from a separate comparison over four repositories. The commit measured for each repository is recorded in the output, and a rerun pinned to it reproduces the file counts and the token totals. The first run, on 2026-09-07, could not be reproduced that way, because the file tree was rendered in directory-walk order until the day it was published and two clones of one commit could order siblings differently; the tree has been sorted since.

The defaults changed twice after the first run, and the sample was re-run at the same 60 commits each time to say by how much. On 2026-09-09 the default ignore list stopped ignoring directories named __tests__ and started ignoring test files by each ecosystem's own naming convention: api.test.ts and api.spec.js, handler_test.go, test_parser.py, parser_spec.rb, UserServiceTest.java, OrderTests.cs, PaymentTest.php, ParserTests.swift. On 2026-09-10 bun.lock and the 3rdparty family joined the list. The page above is the third run; this is what each change moved:

figure2026-09-07, first published2026-09-09, tests by name2026-09-11, this page
median bundle246,424 tokens236,218 tokens236,218 tokens
tokens across the whole sample73,763,19064,095,711, 13.1% fewer55,092,425, 25.3% fewer
median share of files kept87.5%74.2%73.7%
median share of tokens the defaults remove3.5%21.4%22.7%
hidden files, as a share of what the defaults removed63.1% of files, 5.7% of tokens13.8% and 2.5%12.4% and 1.6%
the ignore list, same two shares33.9% of files, 92.5% of tokens85.6% and 96.7%87.0% and 97.8%
tests, as a share of kept tokens17.5%5.5%6.4%
source, as a share of kept tokens70.6%80.8%70.7%
largest bundle9,373,193, KDE/ghostwriter9,374,075, KDE/ghostwriter5,535,907, certd/certd

The first change moved 42 of the 60 down and 18 up, the latter by 3,158 tokens in total, which is the folder-grouped tests coming back now that __tests__ is not ignored for its name. The drops landed where the language table predicts: the five largest were Ruby and PHP repositories, the two languages with the highest test shares in the first run, led by simplecov-ruby/simplecov at 52.8% and catfan/Medoo at 52.1%. The second change moved five repositories and no other, KDE/ghostwriter by its 3rdparty directory and four by a bun.lock.

The last column also recuts every file under the eight-category map, which is why source falls from 80.8% to 70.7% of kept tokens while nothing was removed from it: 7.1% of kept tokens are text-encoded assets that the seven-category map had counted as source, and ghostwriter's departure changed the pool every other share is taken over.

The limit of the test rule is that it is naming, not detection. A tests/ directory whose files carry no convention survives, Rust's integration tests in tests/*.rs survive, and a suite that does not follow its ecosystem's spelling survives. Tests at 6.4% of kept tokens is what remains after the named part is gone, not proof that 6.4% is all the test code there is.

11 of 12

Frequently asked questions

How many tokens is my codebase?

If it is a typical public repository, somewhere between 34,860 and 3,044,662, with a median of 236,218. That range is the honest answer, which is why the tool counts your actual folder instead of guessing. Language matters more than you would think: the median C++ repository in our sample was 790,553 tokens and the median TypeScript one 82,762.

Does removing node_modules and lockfiles shrink a repository a lot?

On a fresh clone the defaults remove a median 22.7% of tokens, and more than half of that is test files dropped by name; before that rule existed the same defaults removed 3.5%. node_modules is not committed, so it is not there to remove. On a working folder the same filters remove much more, because that is where the installed dependencies and build output live. What does shrink a clone is a lockfile or a vendored directory, which is why one missing entry in our ignore list cost 886,586 tokens across four Go repositories and another cost 8,633,558 on one repository.

Will my repository fit in a 1M token context window?

Seven in ten of our sample did: 43 of 60. But fitting is not the same as being used well. Both studies in the references below found accuracy falling as input grows, so a repository that just barely fits a window is sitting in the worst part of it.

Should I strip tests before pasting a codebase into an LLM?

It depends on the question you are asking, and it is the biggest lever available. Tests were 17.5% of all kept tokens in the first run over this sample and more than 41.5% in the top quarter of repositories. Since 2026-09-09 our default ignore list removes test files by each ecosystem's naming convention, which takes that share to 6.4% on the same 60 repositories: 11.9% of every token in the sample is a test file dropped that way. That is naming rather than detection: a tests/ directory whose files carry no convention still comes through, as do Rust's tests/*.rs, so strip the rest yourself when the question is about behaviour rather than about the suite.

Why does the token count differ between tools?

Because tools count different things. Some count file contents only and leave out the wrapper they add, which we measured on ourselves at a median 2.5%. Some estimate from character counts rather than tokenizing, which we also did above 1 MiB and which ran a median 11.6% off. And any tool using an OpenAI tokenizer is approximating when you paste into Claude or Gemini.

12 of 12

References

Liu et al., "Lost in the Middle: How Language Models Use Long Contexts"
TACL vol. 12, 2024
Multi-document QA and key-value retrieval, relevant information moved through the context

Where an answer sits inside a long input, across model sizes

Performance "is often highest when relevant information occurs at the beginning or end of the input context, and significantly degrades" in the middle, "even for explicitly long-context models"

Chroma Research, "Context Rot: How Increasing Input Tokens Impacts LLM Performance"
Industry report, 2025
18 models, 8 input lengths x 11 needle positions

Retrieval and replication tasks as input length grows

"Across all experiments, model performance consistently degrades with increasing input length"

Repomix (yamadashy/repomix)
Project README
Not a study

Its own Tree-sitter compression mode against its own uncompressed output

"~70% token reduction", a claim about optional compression rather than about repository composition

Tip

The measurement script and the repository list are both in the public repository. If you disagree with the category map, change it and rerun: the numbers on this page are an output, not an assertion.