# Keploy vs Deja — evidence-based comparison (research dossier)

Generated 2026-07-06 by a 5-agent research workflow from primary sources (docs, source code,
issue tracker). Every claim carries a source. Companion to `docs/design/effect-algebra.md`.

## Keploy model (evidence-grounded summary)

Keploy is an out-of-process, wire-layer record-replay system: eBPF hooks (cgroup connect4/6, syscall tracepoints/kprobes) transparently redirect an application's TCP/UDP traffic into a userspace proxy, where protocol parsers (HTTP, MySQL, and generic in current OSS v3; postgres/mongo/redis/grpc/kafka in v2.x or enterprise) decode byte streams into human-editable YAML test cases and mocks — no SDK or code change, but root + Linux kernel >= 5.10 required, and TLS is handled by CA-cert MITM. A test case is one ingress HTTP request/response pair plus the egress exchanges captured in its record-time timestamp window; at replay the real app process runs live, recorded requests are re-sent, and ALL outbound calls are answered from mocks (no real dependencies, no seeding, no state — the old fallback-to-real flag is deprecated). In-process nondeterminism (time, UUIDs, RNG, crypto nonces) is not captured at all; it is absorbed post-hoc by tolerance machinery: a timestamp-shape heuristic (IsTime) at save time, hardcoded flaky-header lists (SigV4, Stripe signatures), manual globalNoise config, opt-in drift-learning schema noise, Levenshtein/Jaccard fuzzy mock matching with no minimum threshold for HTTP, and SCRAM proof re-derivation; the only true determinizer is enterprise-tier time freezing applied at replay. The pass/fail verdict compares only the inbound HTTP response (status, headers-modulo-noise, JSON body-modulo-noise); a diverged consumed-mock set on a passing test is explicitly ignored by default, and on a failing test demotes it to OBSOLETE with re-record guidance — so a dropped or extra DB write is structurally invisible unless it changes the response. Mock-to-test correlation is by record-time time windows plus replay-time consumption order, which the issue tracker shows breaking under concurrency: silent mock loss under parallel record load (~9.8% measured), cross-test mock bleed from reconnects/background workers, and crashes on parallel replay. Matching across code versions is payload/hash-keyed (e.g. Postgres SQL hash), so any changed/renamed/added dependency call is a hard miss whose official remedy is `keploy rerecord`. It is mature as a product (Apache-2.0, ~18k stars, near-daily releases, broad language coverage) but has thin independent practitioner evidence and no documented story of catching a real regression.

## Dimension table

