{"id":35873431,"url":"https://github.com/antikirra/probability","last_synced_at":"2026-01-20T17:54:43.562Z","repository":{"id":166582102,"uuid":"642086313","full_name":"antikirra/probability","owner":"antikirra","description":"PHP library for probabilistic code execution, A/B testing, and feature flags with stable distribution 🎲","archived":false,"fork":false,"pushed_at":"2025-10-18T17:09:28.000Z","size":30,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-19T09:54:59.567Z","etag":null,"topics":["ab-testing","experiments","feature-flags","feature-toggles","php","probability","randomization","sampling"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/antikirra.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-05-17T19:41:58.000Z","updated_at":"2025-10-18T17:09:07.000Z","dependencies_parsed_at":"2025-07-19T09:15:30.781Z","dependency_job_id":"4820f9b6-01ce-42ed-99b2-82b1a5266311","html_url":"https://github.com/antikirra/probability","commit_stats":null,"previous_names":["antikirra/probability"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/antikirra/probability","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antikirra%2Fprobability","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antikirra%2Fprobability/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antikirra%2Fprobability/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antikirra%2Fprobability/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/antikirra","download_url":"https://codeload.github.com/antikirra/probability/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antikirra%2Fprobability/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28246677,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2026-01-08T02:00:06.591Z","response_time":241,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ab-testing","experiments","feature-flags","feature-toggles","php","probability","randomization","sampling"],"created_at":"2026-01-08T16:01:54.544Z","updated_at":"2026-01-08T16:05:11.604Z","avatar_url":"https://github.com/antikirra.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Make your code work spontaneously 🙃\n\n![Packagist Dependency Version](https://img.shields.io/packagist/dependency-v/antikirra/probability/php)\n![Packagist Version](https://img.shields.io/packagist/v/antikirra/probability)\n\nA lightweight PHP library for probabilistic code execution and deterministic feature distribution. Perfect for A/B testing, gradual feature rollouts, performance sampling, and controlled chaos engineering.\n\n## Quick Start\n\n```php\nuse function Antikirra\\probability;\n\n// Random execution - 30% chance to log debug info\nif (probability(0.3)) {\n    error_log(\"Debug: processing request #{$requestId}\");\n}\n\n// Deterministic execution - same user always gets same experience\nif (probability(0.5, \"new_checkout_user_{$userId}\")) {\n    return renderNewCheckout();\n}\n\n// Gradual rollout - increase from 10% to 100% over time\nif (probability(0.1, \"feature_ai_search_user_{$userId}\")) {\n    enableAISearch();\n}\n```\n\n## Install\n\n```console\ncomposer require antikirra/probability:^3.0\n```\n\n## 🚀 Key Features\n\n- **Zero Dependencies** - Pure PHP implementation\n- **Deterministic Distribution** - Consistent results for the same input keys\n- **High Performance** - Minimal overhead, suitable for high-traffic applications\n- **Simple API** - Just one function with intuitive parameters\n- **Battle-tested** - Production-ready with predictable behavior at scale\n\n## 💡 Use Cases\n\n- **Performance Sampling** - Log only a fraction of requests to reduce storage costs while maintaining system visibility. Sample database queries, API calls, or user interactions for performance monitoring without overwhelming your logging infrastructure.\n\n- **A/B Testing** - Run controlled experiments with consistent user experience. Test new features, UI changes, or algorithms on a specific percentage of users while ensuring each user always sees the same variant throughout their session.\n\n- **Feature Flags** - Gradually roll out new features with fine-grained control. Start with a small percentage of users and increase over time, or enable features for specific user segments based on subscription tiers or other criteria.\n\n- **Chaos Engineering** - Test system resilience by introducing controlled failures. Simulate random delays, service outages, or cache misses to ensure your application handles edge cases gracefully in production.\n\n- **Rate Limiting** - Implement soft rate limits without additional infrastructure. Control access to expensive operations or API endpoints based on user tiers, preventing abuse while maintaining a smooth experience for legitimate users.\n\n- **Load Balancing** - Distribute traffic across different backend services or database replicas probabilistically, achieving simple load distribution without complex routing rules.\n\n- **Canary Deployments** - Route a small percentage of traffic to new application versions or infrastructure, monitoring for issues before full rollout.\n\n- **Analytics Sampling** - Reduce analytics data volume and costs by tracking only a representative sample of events while maintaining statistical significance.\n\n- **Content Variation** - Test different content strategies, email templates, or notification messages to optimize engagement metrics.\n\n- **Resource Optimization** - Selectively enable resource-intensive features like real-time updates, advanced search, or AI-powered suggestions based on server load or user priority.\n\n## 🔬 How It Works\n\nThe library uses two strategies for probability calculation:\n\n### 1. Pure Random (No Key)\nWhen called without a key, uses PHP's `mt_rand()` for true randomness:\n\n```php\nprobability(0.25); // 25% chance, different result each time\n```\n\n### 2. Deterministic (With Key)\nWhen provided with a key, uses CRC32 hashing for consistent results:\n\n```php\nprobability(0.25, 'unique_key'); // Same result for same key\n```\n\n**Technical Details:**\n- Uses `crc32()` to hash the key into a 32-bit unsigned integer (0 to 4,294,967,295)\n- Normalizes the hash by dividing by `MAX_UINT32` (4294967295) to get a value between 0.0 and 1.0\n- Compares normalized value against the probability threshold\n- Same key → same hash → same normalized value → deterministic result\n\nThe deterministic approach ensures:\n- Same input always produces same output\n- Uniform distribution across large datasets\n- No need for external storage or coordination\n- Fast performance (CRC32 is optimized in PHP)\n\n## 📖 API Reference\n\n```php\nfunction probability(float $probability, string $key = ''): bool\n```\n\n### Parameters\n\n- **`$probability`** *(float)*: A value between 0.0 and 1.0\n    - `0.0` = Never returns true (0% chance)\n    - `0.5` = Returns true half the time (50% chance)\n    - `1.0` = Always returns true (100% chance)\n\n- **`$key`** *(string|null)*: Optional. When provided, ensures deterministic behavior\n    - Same key always produces same result\n    - Different keys distribute uniformly\n\n### Returns\n\n- **`bool`**: `true` if the event should occur, `false` otherwise\n\n### Examples\n\n```php\n// 15% random chance\nprobability(0.15);\n\n// Deterministic 30% for user with id 123\nprobability(0.30, \"user_123\");\n\n// Combining feature and user for unique distribution\nprobability(0.25, \"feature_checkout_user_123\");\n```\n\n## 🎯 Best Practices\n\n### 1. Use Meaningful Keys\n\n```php\n// ❌ Bad - too generic\nprobability(0.5, \"test\");\n\n// ✅ Good - specific and unique\nprobability(0.5, \"homepage_redesign_user_$userId\");\n```\n\n### 2. Separate Features\n\n```php\n// ❌ Bad - same users get all features\nif (probability(0.2, $userId)) { /* feature A */ }\nif (probability(0.2, $userId)) { /* feature B */ }\n\n// ✅ Good - different user groups per feature\nif (probability(0.2, \"feature_a_$userId\")) { /* feature A */ }\nif (probability(0.2, \"feature_b_$userId\")) { /* feature B */ }\n```\n\n### 3. Consider Scale\n\n```php\n// For high-frequency operations, use very small probabilities\nif (probability(0.001)) { // 0.1% - suitable for millions of requests\n    $metrics-\u003erecord($data);\n}\n```\n\n## 📊 When to Use: Random vs Deterministic\n\n| Scenario | Use Random (no key) | Use Deterministic (with key) |\n|----------|-------------------|---------------------------|\n| **Performance sampling** | ✅ Sample random requests | ❌ Would sample same requests |\n| **Logging/Debugging** | ✅ Random sampling | ❌ Not needed for logs |\n| **A/B Testing** | ❌ Inconsistent UX | ✅ User sees same variant |\n| **Feature Rollout** | ❌ Unpredictable access | ✅ Stable feature access |\n| **Chaos Engineering** | ✅ Random failures | ⚠️ Depends on use case |\n| **Load Testing** | ✅ Random distribution | ❌ Predictable patterns |\n| **Canary Deployment** | ❌ Unstable routing | ✅ Consistent routing |\n| **User Segmentation** | ❌ Segments change | ✅ Stable segments |\n\n## 💻 Real-World Examples\n\n### Laravel: Feature Flag Middleware\n\n```php\nnamespace App\\Http\\Middleware;\n\nuse Closure;\nuse function Antikirra\\probability;\n\nclass FeatureFlag\n{\n    public function handle($request, Closure $next, $feature, $percentage)\n    {\n        $userId = $request-\u003euser()?-\u003eid ?? $request-\u003eip();\n        $key = \"{$feature}_user_{$userId}\";\n\n        if (!probability((float)$percentage, $key)) {\n            abort(404); // Feature not enabled for this user\n        }\n\n        return $next($request);\n    }\n}\n\n// Usage in routes:\n// Route::get('/beta', ...)-\u003emiddleware('feature:beta_dashboard,0.1');\n```\n\n### Symfony: Performance Monitoring\n\n```php\nuse function Antikirra\\probability;\nuse Psr\\Log\\LoggerInterface;\n\nclass DatabaseQueryLogger\n{\n    public function __construct(\n        private LoggerInterface $logger,\n        private float $samplingRate = 0.01 // 1% of queries\n    ) {}\n\n    public function logQuery(string $sql, float $duration): void\n    {\n        // Random sampling - no need for deterministic behavior\n        if (!probability($this-\u003esamplingRate)) {\n            return;\n        }\n\n        $this-\u003elogger-\u003einfo('Query executed', [\n            'sql' =\u003e $sql,\n            'duration' =\u003e $duration,\n            'sampled' =\u003e true\n        ]);\n    }\n}\n```\n\n### WordPress: A/B Testing\n\n```php\nuse function Antikirra\\probability;\n\nfunction show_homepage_variant() {\n    $user_id = get_current_user_id() ?: $_SERVER['REMOTE_ADDR'];\n    $key = \"homepage_redesign_user_{$user_id}\";\n\n    // 50% of users see new design, consistently\n    if (probability(0.5, $key)) {\n        get_template_part('homepage', 'new');\n    } else {\n        get_template_part('homepage', 'classic');\n    }\n}\n```\n\n### API Rate Limiting by Tier\n\n```php\nuse function Antikirra\\probability;\n\nclass ApiRateLimiter\n{\n    public function allowRequest(User $user, string $endpoint): bool\n    {\n        $limits = [\n            'free' =\u003e 0.1,    // 10% of requests allowed\n            'basic' =\u003e 0.5,   // 50% of requests allowed\n            'premium' =\u003e 1.0  // 100% of requests allowed\n        ];\n\n        $probability = $limits[$user-\u003etier] ?? 0;\n        $key = \"api_{$endpoint}_{$user-\u003eid}_\" . date('YmdH'); // Hourly bucket\n\n        return probability($probability, $key);\n    }\n}\n```\n\n## 🧪 Testing\n\nThe library includes a comprehensive Pest test suite covering edge cases, statistical correctness, and deterministic behavior.\n\n```bash\n# Install dev dependencies\ncomposer install\n\n# Run tests\ncomposer test\n# or\n./vendor/bin/pest\n\n# Run with coverage (requires Xdebug or PCOV)\n./vendor/bin/pest --coverage\n```\n\nTest coverage includes:\n- Edge cases (0.0, 1.0, epsilon boundaries)\n- Input validation and error handling\n- Deterministic key behavior\n- Statistical correctness over large sample sizes\n- Hash collision handling\n- Type coercion\n\n## ⚡ Performance\n\nBenchmarks on PHP 8.4 (Apple M4):\n\n| Operation | Time per call | Ops/sec |\n|-----------|--------------|---------|\n| Random (no key) | ~0.14 μs | ~7.0M |\n| Deterministic (with key) | ~0.16 μs | ~6.2M |\n\n**Memory usage:** 0 bytes (no allocations)\n\nThe library is optimized for high-throughput scenarios:\n- Fast-path optimization for edge cases (0.0, 1.0)\n- Minimal function calls\n- No object instantiation\n- CRC32 is faster than other hash functions\n\nRun `php benchmark.php` to test performance on your hardware.\n\n## ❓ FAQ / Troubleshooting\n\n### Why do I get different results in different environments?\n\n**Q:** Same key returns different results on different servers.\n\n**A:** This is expected! CRC32 implementation is consistent, but you might be using different keys. Ensure you're using the exact same key string across environments.\n\n```php\n// ❌ This will differ between users\nprobability(0.5, $userId); // If $userId is different\n\n// ✅ This will be consistent for same user\nprobability(0.5, \"feature_x_user_{$userId}\");\n```\n\n### Why is my A/B test showing 52% instead of 50%?\n\n**Q:** I'm using `probability(0.5, $userId)` but getting uneven distribution.\n\n**A:** With small sample sizes, variance is normal. The distribution converges to 50% with larger samples (law of large numbers). For 100 users, expect 45-55%. For 10,000 users, expect 49-51%.\n\n### Can I use this for cryptographic purposes?\n\n**Q:** Is this secure for generating random tokens?\n\n**A:** **No!** This library is NOT cryptographically secure. CRC32 is predictable and `mt_rand()` is not suitable for security. Use `random_bytes()` or `random_int()` for security purposes.\n\n### How do I gradually increase rollout percentage?\n\n**Q:** I want to go from 10% to 50% to 100%.\n\n**A:** Just change the probability value in your code/config. Users in the 0-10% hash range stay enabled, users in 10-50% get added, etc.\n\n```php\n// Week 1: 10% rollout\nif (probability(0.1, \"feature_x_user_{$userId}\")) { ... }\n\n// Week 2: 50% rollout (includes original 10%)\nif (probability(0.5, \"feature_x_user_{$userId}\")) { ... }\n\n// Week 3: 100% rollout\nif (probability(1.0, \"feature_x_user_{$userId}\")) { ... }\n```\n\n### What about hash collisions?\n\n**Q:** Can different keys produce the same result?\n\n**A:** Yes, CRC32 has only 2³² (~4.3 billion) possible values. With many keys, collisions are possible but rare for typical use cases. For most applications this is acceptable. If you need collision-resistant hashing, fork and replace CRC32 with MD5 or SHA256.\n\n### Why not use a database for feature flags?\n\n**Q:** Isn't a feature flag service better?\n\n**A:** Depends on your needs:\n\n- **Use this library:** Simple rollouts, performance sampling, no persistence needed, minimal dependencies\n- **Use feature flag service:** Complex targeting, runtime changes, analytics, team collaboration\n\nThis library excels at simplicity and performance, not flexibility.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fantikirra%2Fprobability","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fantikirra%2Fprobability","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fantikirra%2Fprobability/lists"}