ben-manes/caffeine
A high performance caching library for Java
Healthy across all four use cases
weakest axisPermissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit today
- ✓3 active contributors
- ✓Apache-2.0 licensed
Show all 7 evidence items →Show less
- ✓CI configured
- ✓Tests present
- ⚠Small team — 3 contributors active in recent commits
- ⚠Single-maintainer risk — top contributor 98% of recent commits
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/ben-manes/caffeine)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/ben-manes/caffeine on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: ben-manes/caffeine
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/ben-manes/caffeine shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across all four use cases
- Last commit today
- 3 active contributors
- Apache-2.0 licensed
- CI configured
- Tests present
- ⚠ Small team — 3 contributors active in recent commits
- ⚠ Single-maintainer risk — top contributor 98% of recent commits
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live ben-manes/caffeine
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/ben-manes/caffeine.
What it runs against: a local clone of ben-manes/caffeine — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in ben-manes/caffeine | Confirms the artifact applies here, not a fork |
| 2 | License is still Apache-2.0 | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | Last commit ≤ 30 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of ben-manes/caffeine. If you don't
# have one yet, run these first:
#
# git clone https://github.com/ben-manes/caffeine.git
# cd caffeine
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of ben-manes/caffeine and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "ben-manes/caffeine(\\.git)?\\b" \\
&& ok "origin remote is ben-manes/caffeine" \\
|| miss "origin remote is not ben-manes/caffeine (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
&& ok "license is Apache-2.0" \\
|| miss "license drift — was Apache-2.0 at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 30 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~0d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/ben-manes/caffeine"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Caffeine is a high-performance in-memory caching library for Java that implements near-optimal eviction policies (W-TinyLF) combining frequency and recency. It provides automatic entry loading, time-based expiration, size-based eviction with weak/soft reference support, and asynchronous refresh—drawing from experience with Google's Guava Cache and ConcurrentLinkedHashMap. Core use case: replace Guava's cache with 2-4x better hit rates and lower latency for applications needing sub-millisecond cache operations. Monorepo structure: core cache implementation in caffeine/ directory, separate adapters for JSR-107/JCache in jcache/ and Guava in guava/, simulation tool in simulator/. Build uses Gradle with extensive Error Prone integration. .claude/ directory contains detailed audit rules, design decision docs, and skill assessments for various concurrency and correctness concerns (JMM, linearizability, reentrancy, memory retention, etc).
👥Who it's for
Java backend engineers building high-throughput services (microservices, data pipelines, real-time systems) who need predictable, cache-efficient performance without GC pauses. Also relevant: library maintainers adapting Caffeine to JSR-107 (JCache) or Guava interfaces, and performance researchers studying eviction algorithms.
🌱Maturity & risk
Highly mature and production-ready. 1500+ KB of Java code, comprehensive test suite (Test Count badge displayed), 100% code coverage via Coveralls, active CI/CD on every commit (GitHub Actions), and published to Maven Central. Last activity reflects ongoing maintenance and optimization; this is not a hobby project but a widely-used industry standard (used by Bazel, Elasticsearch, and many others).
Very low risk. Single maintainer (ben-manes) but project is stable with no breaking changes in recent history. Dependencies are minimal (no third-party transitive deps for core cache). Main risk: if security issue emerges in Java memory model or if performance regresses, single maintainer response time could matter. Gradle build system adds some friction for those unfamiliar with it, but setup is automated.
Active areas of work
Project appears actively maintained with focus on correctness auditing (50+ audit skills under .claude/skills/) and performance verification. The .claude/ directory itself suggests ongoing work on formal verification of concurrency properties, memory safety, and eviction correctness—likely preparing for new feature validation or documenting design rationale for contributors.
🚀Get running
git clone https://github.com/ben-manes/caffeine.git
cd caffeine
./gradlew build
No external services required; local builds work standalone via Gradle wrapper.
Daily commands:
Not a server application. Build with ./gradlew build to run tests, or consume as a library: ./gradlew publishToMavenLocal for local Maven repo. To see examples: explore caffeine/src/test/java or read the user guide linked in README.
🗺️Map of the codebase
- caffeine/src/main/java/com/github/benmanes/caffeine/cache/BoundedLocalCache.java: Core cache implementation with eviction logic, synchronization strategy, and entry lifecycle management
- .claude/docs/synchronization.md: Explains the concurrency model, lock hierarchy, and why certain synchronization patterns were chosen
- .claude/docs/design-decisions.md: Documents major architectural trade-offs (W-TinyLF vs other policies, async refresh design, weak references strategy)
- caffeine/src/main/java/com/github/benmanes/caffeine/cache/Caffeine.java: Public builder API; good entry point to understand configuration surface and what features compose
- caffeine/src/test/java/com/github/benmanes/caffeine/cache/EvictionTest.java: Comprehensive eviction correctness tests; essential reading before modifying eviction logic
- .claude/skills/audit-linearizability/SKILL.md: Audit framework for detecting linearizability violations in concurrent operations
- .claude/rules/concurrency.md: Style guide for thread-safe code patterns within this codebase; required reading for any lock-bearing code
🛠️How to make changes
For new eviction policies: modify caffeine/src/main/java/com/github/benmanes/caffeine/cache/ (specifically EvictionPolicy.java and backing data structures). For adapter changes: jcache/src/main/java/ or guava/src/main/java/. For tests: follow pattern in caffeine/src/test/java/com/github/benmanes/caffeine/cache/. Read .claude/docs/design-decisions.md and .claude/rules/concurrency.md before modifying synchronization logic.
🪤Traps & gotchas
- W-TinyLF eviction policy is non-obvious: frequencies are sampled via Bloom filter and periodic resets; naive reads of frequency data will be stale. 2. Double-checked locking patterns used extensively; missing volatile declarations or improper lock ordering causes data races—use
.claude/rules/concurrency.mdas checklist. 3. Generic type erasure: Cache<K,V> becomes Cache at runtime; some adapters work around this with type tokens (seeTypeTokenusage). 4. No public mutable state: Cache is immutable after build; modifying internal collections directly will corrupt state. 5. Gradle version lock: checkgradle/wrapper/gradle-wrapper.propertiesfor exact version; mismatches break reproducibility.
💡Concepts to learn
- W-TinyLF (Weighted Tiny Least Frequently Used) — Core eviction policy used by Caffeine; understanding how it combines frequency and recency (via Bloom filter sampling and aging) is essential to predict cache behavior and tune max sizes
- Double-checked locking — Caffeine uses double-checked locking in hot paths (get/compute operations) to minimize lock contention; requires careful volatile semantics and JMM understanding to avoid data races
- Bloom filter for frequency estimation — Caffeine uses a counting Bloom filter to track access frequencies without per-entry counters; reading code requires understanding false-positive rates and why frequencies are periodically reset
- Weak and Soft References (Java) — Caffeine optionally wraps cache keys/values in weak or soft references; understanding when GC reclaims them (and why ReferenceQueue draining matters) is critical for memory-sensitive applications
- ConcurrentHashMap segment locking — Caffeine's locking strategy for per-entry synchronization; understanding segment-level vs entry-level contention helps optimize for your access patterns
- Linearizability in concurrent data structures — Caffeine cache operations must be linearizable (atomic with respect to client threads);
.claude/skills/audit-linearizability/audits this property—essential before adding features like async refresh - Ring buffer for statistics accumulation — Caffeine tracks cache hits/misses/evictions using lock-free ring buffers instead of atomic counters; reduces contention for stats queries while tolerating eventual consistency
🔗Related repos
google/guava— Predecessor cache implementation; Caffeine was designed to fix Guava Cache limitations (eviction, latency, API brittleness)ben-manes/concurrentlinkedhashmap— Foundational work on high-performance linked hash maps that informed Caffeine's LRU tracking and lock-free statisticsben-manes/gradle-versions-plugin— Same maintainer; dependency management patterns used in Caffeine buildsehcache/ehcache3— Alternative caching library with broader features (persistent store, clustering); Caffeine is lighter-weight but faster for local-only cachesinfinispan/infinispan— Distributed caching library; many Caffeine users wrap it for single-node performance or use Caffeine as a near-cache tier in Infinispan deployments
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Expand audit-temporal-walk skill with automated regression detection across commits
The .claude/skills/audit-temporal-walk/ directory contains Python scripts (walker.py, verify.py) and per-commit.txt data, suggesting an incomplete temporal analysis system. This skill could detect performance regressions, memory leaks, or correctness issues across the commit history. Adding automated detection rules would provide maintainers with early warning of degradations introduced in recent changes—critical for a high-performance caching library where subtle bugs compound.
- [ ] Extend walker.py to collect metrics (operation latency, memory footprint, eviction rates) per commit
- [ ] Add regression detection logic to verify.py that compares current vs baseline metrics
- [ ] Create REGRESSION_RULES.md documenting thresholds for latency, GC pressure, and hit-rate degradation
- [ ] Integrate results into CI pipeline via .github/workflows (reference .claude/rules/gradle-build.md for build integration patterns)
- [ ] Document how new contributors can add custom temporal assertions
Add comprehensive tests for JMM edge cases in audit-jmm skill
The .claude/skills/audit-jmm/SKILL.md exists but the corresponding test cases appear absent from the main test suite. Given that Caffeine is a concurrent data structure library, rigorous Java Memory Model violation detection is critical. A new test module should verify happens-before relationships, visibility guarantees, and race-free access patterns across the caching internals.
- [ ] Create src/test/java/com/github/benmanes/caffeine/cache/jmm/MemoryModelTest.java
- [ ] Add test cases for: volatile field visibility, CAS atomicity, lock-based synchronization (reference .claude/rules/concurrency.md and .claude/docs/synchronization.md)
- [ ] Include tests for interaction between async operations and memory barriers (reference .claude/rules/async-cache.md)
- [ ] Add ThreadSanitizer or similar tool integration to .claude/rules/gradle-build.md for CI
- [ ] Document findings in .claude/docs/research-foundations.md
Create missing feature interaction test suite for cache + async + eviction policy combinations
The .claude/skills/audit-feature-interaction/SKILL.md references feature interactions, but there's no dedicated test module verifying how async operations interact with eviction policies (LRU, LFU, TTL) and listener callbacks. This is a common source of subtle bugs in caching libraries where concurrent feature interactions can violate cache invariants.
- [ ] Create src/test/java/com/github/benmanes/caffeine/cache/FeatureInteractionTest.java
- [ ] Add matrix tests combining: (async|sync) × (LRU|LFU|TTL) × (listeners|no-listeners) × (refresh|no-refresh)
- [ ] Test invariants: cache size bounds, eviction ordering consistency, callback ordering under concurrent operations
- [ ] Reference .claude/rules/testing.md for test structure patterns and .claude/docs/design-decisions.md for expected behavior
- [ ] Use simulator framework (.claude/rules/simulator.md) to validate state machines across feature combinations
🌿Good first issues
- Add missing eviction statistics documentation:
.claude/docs/lacks concrete examples of how W-TinyLF frequency sampling affects hit-rate; write a guide with micro-benchmark numbers for various update frequencies. - Expand test coverage for weak reference edge cases:
caffeine/src/test/java/has eviction tests but minimal coverage for GC-induced reference clearing during concurrent reads; add tests exercisingReferenceQueuedraining under load. - Document synchronization invariants for each cache state transition:
.claude/docs/synchronization.mdis architectural but lacks a state-diagram or invariant checklist; create a formal model of lock release constraints.
⭐Top contributors
Click to expand
Top contributors
- @ben-manes — 98 commits
- @codingkiddo — 1 commits
- @ribafish — 1 commits
📝Recent commits
Click to expand
Recent commits
4863e9a— Preserve refresh and timestamps on async retry-loop no-op returns (ben-manes)c35d49b— Propagate refreshed value from doComputeIfAbsent's existing-entry path (ben-manes)10cdadf— fix audit-temporal-walk findings: ordering, getAll, equals, deserialize (ben-manes)62efeed— add audit-temporal-walk skill for history-mining bug audits (ben-manes)1da5c99— fix stats and Guava-compat issues found by detail.dev triage (ben-manes)b583a4a— audit follow-ups: sketch sentinel guard, async asMap setValue, tests (ben-manes)6053494— Simplify cache name snapshot creation (#1955) (codingkiddo)ac28e6a— Release 3.2.4 (ben-manes)836b65c— use a consistent expiration tolerance calculation (ben-manes)0dc7daf— resurrect in-flight async entries on expiration (ben-manes)
🔒Security observations
The Caffeine caching library demonstrates good security practices with comprehensive testing infrastructure, automated CI/CD pipelines, and defined security policies. No critical vulnerabilities were identified in the visible file structure. The project shows strong security maturity through: (1) Extensive test coverage documentation, (2) Concurrency and synchronization auditing rules, (3) Automated dependency management via Dependabot, (4) Code quality enforcement (DeepSource, CodeCov integration). As a caching library with no direct user input processing, injection risks (SQLi, XSS) are inherently low. Primary recommendations focus on continuous dependency monitoring and ensuring custom actions maintain security standards. The absence of hardcoded secrets or exposed credentials is a positive indicator.
- Low · Potential Dependency Management Risk —
Root directory / Build configuration. No package dependency file (pom.xml, build.gradle, etc.) was provided for analysis. Unable to verify if any direct or transitive dependencies have known security vulnerabilities. Fix: Ensure regular dependency scanning using tools like OWASP Dependency-Check, Snyk, or GitHub Dependabot (already configured in .github/dependabot.yml). Review and update vulnerable dependencies promptly. - Low · GitHub Actions Security Context —
.github/actions/. Custom GitHub Actions are present (.github/actions/) but their implementation details cannot be verified from the provided file structure. Potential for supply chain attacks if not properly reviewed. Fix: Audit all custom GitHub Actions for: (1) Proper secret handling, (2) Input validation, (3) Use of least privilege permissions in action definitions. Pin action versions to specific commits rather than branches. - Low · Security Policy Visibility —
.github/SECURITY.md. SECURITY.md file exists (.github/SECURITY.md), which is a positive sign. However, the content is not visible for review to verify completeness of disclosure policy. Fix: Ensure the security policy includes: (1) Responsible disclosure process, (2) Security contact information, (3) Supported versions, (4) Known security limitations of the caching library.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.