| Dimension | Keploy | Deja |
|---|---|---|
| **Capture layer** | Out-of-process wire layer: eBPF cgroup/syscall hooks redirect TCP/UDP into a userspace proxy; protocol parsers decode bytes to YAML; TLS via CA-cert MITM (opportunistic_tls.go). Sees only what crosses a socket. | In-process semantic layer: attribute macros at definition sites emit typed SemanticEvents with args, result envelope, callsite identity, read/write state keys, and declared metadata (operation kind, return semantics, replay strategy). |
| **Dependency coverage** | Broad by protocol, brittle at edges: v2.x shipped http/grpc/mongo/mysql/postgres/redis/scram parsers; current OSS v3 registers only http/mysql/generic in-tree (rest enterprise or in flux); unknown protocols fall back to base64 byte blobs with fuzzy matching; WebSocket/SSE/server-initiated calls/MySQL cursors unsupported (docs + issues #3811, #1572, #4261). | Narrow by design but semantic: db (diesel seam), redis, http egress/ingress, plus id/uuid/time/crypto-nonce entropy — each an instrumented boundary with declared semantics, Hyperswitch/Rust only. |
| **In-process nondeterminism (time/uuid/rng/crypto)** | Not captured at record time. Handled by tolerance: IsTime timestamp-shape heuristic at save, hardcoded flakyHeaders (SigV4/Stripe/trace IDs), globalNoise config, SCRAM proof re-derivation with a known password, Levenshtein fuzzy matching. Only determinizer is enterprise time-freezing at REPLAY (faketime/LD_PRELOAD); UUIDs/RNG have no freeze. | Captured in-process at record time (entropy sources instrumented), replayed byte-exact — determinization, not tolerance. |
| **State model during replay** | Pure full-mock: no real database, no seeding concept, writes land nowhere; replay is 'always deterministic' (fallBackOnMiss deprecated/ignored); users needing real state are told to reset DBs manually (common-errors docs). | Per-correlation seeded-execute: per-correlation pg schema + redis namespace seeded from the tape's read-set (typed row images); boundaries declared Execute run REAL code against seeded state with shadow observation, or Substitute with fail-stop on miss (never stale). |
| **Transitive side-effect detection** | Structurally invisible: verdict is response-diff only; consumed-mock-set mismatch on a passing test is explicitly ignored ('mock mapping mismatch ignored because testcase passed', replay.go:1985-2011); a missing/extra DB write passes silently unless it changes the HTTP response. Opt-in SchemaNoiseStrict is the only partial exception. | A design goal: Execute against seeded state means a changed upstream write causes a caught downstream divergence; A/B matrix proof includes a seeded dropped-write and extra-call bug, both caught. |
| **Matching robustness across code versions** | Payload/hash-exact per protocol (e.g. 'no recorded invocation shares this SQL hash'); changed/renamed/added calls are hard misses; default demotes diverged tests to OBSOLETE 'so the user can re-record'; keploy rerecord is the official remedy. Fuzzy fallback errs both directions (wrong mock served #2706; false PASS on never-recorded request #2510). | Rank-ladder identity (explicit id > logical span path > syntactic hash > lexical path > source location > sequence) explicitly designed to survive code movement across versions; args-hash canonicalized. Cross-version A/B is the product, not a failure mode. |
| **Noise/nondeterminism policy** | Heuristic and threshold-free: timestamp-shape auto-noise, hardcoded flaky-header list, manual globalNoise regexes, drift-learned schema noise, best-candidate Levenshtein with no minimum similarity, --must-pass deletes flaky tests. Long open-issue tail of noise config not applied / silently dropped (#3492, #3872). | Evidence-gated tolerance: concurrent same-row writes judged by final state, idempotent deletes by outcome class, error messages by stable kind; planned declared effect canonicalization + task-lineage buckets; control-flow races -> inconclusive+rerun, not delete. |
| **Test independence / parallelism / isolation** | Sequential per-test-set with app restart (KeepAppAlive opt-in); parallel replay crashes ('concurrent map writes', #3412); concurrent CLI runs corrupt artifacts (#3836); cross-test mock bleed was the norm until StrictMockWindow; no any-order execution model. | Each correlation = an independent isolated test case (own pg schema + redis namespace), replayable in any order and in parallel by construction. |
| **Concurrency & async background work** | Documented weak point both sides: record drops mocks under parallel load (100-slot channel, ~9.8% measured silent loss, #4175); --enable-sampling deliberately skips excess concurrent requests (#4211); replay-time attribution by consumption order misassigns mocks on reconnects/health checks/pools (#4083, #3580). | Correlation captured at boundary-build and stamped on events; scoring plans task-lineage buckets and treats control-flow races as inconclusive+rerun rather than misattributing. |
| **Production recording story (overhead/PII)** | Positioned for prod traffic but: no PII redaction/masking in OSS (only record filters + comparison-time noise, which does not remove data from tapes); no statistical sampling; 'negligible overhead' is vendor-claimed with no independent benchmark; requires root + kernel >= 5.10. | Durable pipeline (Kafka -> Vector -> S3 zstd) built for production tape; but per the instrumentation audit the tape currently leaks secrets too — neither side has redaction solved; deja has no published overhead numbers either. |
| **Integration burden & language coverage** | Near-zero per-app (wrap launch command, no SDK, any language/framework), high per-environment (root, Linux >= 5.10, CA cert install, macOS via Docker/Lima, Windows via WinDivert/WSL, one parser per wire protocol). | High per-app and single-target: Rust + Hyperswitch, attribute macros at ~37 declaration points, deep integration over generality; zero extra kernel/privilege requirements. |
| **Verdict semantics (what a failure MEANS)** | A failure means the inbound HTTP response diffed after noise subtraction — could be a real regression, a noise-config gap, a wrong fuzzy mock, or drift; a mock-set divergence means OBSOLETE (re-record), not fail. A pass means the response matched — says nothing about writes. | Per-call ledger + scorecard: a divergence is attributed to a specific boundary call with matched identity; Substitute miss = fail-stop NovelCall (never stale); Execute divergence = observed state-level difference including transitive effects. Failures are localized claims about behavior, not response-shape accidents. |

## Keploy shortcomings vs deja

- No transitive side-effect detection: verdict is inbound-response-diff only; a consumed-mock-set mismatch on a passing test is explicitly ignored (replay.go:1985-2011 'mock mapping mismatch ignored because testcase passed'), so a dropped or extra DB write passes silently — exactly the class deja's Execute-against-seeded-state + shadow observation catches (and proved on the A/B matrix with a seeded dropped-write bug).
- No state during replay at all: no seeding, no per-case database, writes land nowhere (fallBackOnMiss deprecated; docs tell users to reset DBs manually). Deja materializes per-correlation pg schemas + redis namespaces from the tape's read-set with typed row images.
- In-process nondeterminism is tolerated, not determinized: time/UUID/RNG/crypto are absorbed by IsTime heuristics, hardcoded flaky-header lists, fuzzy matching, and SCRAM re-derivation with a known password; only enterprise time-freezing exists, at replay, and nothing freezes UUIDs/RNG. Deja captures entropy in-process and replays byte-exact.
- Cross-version brittleness is baked into the matching model: payload/hash-exact keys ('no recorded invocation shares this SQL hash'), hard miss on any changed/renamed/added call, default demotion to OBSOLETE with `keploy rerecord` as the remedy — versus deja's rank-ladder identity built to survive code movement, which is the entire cross-version A/B use case.
- Fuzzy matching errs in both directions: threshold-free best-candidate Levenshtein can serve the wrong mock (#2706) and produce false PASSES on requests that were never recorded (#2510) — deja's fail-stop-on-miss Substitute can never serve stale or wrong data silently.
- Correlation by time window + consumption order, not identity: mocks are attributed to tests by record-time timestamp windows and replay-time consumption order, so reconnects, health checks, background workers, and pools cause cross-test bleed and misattribution (#4083, #3580); StrictMockWindow is a recent patch, not a model. Deja stamps correlation at boundary-build time.
- Concurrency degrades capture silently: 100-slot mock channel drops ~9.8% of mocks under 4-producer load with drop logs only at n==1 and every 1024th (#4175), and --enable-sampling deliberately bypasses recording of excess concurrent requests (#4211).
- No parallel or any-order replay: sequential test-sets with app restart; parallel replay crashes on concurrent map writes (#3412); concurrent CLI runs corrupt artifacts (#3836). Deja's per-correlation isolation makes any-order/parallel replay a design invariant.
- Noise policy is heuristic, unauditable, and buggy in practice: open issues on globalNoise not applied (#3492) and noise assertions silently dropped by a YAML type-assertion bug (#3872); --must-pass literally deletes flaky tests. Deja's tolerance is evidence-gated per divergence class (final-state judgment, outcome class, stable error kind) with inconclusive+rerun for races.
- Verdicts are coarse: a failure is a response-shape diff that could be regression, noise gap, or wrong mock; there is no per-call ledger, no boundary-level attribution, no scorecard. Marketing claims ('AI-powered noise detection', gRPC/WebSocket capture) also overstate the OSS mechanism per its own docs and source.

## Where Keploy is ahead (honest reverse view)

- Language- and framework-agnostic zero-code capture: Keploy works on any runtime by wrapping the launch command (eBPF + proxy, no SDK); deja is Rust/Hyperswitch-only with ~37 macro declaration points and requires owning the codebase.
- Protocol breadth via wire parsers: real decoders for MySQL/Postgres/Mongo/Redis/gRPC/Kafka handshakes and query phases (v2.x tree), including session/connection/per-test mock lifetimes for stateful protocol features like prepared statements — deja covers only the boundaries it has instrumented.
- Product maturity and operational tooling: Apache-2.0, ~18k stars, 615 releases with near-daily cadence, CI integrations, `keploy report`, structured mock-mismatch diagnostics (which match phase ruled candidates out, closest mock, next steps), rerecord/dedup/--remove-unused-mocks workflows. Deja is a pre-v1 internal system (~M2.4 on the roadmap, M1 runner not started).
- Test-suite curation at scale: coverage-based dynamic dedup (per-testcase line-coverage maps -> duplicates.yaml -> --rm) and enterprise record-time schema-signature static dedup — deja has no dedup or suite-minimization story.
- Human-editable artifacts: YAML test cases and mocks users can inspect and tweak by hand; deja tapes (Kafka->S3 zstd SemanticEvents) have no comparable edit/curate surface.
- Ingress-side test generation as a product: recorded ingress requests become named, selectable, re-runnable test cases with reports; deja's runner/harness UX is still being built.
- Cross-platform capture: Linux eBPF, Windows via WinDivert driver, macOS via Docker/Lima — deja has no story outside its own deployment.
- TLS traffic capture without app changes (CA MITM + keylog) — irrelevant to deja's in-process model but a genuine capability deja cannot offer to uninstrumented services.
- Honest mirror on secrets: neither tool redacts PII, but Keploy's record filters (path/method/header include-exclude) at least gate what enters the tape; deja's audit found its tape leaks secrets with no filter mechanism yet.

## Steal-worthy ideas

- Record-time double-run noise detection: Keploy's docs describe re-running a request against the just-captured mocks during recording and marking response fields that differ as noise. Deja could run an immediate shadow-replay at record time to auto-discover benign nondeterminism per endpoint and propose evidence-gated canonicalizations, instead of discovering them as first-replay divergences.
- Structured mock-miss/mismatch diagnostics: Keploy's buildHTTPMismatchReport records which match phase ruled candidates out, candidate count, closest mock, a diff, and next-step guidance. Deja's NovelCall/fail-stop and rank-ladder misses should emit the same shape — which ladder rung failed, nearest-identity candidate, args diff — to make divergence triage fast.
- Mock/segment lifetime classification: the session vs connection vs per-test lifetime model (auth handshakes and SET/SHOW as session, prepared statements as connection-scoped) is a clean taxonomy for events that are real but not per-request; deja will need an equivalent bucket for connection-setup and pool-warmup events that shouldn't count against any correlation.
- Coverage-based dedup: per-testcase line-coverage maps to drop correlations that add no coverage would let deja curate production tapes into a minimal high-value regression suite rather than replaying everything.
- Auto-dynamic URL segment detection (zero-config wildcarding of numeric/uuid/hex path segments on both sides, all other segments byte-equal) is a sane default for deja's http-ingress matching keys.
- Record-time schema-signature static dedup: drop already-seen (method, normalized path, header keys, body schema hash) traffic during capture to bound production tape volume — deja currently has no sampling/dedup story for prod recording.
- Record filters as a PII stopgap: path/method/header include-exclude gates on what enters the tape are cheap and deja's audit says its tape leaks secrets; a boundary-level capture filter (plus field-level redaction, which neither tool has) should ride along with the instrumentation-audit fix list.
- The IsTime timestamp-shape heuristic as a triage aid only: flagging timestamp-shaped diffs in the scorecard as 'likely benign, needs canonicalization declaration' — as a labeled suggestion feeding deja's declared-canonicalization pipeline, never as an auto-suppression.

## Verdict

Keploy wins on reach and productization — any language, zero code change, broad wire-protocol parsers, mature CLI/CI/reporting/dedup tooling — and it validates deja's core market thesis: record-once/replay-as-mock regression testing from real traffic is demanded, funded, and 18k-stars popular. But on correctness it is precisely the total-substitution design deja's partial-derivative analysis predicts will mask transitive effects, and its own source confirms it: response-diff-only verdicts, mock-set mismatches ignored on pass, OBSOLETE-and-rerecord on cross-version drift, threshold-free fuzzy matching that can false-pass, and an issue tracker that is a catalog of the time-window correlation-bleed and parallelism failures deja's per-correlation isolation eliminates by construction. Keploy does not threaten deja on deja's chosen ground — semantic, state-seeded, transitive-effect-catching, cross-version A/B for one deeply-owned Rust codebase — because its architecture cannot reach in-process nondeterminism or seeded-execute without abandoning its zero-instrumentation premise. The honest caveats are that Keploy's breadth, maturity, and suite-curation tooling are years ahead, deja shares the unredacted-tape problem, and Keploy's thin organic adoption despite polish is a market warning: ease of integration alone hasn't produced documented regression catches, which strengthens the case that deja's correctness depth is the differentiator worth proving with the A/B matrix.

---

# Appendix: raw research findings

## Keploy (keploy.io / github.com/keploy/keploy) — capture architecture research

Keploy captures at the NETWORK/WIRE layer, fully out-of-process: on Linux it loads eBPF programs (cgroup connect4/connect6 hooks, syscall tracepoints/kprobes) that transparently redirect the application's TCP/UDP connections into a userspace proxy running inside the Keploy agent; the proxy relays real bytes to the actual upstream while protocol parsers (HTTP, MySQL, Postgres, Mongo, Redis, gRPC, Kafka, generic-fallback) decode the byte streams into structured YAML mocks. TLS is handled by opportunistic MITM with a Keploy CA cert (plus a keylog path), not by uprobing crypto libraries. A test case = one ingress request/response pair (test-N.yaml) plus the dependency interactions captured during it (mocks.yaml, with session/connection/per-test mock lifetimes). Critically for comparison with in-process approaches like deja: Keploy does NOT intercept in-process nondeterminism at record time — time, UUIDs, RNG, and crypto signatures are handled post-hoc by tolerance mechanisms (auto-learned "noise" fields, a hardcoded flaky-header list covering SigV4/Stripe/trace IDs, Levenshtein fuzzy matching, SCRAM auth-proof re-derivation with a known password) rather than by determinization; the only determinizer is enterprise-tier "time freezing" (Go faketime build tag or LD_PRELOAD shim for Node/Java/Python) applied at REPLAY, not record. Integration burden is low per-language (no SDK, wrap the launch command in `keploy record -c "..."`) but high per-environment: root privileges, Linux kernel >= 5.10 (macOS via Docker/Lima; Windows via WinDivert driver or WSL), and one-mock-per-wire-protocol coverage — anything unparsed falls back to a byte-level "generic" recorder that is brittle to any byte-level change. The OSS v3 restructure (module go.keploy.io/server/v3) currently registers only http/mysql/generic parsers in-tree while docs still describe the full protocol set from v2.x, so parser availability per protocol should be verified against the release actually used.

- **Capture mechanism is eBPF + transparent userspace proxy, requiring no SDK or code changes — the flagship positioning of v2/v3.**
  - evidence: README: "Keploy uses eBPF under the hood to capture traffic, so you don't need to add any SDKs or modify code" and "it works with any language, framework, or runtime—no SDK required."
  - source: https://github.com/keploy/keploy
- **Capture happens at the network/socket layer (kernel syscall boundary), not at in-process function-call granularity.**
  - evidence: Official docs: "Keploy generates tests by using eBPF hooks in the Linux kernel to capture socket-level application traffic." The eBPF concept page adds it "intercept[s] network packets at the socket level with near-zero overhead", capturing "all incoming API requests and outgoing dependency calls — database queries, external API calls, and message queue interactions."
  - source: https://keploy.io/docs/keploy-explained/how-keploy-works/ and https://keploy.io/docs/concepts/what-is-keploy-ebpf/
- **Record mode = ingress interceptor (captures incoming HTTP) + egress interceptor (redirects outgoing TCP/UDP into Keploy's proxy); the proxy converts binary streams to YAML, and unknown protocols are stored as base64 bytes.**
  - evidence: Docs: the ingress side "captures incoming HTTP calls and stores them in YAML format"; the egress side "forwards TCP and certain UDP connections to the proxy for interception" transparently; "Keploy can handle unknown dependencies by recording binary data as base64 in YAML." In test mode Keploy "reads the YAML files for test cases and stubs/mocks... sends recorded HTTP test cases, and mocks responses for outgoing calls."
  - source: https://keploy.io/docs/keploy-explained/how-keploy-works/
- **Concrete eBPF attach points (v3 main, Linux): tracepoint on sys_enter_socket plus cgroup-level programs — AttachCgroupInet4Connect/Inet6Connect (connect redirection into the proxy), sendmsg4/recvmsg4 (UDP/DNS), getpeername4/6 (hides the redirect from the app), bind4/6, and sockops.**
  - evidence: pkg/agent/hooks/linux/hooks.go: link.Tracepoint("syscalls", "sys_enter_socket", ...); link.AttachCgroup for connect4/connect6, udp4/6 sendmsg+recvmsg (comment: "unconnected UDP DNS won't be intercepted" if attach fails), AttachCgroupInet4GetPeername/Inet6GetPeername. hooks README: the package "contains the user-space Go code responsible for loading eBPF hooks and eBPF maps... Additionally, it launches proxy on a defined port to capture egress calls." Compiled BPF objects ship as bpf_x86_bpfel.o / bpf_arm64_bpfel.o (cilium/ebpf v0.21.0 in go.mod).
  - source: https://github.com/keploy/keploy/blob/main/pkg/agent/hooks/linux/hooks.go and https://github.com/keploy/keploy/blob/main/pkg/agent/hooks/README.md
- **In the v2.x line the hook set was broader: kprobes/kretprobes on sys_accept/accept4, sys_read, sys_write, sys_writev, sys_sendto, sys_connect, plus tcp_v4/v6_connect kprobes and the same cgroup connect/getpeername hooks — i.e., ingress capture via syscall kprobes.**
  - evidence: v2.6.19 pkg/core/hooks/hooks.go: link.Kprobe("sys_accept"...), link.Kprobe("sys_accept4"...), link.Kprobe("sys_read"...), link.Kprobe("sys_write"...), link.Kprobe("sys_writev"...), link.Kprobe("sys_sendto"...), link.Kprobe("sys_connect"...), link.Kprobe("tcp_v4_connect"...), AttachCgroupInet4Connect/GetPeername — with a source comment "------------ For Ingress using Kprobes --------------".
  - source: https://github.com/keploy/keploy/blob/v2.6.19/pkg/core/hooks/hooks.go
- **The proxy is a byte-transparent relay with parser observation on a tee — real traffic always flows to the real upstream during record; parsers only observe copies and emit mocks (v3 'V2 proxy' architecture).**
  - evidence: pkg/agent/proxy/README.md: "the userspace process that eBPF hooks redirect application TCP connections to. Its job is to forward bytes transparently between the application and the real upstream (database, API, etc.) while observing the traffic and producing mocks for replay." Relay goroutines "stamp time.Now() at the syscall boundary" and tee chunks into a read-only FakeConn consumed by the parser; a supervisor adds a panic firewall, hang watchdog, and memory cap, and drops incomplete mocks ("partial mocks never reach storage").
  - source: https://github.com/keploy/keploy/blob/main/pkg/agent/proxy/README.md
- **Protocol coverage (v2.6.19, released line): dedicated wire-protocol parsers exist in-tree for http, grpc, mongo, mysql, postgres, redis, plus scram (auth) and a generic byte-level fallback.**
  - evidence: GitHub tree of tag v2.6.19 lists pkg/core/proxy/integrations/{generic, grpc, http, mongo, mysql, postgres, redis, scram, util}. Protocol parsing is real wire-format decoding, e.g. the MySQL parser has wire/phase/conn/handshakeV10Packet.go, authSwitchRequestPacket.go, wire/phase/query/preparedstmt/stmtExecutePacket.go, rowscols/binaryProtocolRowPacket.go, etc.
  - source: https://github.com/keploy/keploy/tree/v2.6.19/pkg/core/proxy/integrations (dir listing via GitHub API) and https://github.com/keploy/keploy/tree/main/pkg/agent/proxy/integrations/mysql
- **CAVEAT for current OSS v3 main (module go.keploy.io/server/v3, releases v3.5.x as of July 2026): only http, mysql, and generic parsers are registered in-tree; postgres/mongo/redis/kafka/grpc appear via type constants, models, docs and CI but their parser code is no longer under the OSS integrations dir — verify per-release before relying on a specific protocol.**
  - evidence: pkg/agent/proxy/parsers.go imports exactly three: integrations/generic, integrations/http, integrations/mysql. integrations.go still declares IntegrationType constants HTTP, HTTP2, GRPC, GENERIC, MYSQL, POSTGRES_V1/V2/V3, MONGO_V1/V2, AEROSPIKE; pkg/models retains postgres/mongo/grpc models and CI still runs gin-mongo and django-postgres suites. Latest release v3.5.84 (2026-07-01).
  - source: https://github.com/keploy/keploy/blob/main/pkg/agent/proxy/parsers.go and https://github.com/keploy/keploy/blob/main/pkg/agent/proxy/integrations/integrations.go
- **The docs' record-time classification table nevertheless documents live handling for HTTP/HTTP2, MySQL, Postgres v2, Mongo v2, Redis, gRPC v2, Kafka, and Generic/DNS — including protocol-aware session vs per-test mock classification.**
  - evidence: docs/explanation/mock-lifetimes.md classifies e.g. Postgres StartupMessage/SASLResponse and SET/SHOW as session mocks, non-empty Parse (prepared statements) as connection-lifetime, Redis HELLO/AUTH/CLIENT/SUBSCRIBE as session, Kafka ApiVersions/JoinGroup/SyncGroup as session, Mongo hello/isMaster/SCRAM as session; "Everything else: HTTP app requests, MySQL queries, Postgres Bind/Execute, Kafka Produce/Fetch, Redis data commands, Mongo CRUD" are per-test mocks consumed on match.
  - source: https://github.com/keploy/keploy/blob/main/docs/explanation/mock-lifetimes.md
- **What is recorded per interaction: a test case = the ingress HTTP request/response pair (with method, url, headers, body, status, and timestamps) stored as test-N.yaml, plus a mocks.yaml holding every egress dependency exchange captured during that test-set; all human-editable YAML.**
  - evidence: Docs: "Autogenerated test cases and mocks are stored in YAML format"; the custom-mock page shows the schema — version/kind/name + spec.request(method, proto_major/minor, url, header, body, timestamp) and spec.response(status_code, header, body, timestamp) — and notes users can "inspect the results and tweak the test data in the mocks.yml or test-x.yml files." Keploy also "incorporates the timestamps of each request and response in the tests (ingress) and compares these with the timestamps in the mocks (egress)" for match windowing.
  - source: https://keploy.io/docs/running-keploy/custom-mocks/ and https://keploy.io/docs/running-keploy/configuration-file/
- **Mock replay uses a three-tier lifetime model (session/config, connection, per-test) specifically to prevent cross-test mock bleed and to survive stateful protocol features like prepared statements.**
  - evidence: mock-lifetimes.md: per-test mocks are "consumed on match and window-filtered" to fix "Cross-test bleed — test B accidentally matches a data-plane mock that test A recorded"; connection-lifetime mocks fix "prepared-statement evaporation" by making prepares "reusable only within the connID that owns them."
  - source: https://github.com/keploy/keploy/blob/main/docs/explanation/mock-lifetimes.md
- **TLS/encrypted traffic is captured by opportunistic man-in-the-middle: the proxy sniffs for a ClientHello mid-stream, terminates TLS with a Keploy CA-signed MITM cert toward the app, and opens its own TLS session to the real upstream; a CA cert (ca.crt + setup_ca.sh, cfssl dependency) is installed into trust stores. No uprobes on crypto libraries.**
  - evidence: pkg/agent/proxy/opportunistic_tls.go: "The instant a chunk on the CLIENT side starts with a TLS ClientHello (0x16 0x03 …) ... the proxy terminates TLS with the client using keploy's MITM cert (HandleTLSConnection — KeyLogWriter is wired there) [and] opens a fresh tls.Client to the upstream"; handles "server-first TLS protocols (MySQL)" bidirectionally. Supporting files: pkg/agent/proxy/tls/{asset/ca.crt, asset/setup_ca.sh, ca.go, keylog.go, java_detect.go}.
  - source: https://github.com/keploy/keploy/blob/main/pkg/agent/proxy/opportunistic_tls.go
- **In-process nondeterminism is NOT captured at record time; the primary OSS mechanism is response-side 'noise' — fields like timestamps/UUIDs/tokens are detected (by diffing runs) or declared in config (globalNoise, per test-set or per test) and excluded from assertions.**
  - evidence: Marketing/docs: "Keploy identifies noisy fields in the responses accurately like timestamps and random values"; config docs: "The global subsection of globalNoise is used to define parameters that are globally ignored for all API calls during testing", previously only settable per test file. README claims "AI-powered noise detection to identify fields that change between runs — timestamps, UUIDs, session tokens — and automatically excludes them from strict assertions."
  - source: https://keploy.io/docs/running-keploy/configuration-file/ and https://github.com/keploy/keploy
- **Request-side (egress mock matching) nondeterminism is absorbed by tolerance, not determinization: a hardcoded flakyHeaders auto-noise list (SigV4 signatures, x-amz-date, trace/correlation IDs, Stripe/GitHub/Slack webhook signatures, per-call invocation IDs), a shared schema-noise engine that auto-learns drifting body field paths, and Levenshtein-based fuzzy matching in the HTTP matcher.**
  - evidence: http/match.go: "flakyHeaders lists HTTP header keys ... known to change on every request due to cryptographic signatures, timestamps, credential rotation, or per-request identifiers. These are automatically treated as noise during mock matching" (disable with --disableAutoHeaderNoise); imports github.com/agnivade/levenshtein. schemanoise.go: "when a recorded request body and the live one differ on a field, the drifting field path is recorded as noise on the mock so a later strict replay tolerates it instead of failing."
  - source: https://github.com/keploy/keploy/blob/main/pkg/agent/proxy/integrations/http/match.go and https://github.com/keploy/keploy/blob/main/pkg/agent/proxy/integrations/schemanoise/schemanoise.go
- **Crypto-nonce-bearing auth protocols are handled by re-computation rather than byte replay: a dedicated SCRAM package re-derives the server proof (PBKDF2 salted password, HMAC ServerKey) for Mongo/Postgres SASL auth during mocked replay, using a configured password — because recorded SCRAM bytes can never match a fresh client nonce.**
  - evidence: v2 pkg/core/proxy/integrations/scram/scram.go: "GenerateServerFinalMessage generates the server's final message (i.e., the server proof) for SCRAM authentication, using a default password and given authentication message, mechanism, salt, iteration count" — supporting SCRAM-SHA-1 (with mongoPasswordDigest) and SCRAM-SHA-256 (SASLprep + pbkdf2.Key).
  - source: https://github.com/keploy/keploy/blob/v2.6.19/pkg/core/proxy/integrations/scram/scram.go
- **Time is the one nondeterminism source Keploy can determinize — via enterprise-only 'Time Freezing' at replay: Go apps rebuilt with the faketime build tag read clock from an agent file; Node/Java/Python get an LD_PRELOAD shared library intercepting time calls. UUIDs and RNG have no equivalent freeze.**
  - evidence: Time Freezing docs: motivated because "time-sensitive objects like JWT tokens are a challenge as they expire, leading to test failures"; Go path "swaps Go's time package to read from a runtime agent file instead of the OS clock" via faketime; other languages use LD_PRELOAD of freeze_time_amd64.so/arm64.so; listed as an Enterprise/Self-Hosted feature enabled with --freeze-time.
  - source: https://keploy.io/docs/keploy-cloud/time-freezing/
- **Language/runtime coverage is broad because interception is at the OS layer, but platform requirements are strict: Linux kernel >= 5.10 with root, macOS only via Docker/Lima, Windows natively via a WinDivert packet-redirection driver (admin, AMD64) or WSL; apps must be launched wrapped in the Keploy CLI.**
  - evidence: Install docs: "Make sure your Linux kernel version is 5.10 or higher"; record syntax is `keploy record -c "go run main.go"` (or wrapping a docker run). README claims support for "Go, Java, Node.js, Python, Rust, C#, ...". v3 source confirms native Windows support via pkg/agent/hooks/windows/assets/{WinDivert.dll, WinDivert64.sys} + redirector.go (packet redirection driver instead of eBPF).
  - source: https://keploy.io/docs/server/installation/ and https://github.com/keploy/keploy (tree: pkg/agent/hooks/windows/)
- **Historical note: Keploy v1 (pre-eBPF) DID use language SDKs — a Go SDK with per-library wrappers — which is the integration model v2 explicitly abandoned; this is why old docs mention Redis/DynamoDB/Elasticsearch 'support' that meant wrapped clients, not wire parsers.**
  - evidence: v1.0.0 Go integration docs list SDK-supported dependencies: "MongoDB, DynamoDB, SQL Driver, Elasticsearch, and Redis. For clients, it supports net/http and gRPC" — i.e., in-process wrappers per client library, superseded by the eBPF/no-SDK approach.
  - source: https://keploy.io/docs/1.0.0/go/integration/

## Keploy replay + mock-matching + noise + verdict + dedup model (official docs, wiki, and keploy/keploy v3 source @ ca1a05ea, 2026-07-04)

Keploy replay runs the real application process live and re-sends recorded inbound HTTP requests to it, while ALL outbound network calls are intercepted at the eBPF/proxy layer and answered from recorded YAML mocks (no real dependencies; the old fallback-to-real-on-miss flag is deprecated — "Replay is now always deterministic"). Mock matching is NOT exact-bytes: for HTTP it is a staged cascade — schema match (method, URL path with regex url-noise + auto-detected dynamic id segments, content-type media overlap, header-KEY presence, query-param key sets) → exact body → noise-aware JSON field match → fuzzy fallback (Levenshtein for ASCII, Jaccard shingles for binary) that picks the best candidate with no minimum threshold; unknown protocols use exact-bytes then Jaccard with a 0.9 threshold. On a miss the proxy synthesizes a 502 "no matching mock" into the app and emits a mismatch report; the test then usually fails via the response diff. Noise = (a) docs-described double-run at record time (Keploy re-runs the request against captured mocks and marks differing response fields as noise), (b) source-verified auto-flagging of timestamp-shaped values (IsTime) at test-case encode time, (c) manual test.globalNoise config (global + per-test-set, body/header/url regex paths), (d) opt-in learned request-body noise (--schema-noise-detection/persisted req_body_noise), (e) a DenoiseTestCases API and a --must-pass flaky-delete rerun. The pass/fail verdict compares ONLY the inbound HTTP response: status code equality, headers modulo header-noise (Content-Length ignored if body matched), JSON body diff modulo body-noise (non-JSON bodies skipped unless --compare-all; >1MB bodies compared by size). Dependency side effects are NOT diffed by default: an expected-vs-consumed mock-set mismatch is explicitly ignored when the response matches (only the opt-in SchemaNoiseStrict mode fails a passing test on a rejected/unconsumed expected mock), so a missing or extra DB write passes silently unless it changes the response. Dedup: dynamic (coverage-based, experimental) via per-testcase line-coverage maps → duplicates.yaml → `keploy dedup --rm`; static (enterprise) via record-time schema signatures (normalized path, header keys, body schema hash) that drop repeats during capture.

- **Replay model: the application process runs live (its real code executes); Keploy starts it, replays previously recorded inbound API requests against it, and intercepts every outbound dependency call, serving the recorded response instead of letting the call reach the real dependency.**
  - evidence: Official docs: "start keploy in test mode to replay all recorded API calls/test-cases"; "When the application will try to talk to any dependencies like DBs, Routers, vendor services, Keploy will intercept and provide the previously recorded dependency response." How-it-works page: in test mode Keploy "reads the YAML files for test cases and stubs/mocks. It starts the application, sends recorded HTTP test cases, and mocks responses for outgoing calls" via eBPF redirection of outgoing TCP/UDP into its proxy.
  - source: https://keploy.io/docs/keploy-explained/introduction/ and https://keploy.io/docs/keploy-explained/how-keploy-works/
- **During replay there is no fallback to real dependencies on a mock miss: the once-available fallBackOnMiss option is deprecated and ignored — replay is always fully mocked/deterministic (except hosts explicitly configured as passthrough/bypass).**
  - evidence: config/config.go:208: `FallBackOnMiss bool ... // Deprecated: this flag is ignored. Replay is now always deterministic.` and cli/provider/cmd.go:405: flag help text "[DEPRECATED] This flag is ignored. Replay is now always deterministic."
  - source: github.com/keploy/keploy @ ca1a05ea — config/config.go:208, cli/provider/cmd.go:405
- **HTTP mock matching is a staged cascade, not exact-byte matching: (1) SchemaMatch filters candidates by content-type media-type overlap, guessed body type, URL path, HTTP method equality, header KEY presence (values ignored; extra request headers allowed), and query-parameter key-set equality; (2) exact body match; (3) JSON field-level body match; (4) fuzzy fallback.**
  - evidence: pkg/agent/proxy/integrations/http/match.go: match() runs SchemaMatch → ExactBodyMatch → PerformBodyMatch (JSON) → PerformFuzzyMatch. SchemaMatch (line 533) checks mediaTypesOverlap, MatchBodyType, MatchURLPath, method equality, HeadersContainKeys ("presence-only; extra request headers allowed"), MapsHaveSameKeys for URL params.
  - source: github.com/keploy/keploy @ ca1a05ea — pkg/agent/proxy/integrations/http/match.go:135-293,533-597
- **URL matching tolerates non-determinism two ways: user-configured url-noise regexes (both mock and live path have the pattern replaced by a placeholder before comparing) and a zero-config second pass that wildcards path segments that look like machine-generated ids (numeric/uuid/hex/long token) on BOTH sides while all other segments must be byte-equal (disable via DisableAutoURLDynamic).**
  - evidence: match.go MatchURLPath: url-noise replaces patterns with "{{keploy.urlnoise}}" in both paths; comment: "Pass 2 (zero-config DEFAULT): only when nothing matched... retry allowing auto-detected dynamic id segments (numeric/uuid/hex/long token) to vary — so a non-deterministic path id doesn't 502 with no config." pathMatchesModuloDynamicSegments requires same segment count and every non-id segment exactly equal.
  - source: github.com/keploy/keploy @ ca1a05ea — pkg/agent/proxy/integrations/http/match.go:199-218,319-444
- **The final fuzzy-match stage is heuristic and threshold-free for HTTP: after base64 exact checks, it strips known-noisy values from mock bodies, then picks the mock with minimum Levenshtein distance (ASCII) or highest Jaccard shingle similarity (binary) — it returns the best candidate as a match regardless of how low the similarity is. The generic (unknown-protocol/binary) parser instead requires exact byte match first, then Jaccard similarity with a 0.9 floor.**
  - evidence: match.go PerformFuzzyMatch → findStringMatch (levenshtein.ComputeDistance, returns best index even if distance is large) and jaccardBestMatch (CreateShingles + JaccardSimilarity, `if mxIdx != -1 { return true, ... }`). Generic parser match.go: `index := findExactMatch(filteredMocks, reqBuff); if index == -1 { index = findBinaryMatch(filteredMocks, reqBuff, 0.9) }`.
  - source: github.com/keploy/keploy @ ca1a05ea — pkg/agent/proxy/integrations/http/match.go:775-890; pkg/agent/proxy/integrations/generic/match.go:22-62,179-260
- **Mocks are looked up from two pools with per-test priority: per-test mocks (Lifetime=PerTest, time-window filtered at ingest, consumed on match) and session mocks (auth/handshake traffic, reusable across tests, not consumed); per-test mocks are matched first so a session mock only serves when no per-test mock matches.**
  - evidence: match.go comment block: "Fetch HTTP mocks from BOTH pools: Per-test mocks (Lifetime=PerTest)... window-filtered at ingest, consumed on match... Session mocks (Lifetime=Session): auth/SigV4/SQS handshake, reusable across every test... Ordering: per-test FIRST."
  - source: github.com/keploy/keploy @ ca1a05ea — pkg/agent/proxy/integrations/http/match.go:147-183
- **On a mock miss during replay the app receives a synthetic HTTP 502 with body "keploy: no matching mock found for this HTTP request", and Keploy builds a structured mismatch report (which match phase ruled candidates out, candidate count, closest mock, diff, next steps) surfaced in logs/report/`keploy report` — the test itself then fails only via the resulting response difference.**
  - evidence: decode.go: "No mock matched — send a 502 so the application gets a proper HTTP error instead of a silent connection close" + literal 502 response string; buildHTTPMismatchReport with matchDiag phases (MatchPhaseNoMocks/Schema/Body/Strict/Exhausted); replay.go log guidance: "Add drifting dynamic fields as noise (test.globalNoise), or re-record the test-set".
  - source: github.com/keploy/keploy @ ca1a05ea — pkg/agent/proxy/integrations/http/decode.go:223-253, match.go:120-128, pkg/service/replay/replay.go:853-857
- **Noise detection per official docs/wiki is a record-time double-run: as the app serves an API during recording, Keploy re-runs that request against the captured dependency mocks and marks response fields that differ between the two runs as random/noisy, excluding them from assertions.**
  - evidence: Wiki/docs: "As the application serves the API, Keploy re-run that API request with the captured dependency mocks. Keploy identifies differences in API responses, marking them as random/noisy fields"; intro docs: "identifies noisy fields in the responses accurately like (timestamps, random values) to ensure high quality tests." Glossary: "Noisy field refers to the random data whose value changes each time you make a request."
  - source: https://github.com/keploy/keploy/wiki/1.-Know-more-about-Keploy ; https://keploy.io/docs/keploy-explained/introduction/ ; https://keploy.io/docs/concepts/general-glossary/
- **In the current v3 source, the built-in automatic noise marking at test-case save time is timestamp-shape-based, not diff-based: EncodeTestcase flattens the HTTP response and auto-adds any field whose value parses as a date (~20 formats) or as a unix-epoch number within ±24h of now (pkg.IsTime) to the test case's noise map, persisted as a noise assertion in the YAML.**
  - evidence: pkg/platform/yaml/testdb/util.go:145-165: FlattenHTTPResponse → FindNoisyFields with comparator `pkg.IsTime(v)`; found fields added to `noise` map → `a[models.NoiseAssertion] = noise`. pkg/util.go IsTime: epoch heuristic `currentTime.Sub(expectedTime) < 24*time.Hour` plus a dateFormats parse loop.
  - source: github.com/keploy/keploy @ ca1a05ea — pkg/platform/yaml/testdb/util.go:126-190, pkg/util.go:280-310
- **Manual noise config exists at two scopes in keploy.yml — test.globalNoise.global and test.globalNoise.test-sets.<id> — with body/header (and url, for mock matching) buckets; keys are dotted field paths or header names and values are optional regexes (empty array = ignore the whole field, regex = ignore matching values only).**
  - evidence: Docs config page shows `globalNoise: global: { body: {"url": ['https?://\\S+']}, header: {"Date": []} }` and test-set-level `"uuid": []`, explaining it filters "out consistent noise, ensuring a cleaner evaluation of responses." Source Match() merges noiseConfig["body"]/["header"] with per-testcase tc.Noise (fields prefixed body./header.); decode.go feeds the same config's url/requestbody buckets into mock matching.
  - source: https://keploy.io/docs/running-keploy/configuration-file/ ; github.com/keploy/keploy @ ca1a05ea — pkg/matcher/http/match.go:86-112, pkg/agent/proxy/integrations/http/decode.go:180-215
- **Additional noise machinery: (a) a DenoiseTestCases service API adds/removes noise paths on stored test cases (models.NoiseParams with Ops add/remove — used to mark fields noisy from reports/UI); (b) opt-in --schema-noise-detection learns request-body fields that drift between recording and replay and persists them as req_body_noise on mocks, with --schema-noise-strict enforcing that any non-noise drift rejects the mock; (c) --must-pass reruns test sets and deletes flaky test cases.**
  - evidence: pkg/service/replay/replay.go:3585 DenoiseTestCases merges/removes noiseParam.Assertion into tc.Noise and updates the test case. cli flags: "Detect request-body fields that drift between recording and replay and persist them as field-path noise (req_body_noise)" and "a candidate mock carrying req_body_noise is rejected when any field OUTSIDE its learned/user-configured noise drifted". replay.go:701-794: --must-pass "delete the failed testcases and rerun" / "the testset is flaky... remove flaky testcases".
  - source: github.com/keploy/keploy @ ca1a05ea — pkg/service/replay/replay.go:3585-3612,701-794; cli/provider/cmd.go:417-418; config/config.go:225-226
- **The pass/fail verdict compares ONLY the inbound response: status code (strict equality), headers modulo header-noise (with a Content-Length mismatch ignored when the body matched), and body — JSON bodies get a field-level diff honoring body-noise paths and --ignore-ordering; non-JSON bodies are skipped entirely unless --compare-all is set; bodies >1MB at record time are compared by size only.**
  - evidence: pkg/matcher/http/match.go Match(): builds Result{StatusCode, BodyResult, HeadersResult}; JSONDiffWithNoiseControl(validatedJSON, bodyNoise, ignoreOrdering); "Skipping body comparison for non-JSON response" when !compareAll; BodySkipped → bodySizeResult; "Ignoring Content-Length mismatch since body content is identical"; `if tc.HTTPResp.StatusCode == actualResponse.StatusCode { res.StatusCode.Normal = true } else { pass = false }`.
  - source: github.com/keploy/keploy @ ca1a05ea — pkg/matcher/http/match.go:30-182
- **Dependency-call side effects are NOT part of the verdict by default: Keploy records which mocks were consumed per test and detects an expected-vs-actual mock-set mismatch, but if the response assertion passed the mismatch is explicitly ignored ("mock mapping mismatch ignored because testcase passed"); a missing or extra DB write therefore cannot fail a test unless it changes the HTTP response. Only under the opt-in SchemaNoiseStrict mode does an unconsumed expected mock fail an otherwise-passing test; when the test already failed, a mock mismatch just reclassifies it as "obsolete" with re-record guidance.**
  - evidence: pkg/service/replay/replay.go:1985-2011: `case testPass: r.logger.Debug("mock mapping mismatch ignored because testcase passed"...)`; `case testPass && r.config.Test.SchemaNoiseStrict: ... "failing testcase even though the response matched" testPass = false`; default: "mock mapping mismatch detected; marking testcase as obsolete. Re-record the test case or run with --update-test-mapping".
  - source: github.com/keploy/keploy @ ca1a05ea — pkg/service/replay/replay.go:1979-2012
- **Extra/unmatched outbound calls are surfaced as diagnostics, not assertions: unconsumed mocks can be garbage-collected with --remove-unused-mocks ("Clear the unused mocks for the passed test-sets"), and mock-miss events accumulate in a mockMismatchFailures table printed after the run — neither flips a passing verdict by default.**
  - evidence: cli/provider/cmd.go:404 flag text; replay.go:229-235 mockMismatchFailures *TestFailureStore + PrintFailuresTable at line 860; TestResult.MockMismatches populated as report info.
  - source: github.com/keploy/keploy @ ca1a05ea — cli/provider/cmd.go:404, pkg/service/replay/replay.go:229-235,828-860,2187-2207
- **Dynamic (coverage-based) test deduplication — experimental — detects duplicate tests from a per-testcase line-coverage map (testSetID/testCaseID → executed lines per source file): run `keploy test ... --dedup` to generate dedupData.yaml, `keploy dedup` to compute duplicates.yaml, and `keploy dedup --rm` to delete the redundant tests; docs cover Go and Java (JaCoCo agent) plus JS variants, and note coverage flags must be present in the build.**
  - evidence: Docs: "per-testcase coverage map (testSetID/testCaseID to executed lines per source file)"; commands `keploy test -c "docker compose up" --containerName containerName --dedup`, `keploy dedup --rm`; "The deduplication feature necessary for high-traffic environments is currently experimental."
  - source: https://keploy.io/docs/keploy-cloud/deduplication/ ; https://keploy.io/docs/keploy-explained/introduction/
- **Static deduplication (enterprise) prevents duplicates at record time using a schema signature — HTTP method + normalized URL path (numeric ids/UUIDs → {id}) + sorted request/response header keys + response status + JSON body-schema hashes (type inference, XOR-combined) — "the first occurrence of a signature is recorded. Every later occurrence is silently dropped", contrasting with coverage dedup which "runs after a replay and removes tests that do not add code coverage".**
  - evidence: Docs quotes: "the Keploy agent computes a lightweight schema signature for each captured request/response pair and drops any copy whose signature has already been seen in this session"; enabled via `keploy enterprise record ... --static-dedup` or `agent: static-dedup: true`.
  - source: https://keploy.io/docs/keploy-cloud/static-deduplication/
- **Marketing-level claims of "AI-powered noise detection" and "kernel-level time freezing" (e.g., third-party roundups and keploy.io landing pages) overstate the open-source mechanism: in the OSS v3 tree the automatic parts are the timestamp-shape heuristic (IsTime) at record time plus the opt-in drift-learning schema-noise engine; everything else is manual globalNoise config or the docs-described record-time re-run diff.**
  - evidence: No LLM/AI code path exists in the OSS noise pipeline (pkg/platform/yaml/testdb/util.go, pkg/agent/proxy/integrations/schemanoise, pkg/matcher/http/match.go); the landing-page claim "automatically excludes them from strict assertions... Combined with time-freezing at the kernel level" appears only in marketing copy (keploy.io/regression-testing, index.dev roundup), not in the docs' mechanism descriptions or the source.
  - source: https://keploy.io/regression-testing (marketing) vs github.com/keploy/keploy @ ca1a05ea source inspection

## Competitive research: Keploy's handling of state, concurrency, test isolation, cross-version mock matching, and recurring user-reported limitations (docs + GitHub issues + source config)

Keploy has NO real database state during replay: all dependency I/O (Postgres/MySQL/Mongo/Redis wire protocols, HTTP) is intercepted by eBPF+transparent proxy at record time and served back from YAML mocks at replay; there is no seeding concept, writes land nowhere, and the only assertion is a response diff against the recorded HTTP response. Replay is now "always deterministic" (the old fallBackOnMiss passthrough flag is deprecated/ignored). Concurrency is a documented weak point on both sides: at record, parallel load silently drops mocks (100-slot channel, ~9.8% measured loss) and --enable-sampling deliberately bypasses capture of excess concurrent requests; at replay, mock-to-test attribution is by record-time timestamp windows plus replay-time consumption order, so background workers, health checks, reconnects, and connection pools cause cross-test mock bleed and intermittent match failures (StrictMockWindow was recently added specifically to "eliminate cross-test mock bleed"). Test-sets replay sequentially with the app restarted per set; parallel replay crashes (concurrent map writes) and concurrent CLI runs corrupt artifacts — there is no supported any-order/parallel test-case execution model comparable to per-case isolation. Cross-version brittleness is acknowledged in the product itself: matching is payload/hash-exact (e.g. "no recorded invocation shares this SQL hash"), a changed/renamed/added query is a hard miss, and the default behavior demotes a test whose consumed-mock set diverged to OBSOLETE "so the user can re-record" — keploy rerecord is the official remedy for candidate-code call changes. Top recurring complaints: noise/non-determinism false positives (many open issues on noise config not applied, nested fields, silent noise drops), wrong-mock fuzzy matches (both false failures and false passes), protocol coverage gaps (WebSocket, SSE/streaming, server-initiated calls, MySQL cursors, multi-value headers), and performance degradation on large suites. Relevance to deja: Keploy is a pure total-substitution (full-mock) design with time-window correlation — it has none of deja's per-correlation seeding/Execute path, and its issue tracker is a catalog of exactly the correlation-bleed and ordering failure modes deja's per-case logical spaces are designed to avoid.

- **Q1: During replay there is no real database and no seeding — DB interactions are fully mocked at the wire-protocol level. Keploy intercepts traffic with eBPF socket hooks plus a transparent proxy, stores interactions as YAML mocks, and in test mode serves 'mocks instead of real dependencies' with 'no side effects due to non-idempotency' because it 'mocks responses for outgoing calls'.**
  - evidence: How-Keploy-Works docs: egress interceptor 'Forwards TCP and certain UDP connections to the proxy for interception'; proxy 'acts as a transparent proxy for recording or mocking outgoing network calls'; explicit statement that mocks are used instead of real dependencies and no non-idempotency side effects occur. Mongo docs describe parsing raw wiremessages. FAQ: 'Keploy can mock database responses during test replay. This helps isolate tests and ensures consistency.'
  - source: https://keploy.io/docs/keploy-explained/how-keploy-works/ ; https://keploy.io/docs/dependencies/mongo/ ; https://keploy.io/docs/2.0.0/keploy-explained/faq/
- **Q1: Replay is now hard-locked to mocks — the old escape hatch to hit a live dependency on a mock miss was removed. There is a Mocking bool to turn mocking off entirely (then you need a real DB in the right state yourself); there is no seeding/state-materialization mechanism anywhere.**
  - evidence: config/config.go on main: 'FallBackOnMiss bool ... // Deprecated: this flag is ignored. Replay is now always deterministic.' and 'Mocking bool'. Docs' common-errors page tells users whose replay hits a real DB in a different state to 'reset database state' / 'use database mocks/stubs' — manual, no tooling.
  - source: https://github.com/keploy/keploy/blob/main/config/config.go (Test struct, FallBackOnMiss/Mocking fields) ; https://keploy.io/docs/keploy-explained/common-errors/
- **Q1 (corollary): writes are never applied to any store during replay; correctness checking is only a diff of the candidate's HTTP response against the recorded response (with noise subtraction) — i.e., Keploy is a pure total-substitution/full-mock design, so transitive effects through substituted results are structurally invisible.**
  - evidence: Docs describe 'Mocking responses during testing by matching requests' and a 'Response Mismatch Error' raised when 'the application's behavior has changed, leading to different responses'; no write-verification or state-assertion mechanism appears in docs, config, or CLI reference.
  - source: https://keploy.io/docs/keploy-explained/how-keploy-works/ ; https://keploy.io/docs/keploy-explained/common-errors/ ; https://keploy.io/docs/running-keploy/cli-commands/
- **Q2 (record-side concurrency): parallel requests during record cause silent mock loss — the agent→CLI mock channel is hard-capped at 100 slots and drops mocks after a 200 ms budget; a measured 4-producer workload showed 9.8% silent loss, and the drop log only fires at n==1 and every 1024th drop, so sessions 'can quietly degrade to losing 80%+ of mocks' that later surface as replay misses.**
  - evidence: Open issue #4175: 'silent mock drops at recording time — outChan cap of 100 collapses under modest parallel load'; quotes measurement '9.8% silent mock loss' vs '0% loss' at cap 16384, and the downstream replay error 'keploy-pg-v3: no recorded invocation matched (... reason=no recorded invocation shares this SQL hash)'. Related closed #4171 added configurable record buffers for 'large-payload / high-concurrency apps'.
  - source: https://github.com/keploy/keploy/issues/4175 ; https://github.com/keploy/keploy/issues/4171
- **Q2 (record-side concurrency, by design): the --enable-sampling flag caps how many concurrent in-flight requests are captured; excess concurrent requests are proxied transparently but NOT recorded as test cases — i.e., under concurrency Keploy deliberately samples rather than correlating.**
  - evidence: Issue #4211 describing the documented behavior: 'when the number of concurrent in-flight requests exceeds the configured sampling slot count, the excess requests must be proxied transparently without being captured as test cases (the bypass path in pkg/agent/proxy/incoming/http.go)' — it is 'the user-visible safety valve' so a 'traffic burst can't drive the agent's memory unbounded'.
  - source: https://github.com/keploy/keploy/issues/4211
- **Q2 (correlation model): mocks are correlated to test cases by record-time timestamp windows and (in v3) a mappings.yaml; replay-time attribution tracks CONSUMPTION ORDER, so 'any reconnect, retry, or test flake moves a mock to a different owner' — a startup Redis HELLO recorded 14s before any test was attributed to test-3 because a client reconnect during test-3's replay consumed it.**
  - evidence: Open issue #4083: 'upsertActualTestMockMapping ... unconditionally appends every mock returned by GetConsumedMocks() to the current test case. Attribution tracks replay-time consumption order... Record-time timestamps on the mocks are ignored even though they're available.' Config comment for StrictMockWindow confirms the window model: 'mocks whose request timestamp falls outside the outer test window are DROPPED rather than promoted to the cross-test unfiltered pool, which eliminates cross-test mock bleed.'
  - source: https://github.com/keploy/keploy/issues/4083 ; https://github.com/keploy/keploy/blob/main/config/config.go (StrictMockWindow comment)
- **Q2 (replay-side concurrency): apps that do concurrent outbound I/O during replay (background workers, health checks, connection pools, async I/O) hit intermittent mock-matching failures because Keploy rebuilds the mock tree between test cases non-atomically (deleteAll() + inserts), letting concurrent readers observe an empty/partial tree.**
  - evidence: Open issue #3580: 'Although individual tree operations are locked, the overall update is not atomic... mock matching can intermittently fail even when valid mocks exist, leading to flaky test failures'; repro step 2 is literally 'Ensure the application performs concurrent outbound requests (e.g. background workers, health checks, connection pools, async I/O).'
  - source: https://github.com/keploy/keploy/issues/3580
- **Q2 (async requests at record): recording two requests fired asynchronously produced wrong mock matching and failing later test cases (fixed/closed May 2025, but demonstrates the ordering sensitivity of the shared-pool model).**
  - evidence: Issue #2679 '[bug]: Wrong mock matching leads to failed testcase': 'send two requests asynchronously to your web server while in keploy record mode... run keploy test... the later testcases are failing' (closed COMPLETED 2025-05-05).
  - source: https://github.com/keploy/keploy/issues/2679
- **Q3: test-sets replay sequentially with the app restarted per test-set by default; a single warm app serving sets 'back-to-back' is a newer opt-in (KeepAppAlive). Users can select specific test-sets (-t "test-set-1,test-set-3") but there is no documented any-order or parallel test-case execution mode.**
  - evidence: config/config.go KeepAppAlive comment: 'Start the user app ONCE on the outer errgroup at Start() time instead of restarting it per test-set... Default FALSE preserves the historical per-test-set restart behaviour.' CLI docs document -t/--test-sets selection but 'do not document flags for controlling test execution order or parallel execution.'
  - source: https://github.com/keploy/keploy/blob/main/config/config.go (KeepAppAlive comment) ; https://keploy.io/docs/running-keploy/cli-commands/
- **Q3: parallel replay is not safe today — running multiple test sets concurrently crashes with 'fatal error: concurrent map writes' on global report maps, and running two Keploy CLI commands in the same project concurrently corrupts mocks/artifacts (an issue asks for a lock file to forbid it).**
  - evidence: Open issue #3412: 'When running multiple test sets concurrently or during parallel test execution in replay mode, the application crashes... Global variables (completeTestReport, failedTCsBySetID...) are accessed from multiple goroutines without synchronization.' Open issue #3836 proposes a lock because concurrent CLI runs cause 'Overwriting test artifacts, Corrupted mocks, Inconsistent recordings'. Historical #479 (closed): races when the old SDK ran tests in parallel with a semaphore of 10.
  - source: https://github.com/keploy/keploy/issues/3412 ; https://github.com/keploy/keploy/issues/3836 ; https://github.com/keploy/keploy/issues/479
- **Q3 (isolation): test cases are NOT fully independent — mocks live in a per-test-set shared pool with a per-test filtered window plus a cross-test 'unfiltered' fallback pool, so a test could historically consume another test's (or app-startup's) mocks; strict per-test containment only became the default recently via StrictMockWindow ('eliminates cross-test mock bleed').**
  - evidence: StrictMockWindow config comment (quoted above) plus issue #4083's concrete cross-test leak, plus #4098 'Streaming test cases missing from mappings.yaml due to double-drain of consumed mocks' and old #1491 'sorting order of test cases wrong'.
  - source: https://github.com/keploy/keploy/blob/main/config/config.go ; https://github.com/keploy/keploy/issues/4083 ; https://github.com/keploy/keploy/issues/4098 ; https://github.com/keploy/keploy/issues/1491
- **Q4: mock matching is payload/hash-keyed per protocol (e.g. Postgres v3 matches on an SQL hash), so a renamed or edited query in candidate code is a hard miss — 'no recorded invocation matched... no recorded invocation shares this SQL hash' — and unsupported wire features make replay drop the DB connection outright.**
  - evidence: Error string quoted in #4175; open issue #4261: 'COM_STMT_FETCH / useCursorFetch=true not supported — cursor rows never recorded, replay drops the connection.'
  - source: https://github.com/keploy/keploy/issues/4175 ; https://github.com/keploy/keploy/issues/4261
- **Q4: Keploy's own default handling of changed dependency calls concedes brittleness: if a test's response fails AND its consumed mock set diverged from the recorded mapping, the test is demoted to OBSOLETE rather than FAILED 'so the user can re-record without seeing the response diff as a hard failure' (StrictFailure=true is the opt-in to make it a real failure). The documented remedy for added/changed DB interactions is the keploy rerecord command.**
  - evidence: config/config.go StrictFailure comment: 'Default false preserves the historical demotion: response failures with mock-set mismatch are marked OBSOLETE so the user can re-record...'. CLI docs: rerecord 'record[s] new Keploy testcases/mocks from existing test cases for given testset(s)'; search-surfaced docs guidance: if replay fails due to missing mocks 'it usually means a new database interaction was introduced, and in that case, re-recording is the correct fix.'
  - source: https://github.com/keploy/keploy/blob/main/config/config.go (StrictFailure comment) ; https://keploy.io/docs/running-keploy/cli-commands/
- **Q4: request-side drift between record and replay (e.g. timestamps embedded in outbound request bodies) is common enough that Keploy added schema-based REQUEST-body noise detection to keep mocks matching, plus auto-noise for flaky headers like AWS SigV4 — direct evidence that byte-exact matching breaks across runs, let alone across code versions.**
  - evidence: config/config.go: 'SchemaNoiseDetection ... detect request-body fields that drift between recording and replay and persist them as field-path noise (req_body_noise) during auto-replay matching'; 'DisableAutoHeaderNoise ... skip auto-noise for flaky headers (e.g. AWS SigV4)'. Feature issue #4233 'Schema-based request-body noise detection & persistence for HTTP mocks (auto-replay)' (closed/implemented).
  - source: https://github.com/keploy/keploy/blob/main/config/config.go ; https://github.com/keploy/keploy/issues/4233
- **Q4: fuzzy matching errs in both directions — wrong mock served for a changed call (false failure or wrong data) and false PASS when a request is changed to something never recorded. For unknown protocols Keploy explicitly falls back to base64 blobs + fuzzy matching.**
  - evidence: #2706 'wrong mock matching by postgres parser' (closed Jan 2026); #2510 open: user changed recorded URL /students/1 to /students/20 'for which there is no mock and no entry in the mongoDB... its getting passed'; docs: 'Keploy can handle unknown dependencies by recording binary data as base64 in YAML and using fuzzy matching to correlate incoming requests during testing.' Feature #3589 'AI-Powered Smart Mock Recommendation and Auto-Healing' and #3738 'Configurable custom matchers for more reliable replay comparisons' acknowledge the brittleness.
  - source: https://github.com/keploy/keploy/issues/2706 ; https://github.com/keploy/keploy/issues/2510 ; https://keploy.io/docs/keploy-explained/how-keploy-works/ ; https://github.com/keploy/keploy/issues/3738
- **Q5 (top recurring limitation #1 — noise false positives): a long tail of issues about non-deterministic response fields wrongly failing tests and noise configuration not working: global noise config not applied (open), noise assertions silently dropped by a YAML type-assertion bug (open), nested-field noise filtration broken (fixed Dec 2025), test-sets failing because of noisy fields (fixed Dec 2025), plus open asks for better auto-detection and large-response denoise. Docs list 'non-deterministic values like timestamps, UUIDs' as a primary replay-failure cause.**
  - evidence: Open: #3492 'Global noise configuration not get applied during replay'; #3872 'Noise assertions silently dropped during YAML decode due to incorrect type assertion'; #2276 indentation levels; #2456 'robust denoise functionality for large responses'; #1098 'detecting accurate noisy parameters'. Closed: #3311, #3299.
  - source: https://github.com/keploy/keploy/issues/3492 ; https://github.com/keploy/keploy/issues/3872 ; https://github.com/keploy/keploy/issues/3311 ; https://github.com/keploy/keploy/issues/3299 ; https://keploy.io/docs/keploy-explained/common-errors/
- **Q5 (top recurring limitation #2 — protocol coverage gaps): WebSocket unsupported per Keploy's own troubleshooting docs; SSE/HTTP streaming support still an open feature; server-initiated calls unsupported (open since ~2024); MySQL cursor fetch unsupported (open); multi-value headers (Set-Cookie) broken (open); Kafka support only landed Jan 2026; HBase/Pulsar/ZooKeeper replay mismatches were being fixed as recently as 2026; large (>750KB) read/write syscalls needed a fix for HTTP/gRPC record.**
  - evidence: Common-errors doc: 'Application might use API that Keploy doesn't support (WebSocket...)'. Open issues: #3811 (SSE/streaming), #1572 (server-initiated calls), #4261 (MySQL COM_STMT_FETCH), #2640 (Set-Cookie multi-value). Closed: #3474 Kafka (2026-01-20), #4191 HBase/Pulsar/ZooKeeper mismatches, #2683 >750KB syscalls.
  - source: https://keploy.io/docs/keploy-explained/common-errors/ ; https://github.com/keploy/keploy/issues/3811 ; https://github.com/keploy/keploy/issues/1572 ; https://github.com/keploy/keploy/issues/4261 ; https://github.com/keploy/keploy/issues/2640 ; https://github.com/keploy/keploy/issues/3474 ; https://github.com/keploy/keploy/issues/4191
- **Q5 (top recurring limitation #3 — flaky matching / silent data loss in the pipeline): beyond #4175/#3580/#4083 above, mock dropping during re-record causes incomplete mappings and test failures (open), stale HTTP/1.1 upstream pool entries caused silent request drops (closed 2026), and performance degrades with large test suites (open). A test-flakiness detection feature was added in response (#3380).**
  - evidence: #3463 'Mock dropping during re-record causes incomplete mappings and test failures' (open); #4165 'stale upstream pool entries cause silent request drops + downstream 503/UC' (closed); #4259 'Performance degrades with large test suites, slow execution' (open); #3380 '[ENHANCEMENT] Add test flakiness detection and reporting' (closed).
  - source: https://github.com/keploy/keploy/issues/3463 ; https://github.com/keploy/keploy/issues/4165 ; https://github.com/keploy/keploy/issues/4259 ; https://github.com/keploy/keploy/issues/3380
- **Method/caveat note: the config.go comments quoted (FallBackOnMiss deprecation, StrictMockWindow, StrictFailure, KeepAppAlive, SchemaNoiseDetection) are from keploy main (go.keploy.io/server/v3, the v3-dev line) as of 2026-07; the 2.0.0 docs site is marked no longer actively maintained and the v3 FAQ URL 404s, so docs evidence is a mix of v2-era pages and current source-of-truth code comments. Everything labeled 'open' was verified open via the GitHub API on 2026-07-06.**
  - evidence: https://keploy.io/docs/keploy-explained/faq/ returns 404; 2.0.0 FAQ page carries a deprecation note; issue states pulled live via gh CLI (states/stateReasons recorded per issue above).
  - source: https://github.com/keploy/keploy/blob/main/config/config.go ; https://keploy.io/docs/2.0.0/keploy-explained/faq/

## Keploy positioning and practitioner evidence (web research)

Keploy positions itself as an open-source (Apache-2.0), eBPF-based record-replay tool that turns real API traffic into deterministic regression tests plus auto-generated dependency mocks (DB/queue/HTTP), run locally or in CI — "API tests faster than unit tests, from user traffic" — with an AI unit-test generator bolted on for coverage boosting. The mechanics are well documented (eBPF syscall hooks for ingress, a transparent proxy for egress, TLS interception via injected cert chain, YAML tapes), but the production-traffic story is the weakest part: no statistical sampling and no PII redaction/masking feature appear anywhere in the OSS docs (only path/method/header record filters and comparison-time "globalNoise" ignore rules), and overhead claims ("negligible") are vendor-only with no independent benchmark. Non-goals are implicit, never stated: load/performance testing is deferred (own compare page vs Speedscale; a perf-testing feature request open since 2022), and the troubleshooting docs contradict marketing on protocol support (gRPC/SOAP listed as unsupported vs "captures gRPC/WebSocket" claims). Comparisons in the wild are almost entirely vendor-authored (Keploy's own /compare pages; Speedscale's and WireMock's roundups don't mention Keploy at all); the structural contrasts vs VCR-style libs (in-process, language-specific, HTTP-only cassettes) and GoReplay (raw HTTP replay, no mocks/assertions) are real but come from Keploy's content. Maturity signals are mixed: ~18k stars, near-daily releases (v3.5.75→84 in 10 days, 615 total releases), active pushes through July 2026 — but 668 open issues including core-path breakage (replay fails on older Debian images, delayed PID capture missing calls, TLS/DNS trouble in containers), essentially zero organic HN/Reddit discussion (every HN story ≤9 points, ≤4 comments, several from Keploy-affiliated accounts), and pricing-page testimonials attributed to Notion/GitLab/Twilio engineers with no independent corroboration. No independent, detailed story of Keploy catching a real regression was found — only generic testimonials and unattributed metrics ("40% reduction in manual testing") — while Keploy's own troubleshooting docs acknowledge replay mismatches from state changes and non-determinism as a routine failure class. Relevance to deja: Keploy validates the record-once/replay-as-partial-mock demand, but its gaps (no per-case isolation guarantees, comparison-time noise suppression instead of declared boundary semantics, no redaction) mirror exactly the problems deja's correlation-isolation and declarative-boundary work addresses.

- **Keploy's intended use cases are: record-replay API regression testing (replay recorded traffic against new code and diff responses), auto-generated mocks for dependencies (Postgres, MySQL, MongoDB, Kafka, RabbitMQ), CI integration (Jenkins, GitHub Actions, Kubernetes), coverage reporting, and an LLM-based unit-test generator for coverage boosting.**
  - evidence: README tagline: 'API tests faster than unit tests, from user traffic'; repo description: 'Open-source platform for creating safe, isolated production sandboxes for API, integration, and E2E testing'; README: 'Run tests with mocks anywhere you like—locally on the CLI, in your CI pipeline (Jenkins, Github Actions..), or even across a Kubernetes cluster'; UTG docs describe it as 'an implementation of Meta LLM research paper' for unit-test generation with coverage boosting.
  - source: https://github.com/keploy/keploy ; https://keploy.io/docs/2.0.0/running-keploy/unit-test-generator/
- **Keploy has no explicit documented non-goals; the clearest implicit non-goal is load/performance testing.**
  - evidence: No 'non-goals' or 'limitations' section exists in README/FAQ/docs. Keploy's own comparison page frames Speedscale as the one offering 'combined functional testing and load testing from captured traffic' and poses 'Can Keploy do load testing like Speedscale?' as an FAQ; a GitHub feature request '[feature]: support performance testing' has been open since Jul 15, 2022.
  - source: https://keploy.io/compare/speedscale ; https://api.github.com/search/issues?q=repo:keploy/keploy+is:issue+is:open&sort=reactions
- **Keploy's docs contradict its marketing on protocol scope: troubleshooting docs list gRPC/SOAP as unsupported ('currently supporting only HTTP/REST and GraphQL') while marketing/blog claims capture of 'every HTTP, gRPC, WebSocket, or database request'.**
  - evidence: Common-errors docs: 'Keploy does not support the protocol or API structure you are using (e.g., gRPC, SOAP, etc.)'; eBPF marketing content claims kernel-level capture of HTTP, gRPC, WebSocket and database requests with no SDK.
  - source: https://keploy.io/docs/keploy-explained/common-errors/ ; https://keploy.io/what-is-ebpf
- **Vs VCR-style cassette libraries (vcr, vcrpy, go-vcr): Keploy differs structurally — kernel/network-layer capture (language-agnostic, zero code change), multi-protocol tapes (DB wire protocols, queues, not just HTTP), and auto-generation of test cases with assertions; VCR libs are in-process, language-specific, HTTP-only, and only replay interactions for tests you wrote. However, essentially all published Keploy-vs-VCR comparison content is vendor-authored.**
  - evidence: go-vcr/vcrpy describe themselves as recording HTTP interactions to cassettes inside language-specific test code; Keploy docs describe eBPF capture plus proxy-based mocking of Postgres/MySQL/MongoDB/Kafka without SDKs. No independent head-to-head comparison was found in searches.
  - source: https://github.com/dnaeon/go-vcr ; https://vcrpy.readthedocs.io/en/latest/ ; https://keploy.io/docs/keploy-explained/how-keploy-works/
- **Vs traffic-replay tools: GoReplay replays raw live HTTP traffic (load/shadowing, terminal-driven, no mock generation or assertions); Speedscale is a commercial Kubernetes-native SaaS using sidecar/service-mesh capture with traffic transforms and load testing; Keploy targets functional regression tests + mocks via eBPF with no sidecars and is not Kubernetes-bound. Notably, competitor Speedscale's own 'traffic shadowing alternatives' roundup (Speedscale, GoReplay, JMeter, K6, NeoLoad, Gatling) does not mention Keploy at all.**
  - evidence: Keploy compare page: Keploy = 'eBPF-based traffic capture, zero instrumentation... no sidecars needed', Speedscale = 'Requires sidecar injection in Kubernetes pods', 'Commercial SaaS with usage-based pricing'. Direct fetch of the Speedscale roundup confirmed zero Keploy mentions.
  - source: https://keploy.io/compare/speedscale ; https://speedscale.com/blog/traffic-shadowing-alternatives/ ; https://goreplay.org/
- **Vs service virtualization (WireMock/Hoverfly/Mountebank): Keploy's auto-recorded mocks overlap Hoverfly's proxy capture mode, but mainstream service-virtualization buyer's guides and roundups (WireMock's buyer's guide, Traffic Parrot, guru99) do not feature Keploy — it is absent from that market's comparison literature.**
  - evidence: Searches for 'Keploy vs WireMock vs Hoverfly' return only generic service-virtualization roundups with no Keploy entry; WireMock's own market-landscape guide does not include Keploy.
  - source: https://www.wiremock.io/post/api-mocking-tools-buyers-guide-market-landscape ; https://trafficparrot.com/articles/best-service-virtualization-tools.html
- **Production recording mechanics: eBPF hooks on syscalls (accept/read/write/sendto/recvfrom) capture ingress; outgoing TCP/UDP is redirected to a Keploy proxy that writes YAML tapes; TLS is intercepted 'by inserting a fake certificate chain between the application and itself'; unknown binary protocols are stored as base64 with fuzzy matching for replay.**
  - evidence: How-Keploy-Works docs: 'Keploy injects eBPF hooks to capture incoming HTTP traffic and redirects outgoing TCP/UDP traffic to its proxy server'; 'For TLS-based connections like HTTPS, Keploy intercepts traffic by inserting a fake certificate chain'; 'recording binary data as base64 in YAML and using fuzzy matching'. Note the tension with the compare-page claim 'no proxy needed' — egress does traverse a proxy in record mode.
  - source: https://keploy.io/docs/keploy-explained/how-keploy-works/ ; https://keploy.io/compare/speedscale
- **No statistical sampling feature is documented for production capture in the OSS product; selectivity is only via record-time include/exclude filters (path, urlMethods, headers, host, with AND/OR matchType).**
  - evidence: The configuration-file docs document 'filters' for 'API calls to the application to avoid recording' and nothing about sampling rates; a targeted probe of docs/README/FAQ found no sampling option. (Absence claim — bounded by pages reviewed.)
  - source: https://keploy.io/docs/running-keploy/configuration-file/
- **No PII redaction/masking feature is documented in the OSS docs; recorded tapes contain full request/response bodies, and the only related mechanism is comparison-time 'globalNoise' (ignore fields when diffing), which does NOT remove data from tapes.**
  - evidence: Config docs describe globalNoise body/header ignore patterns ('Defines patterns to ignore for the response body') with dot-notation paths; targeted searches for Keploy redact/mask/PII returned only third-party OpenTelemetry content; FAQ contains no security/PII statements. (Absence claim — bounded by pages reviewed: README, FAQ, how-it-works, config, common-errors.)
  - source: https://keploy.io/docs/running-keploy/configuration-file/ ; https://keploy.io/docs/2.0.0/keploy-explained/faq/
- **Overhead claims ('minimal overhead', 'negligible impact on system performance' vs SDK/reverse-proxy approaches) are vendor-published only; no independent benchmark of Keploy's record-mode overhead was found.**
  - evidence: The 'negligible impact' language appears in Keploy's own eBPF/TLS blog content; no third-party measurement surfaced in any search angle.
  - source: https://keploy.io/blog/community/ebpf-for-tls-traffic-tracing-secure-efficient-observability ; https://keploy.io/what-is-ebpf
- **Maturity — adoption/maintenance: repo created Jan 19, 2022; 17,975 stars, 2,263 forks, Apache-2.0, pushed July 5, 2026; extremely high release cadence (v3.5.75 through v3.5.84 released between Jun 22 and Jul 1, 2026; 615 releases total, none prerelease); homepage claims '1.2M+ downloads', '300M+ mocks created', '1,000+ contributors' (vendor-claimed).**
  - evidence: GitHub API returned the counts and dates directly; releases API shows near-daily tagging; homepage adoption numbers are self-reported and uncorroborated.
  - source: https://api.github.com/repos/keploy/keploy ; https://api.github.com/repos/keploy/keploy/releases?per_page=10 ; https://keploy.io/
- **Maturity — breaking issues: 668 open issues; top-reacted open bugs describe core-path breakage: test mode fails on older Debian-based images (records fine, cannot replay), delayed PID capture causing missed external calls, TLS configuration difficulties in containers, and DNS resolution failures on older distros.**
  - evidence: GitHub issue search sorted by reactions surfaced '[bug]: keploy test mode doesn't work with older Debian-based images' (open since Aug 2023) and issue #2080 listing PID-capture delay, TLS config, and DNS failures as systemic recording problems.
  - source: https://api.github.com/search/issues?q=repo:keploy/keploy+is:issue+is:open&sort=reactions&order=desc
- **Organic practitioner discussion is remarkably thin for an ~18k-star project, and much of what exists is vendor-driven: every HN story mentioning Keploy has ≤9 points and ≤4 comments (most have 0), several HN comments promoting Keploy come from the official 'keploy' account or recurring promoter accounts, a site:reddit.com search returned zero results, and the SourceForge mirror has 0 reviews.**
  - evidence: HN Algolia story search: best-performing thread is a 2022 Show HN with 9 points/4 comments; 2023-2026 submissions score 1-3 points with 0-1 comments; comment search shows 'keploy (Official)' and repeat blog-promotion accounts; Reddit search: 'No links found'; SourceForge: '0 user reviews'.
  - source: https://hn.algolia.com/api/v1/search?query=keploy&tags=story ; https://sourceforge.net/projects/keploy.mirror/reviews/
- **Review-site signals: vendor cites 4.9 ratings on G2 and Gartner Peer Insights; reported cons across reviews are onboarding/documentation gaps, a learning curve for advanced configuration, limited support for running without Docker on macOS, and 'occasional issues with having to regenerate fragile stubs'. Pricing-page testimonials attributed to engineers at Notion, GitLab, and Twilio (e.g., 'Ryan O'Brien, DevOps Lead at GitLab') are vendor-published with no independent corroboration or case study found anywhere.**
  - evidence: G2/Gartner aggregations surfaced the pros (isolated testing, mock-all-dependencies) and the cons quoted above; the named-company testimonials exist only on keploy.io/pricing — no matching engineering-blog posts, conference talks, or first-party statements from those companies were found.
  - source: https://www.g2.com/products/keploy/reviews ; https://www.gartner.com/reviews/product/keploy-618993540 ; https://keploy.io/pricing
- **Enterprise adoption evidence is weak: the one named enterprise, Maruti Suzuki, traces to Maruti Suzuki's accelerator program backing Keploy (per Crunchbase); a Tracxn snippet claims it was 'onboarded as a customer with revenue' — accelerator-linked, so it is not clean evidence of an arms-length enterprise customer. Keploy splits OSS vs paid: enterprise/cloud adds Kubernetes recording, team dashboards, and closed-source protocol parsers.**
  - evidence: Crunchbase profile (hybridk8s) lists Maruti Suzuki Accelerator involvement; README notes some dependency parsers are 'not open-source by nature... supported in Keploy enterprise'; homepage: 'advanced features available through managed cloud service'.
  - source: https://www.crunchbase.com/organization/hybridk8s ; https://tracxn.com/d/companies/keploy/__lTKMBFH3EscRafIRVxo_LNmjVc2M3TkfO72VRNMrhrs ; https://github.com/keploy/keploy
- **No independent, detailed public story of Keploy catching a real regression exists (or failing to catch one); the evidence base is generic vendor testimonials and unattributed marketing metrics, while Keploy's own troubleshooting docs treat replay mismatch from state changes and non-determinism as a routine, expected failure class — i.e., false-positive divergence noise is the documented norm, not a documented catch.**
  - evidence: Best available 'success' evidence: an anonymous testimonial ('Using it for our Golang projects with Postgres and Redis, Keploy helps us quickly identify and fix issues by replaying real user interactions') and vendor claims of '40% reduction in manual testing efforts'; meanwhile common-errors docs list 'Keploy is unable to replay recorded API requests' due to state changes or non-deterministic values, and response mismatches, as standard errors. Multiple targeted searches for engineering-blog case studies found only Keploy's own content-marketing posts.
  - source: https://keploy.io/docs/keploy-explained/common-errors/ ; https://keploy.io/regression-testing ; https://keploy.io/blog
