Product Decisions This Supports
- Feature feasibility for "have we seen this before?" problems at scale. Named, config-defined Bloom filters and Cuckoo filters make it cheap to prototype deduplication, already-viewed content suppression, invite/allowlist gating, and cache-penetration protection without provisioning a Redis cluster or a full key-value store. That directly informs whether a "unique-per-user" or "first-seen-only" feature is a one-sprint build or an infrastructure project.
- Approximate analytics as a product surface. HyperLogLog (unique visitors/unique actors) and Count-Min sketches (heavy hitters, top-N trends, per-tenant volume estimation) let you scope dashboards and "trending"/"most active" features without committing to exact-count storage costs. This is the key build-vs-buy conversation: exact counts are an unbounded storage liability, so the decision is really "approximate within X% and ship" versus "dedicate a data team."
- Cost/scale tradeoff framing for roadmap sequencing. Because each structure is declared once in config and injected by name, capacity and error-rate knobs become explicit, reviewable product parameters rather than buried constants. PMs can ask "what false-positive rate are we willing to tolerate?" as a product question instead of an engineering one.
- Operational transparency for support and on-call. The
probabilistic:list command gives a non-authoritative inventory of what filters exist in an environment — useful for release checklists, and for confirming a filter was actually wired up before promising a feature in a launch note.
- Risk flag: framework mismatch. This is a Symfony bundle, not a Laravel package. Despite the "Laravel/PHP" framing, a Laravel codebase gets essentially zero out-of-the-box value from the config, registry, autowiring, and console command. If your stack is Laravel, the actionable decision is not "adopt this," but "the underlying
pouya1364/probabilistic-php algorithms are the asset; budget a thin Laravel service-provider adapter (or evaluate a Laravel-native alternative) as separate scope."
When to Consider This Package
Consider it when all of the following hold:
- Your backend is Symfony (with the standard DependencyInjection/Console components), and you want probabilistic structures as first-class, config-declared services rather than hand-constructed objects.
- You have more than one filter, or expect to. The registry and per-instance autowiring pay off at roughly 3+ named structures. A single Bloom filter is a five-line manual instantiation — this is overhead.
- You want configuration-as-documentation. Declaring capacity and error rate in config makes those parameters visible to reviewers and auditable in PRs, which matters in regulated or multi-team environments.
- You are pre-production or in prototype. That is the honest fit for a
0.1.0.
Look elsewhere or wait when:
- You are on Laravel. The bundle's value (bundle config, service wiring, command) does not transfer. Take the underlying library and integrate it yourself, or pick a Laravel-native package.
- You need production stability guarantees. v0.1.0 is an initial release with no API freeze. Config schema, service IDs, and registry method signatures may change without a deprecation cycle. Pinning is possible; relying on it is not.
- You need persistence or a distributed/shared filter. These are in-memory structures per process. Multi-node deployments, cross-request state, and restarts all invalidate the filter. If your requirement is "shared across the fleet," this is not the layer — you need Redis (or similar) with the structure maintained server-side, and this package's role shrinks to a client-side pre-filter.
- You need deletions. Standard Bloom filters cannot delete; Counting Bloom filters can, at a memory multiplier. Cuckoo filters support deletion but have their own insertion-failure behavior. Confirm the semantics of the specific structure before designing a feature that requires removal (e.g. "unsubscribe then allow re-add").
- You need exact counts or audit-grade accuracy. Sketches and HLL are probabilistic by definition. Anything with billing, compliance, or per-user reporting implications needs an exact source of truth, with these used only as a fast path.
How to Pitch It (Stakeholders)
For executives (one line): A small, low-cost integration that lets engineering add "have we seen this before?" and "roughly how many unique users?" capabilities using a few megabytes of memory instead of a database table or a new service — which changes several roadmap items from infrastructure projects into feature work. Note it is a Symfony integration at v0.1.0, so treat it as an evaluation, not a platform commitment.
For engineering leadership: The value is the convention, not novel algorithms. It turns named probabilistic structures into declarative config with injectable services and a listing command, which reduces per-feature bespoke wiring and makes capacity/error-rate decisions reviewable. The tradeoffs are deliberate and must be stated up front: in-memory and per-process (no multi-node sharing, no durability across restart), approximate by design, and pre-1.0 (no API stability promise, no migration path yet).
Recommended ask: Timebox a spike — one real feature (deduplication or unique-visitor estimation) on a non-critical path, one engineer, one to two weeks. Success criteria: measured memory footprint at production-representative cardinality, observed false-positive rate against the configured target, and an honest answer to "what happens on deploy?" If the answer is "the filter resets and we accept a warm-up period," that is a product decision worth surfacing now rather than after launch. If your primary stack is Laravel, scope the work as "adopt the underlying library plus a thin adapter," and price it accordingly — do not represent this bundle as drop-in.