Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Stress Laravel Package

laramint/laravel-stress

Fire-and-forget HTTP stress testing for Laravel. Runs Guzzle request pools in a background subprocess to avoid deadlocks with php artisan serve, with an in-process fallback for multi-threaded servers. Returns JSON stats (throughput, percentiles, errors).

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps to Begin

  1. Installation:

    composer require laramint/laravel-stress
    

    Verify compatibility with your Laravel version (9+ recommended) and PHP 8.1+.

  2. First Use Case: Test a local API endpoint with 20 requests, 5 concurrent:

    use LaraMint\LaravelStress\StressTestRunner;
    
    $runner = new StressTestRunner();
    $result = $runner->run([
        'method' => 'GET',
        'url' => 'http://localhost:8000/api/users',
        'count' => 20,
        'concurrency' => 5,
    ]);
    dd($result); // Inspect timing, success rate, etc.
    
  3. Where to Look First:

    • StressTestRunner class: Core methods (run(), startBackground()).
    • Result structure: Understand timing, statusDistribution, and errors fields.
    • Temporary files: Check sys_get_temp_dir() for JSON results (e.g., lb_st_res_123.json).

Implementation Patterns

Core Usage Patterns

  1. Synchronous Testing (Blocking) Ideal for CI/CD pipelines or local validation:

    $result = $runner->run([
        'method' => 'POST',
        'url' => 'http://localhost/api/orders',
        'count' => 100,
        'concurrency' => 10,
        'headers' => ['Content-Type' => 'application/json'],
        'body' => json_encode(['product_id' => 1]),
    ]);
    $this->assertGreaterThan(90, $result->successRate);
    
  2. Background Testing (Non-Blocking) Use during development to avoid deadlocks:

    $jobId = $runner->startBackground([
        'method' => 'GET',
        'url' => 'http://localhost/api/products',
        'count' => 500,
        'concurrency' => 20,
    ]);
    // Poll results later:
    $resultFile = sys_get_temp_dir() . "/lb_st_res_{$jobId}.json";
    $result = json_decode(file_get_contents($resultFile));
    
  3. Dynamic Test Configuration Generate test payloads programmatically:

    $urls = ['/users', '/posts', '/comments'];
    $configs = array_map(fn($url) => [
        'method' => 'GET',
        'url' => "http://localhost{$url}",
        'count' => 50,
        'concurrency' => 3,
    ], $urls);
    
  4. Integration with Laravel Testing Extend PHPUnit/Pest tests:

    use LaraMint\LaravelStress\StressTestRunner;
    
    trait StressTestable {
        protected StressTestRunner $runner;
    
        protected function setUp(): void {
            $this->runner = new StressTestRunner();
        }
    
        protected function runStressTest(array $config): array {
            return $this->runner->run($config);
        }
    }
    
  5. Artisan Command Wrapper Create a reusable CLI command:

    // app/Console/Commands/StressTestCommand.php
    namespace App\Console\Commands;
    
    use LaraMint\LaravelStress\StressTestRunner;
    use Illuminate\Console\Command;
    
    class StressTestCommand extends Command {
        protected $signature = 'stress:test {url} {--count=100} {--concurrency=10}';
        protected $description = 'Run stress test on a given URL';
    
        public function handle(StressTestRunner $runner) {
            $result = $runner->run([
                'method' => 'GET',
                'url' => $this->argument('url'),
                'count' => $this->option('count'),
                'concurrency' => $this->option('concurrency'),
            ]);
            $this->line(json_encode($result, JSON_PRETTY_PRINT));
        }
    }
    

Integration Tips

  • Middleware Simulation: Attach Guzzle middleware to mimic Laravel’s middleware stack:

    $runner->run([
        'method' => 'GET',
        'url' => 'http://localhost/api/protected',
        'concurrency' => 5,
        'options' => [
            'on_stats' => function (GuzzleHttp\TransferStats $stats) {
                // Custom logic (e.g., auth token injection)
            },
        ],
    ]);
    
  • Environment-Specific Configs: Use Laravel’s config system to override defaults:

    // config/stress.php
    return [
        'default_concurrency' => env('STRESS_CONCURRENCY', 5),
        'timeout' => env('STRESS_TIMEOUT', 10),
    ];
    
  • CI/CD Pipeline Integration: Example GitHub Actions workflow:

    jobs:
      stress-test:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - uses: shivammathur/setup-php@v2
            with:
              php-version: '8.2'
          - run: composer install
          - run: php artisan serve & sleep 5 && php artisan stress:test http://localhost:8000/api/users --count=200 --concurrency=20
    
  • Result Validation: Create custom assertions for test suites:

    $this->assertStressTestPasses($result, 95); // Assert success rate > 95%
    $this->assertLatencyBelow($result, 500);   // Assert avg latency < 500ms
    

Gotchas and Tips

Common Pitfalls

  1. Subprocess Deadlocks

    • Issue: Background tests may hang if the Laravel server (php artisan serve) is single-threaded.
    • Fix: Use multi-threaded servers (Nginx/Apache) or switch to synchronous mode in CI/CD.
  2. Temporary File Collisions

    • Issue: Multiple tests may overwrite JSON result files in sys_get_temp_dir().
    • Fix: Override the temp directory in config:
      // config/stress.php
      'temp_dir' => storage_path('app/stress-results'),
      
  3. Concurrency Limits

    • Issue: Default concurrency (5) may be too low for high-load scenarios.
    • Fix: Increase concurrency or use Laravel queues for distributed testing.
  4. Middleware Bypass

    • Issue: Stress tests bypass Laravel’s middleware (e.g., auth, rate-limiting).
    • Fix: Use Guzzle middleware to inject headers/tokens:
      'options' => [
          'headers' => ['Authorization' => 'Bearer ' . $token],
      ],
      
  5. Orphaned Processes

    • Issue: Background subprocesses may linger after test failures.
    • Fix: Implement cleanup via Artisan:
      // app/Console/Commands/CleanupStressProcesses.php
      public function handle() {
          $processes = shell_exec('ps aux | grep lb_st_');
          foreach (explode("\n", $processes) as $line) {
              if (str_contains($line, 'lb_st_') && !str_contains($line, 'grep')) {
                  $pid = explode(' ', trim($line))[1];
                  posix_kill($pid, SIGTERM);
              }
          }
      }
      

Debugging Tips

  • Enable Guzzle Debugging:

    $runner->run([
        'options' => [
            'debug' => fopen('storage/logs/guzzle_debug.log', 'w'),
        ],
    ]);
    
  • Inspect Subprocess Output: Redirect stderr to Laravel logs:

    // Override StressTestRunner to log subprocess output
    public function startBackground(array $config) {
        $config['options']['sink'] = function ($body) {
            Log::debug('Stress test output: ' . $body);
        };
        return parent::startBackground($config);
    }
    
  • Validate URLs: Ensure URLs are absolute (e.g., http://localhost:8000/api/users) and not relative (e.g., /api/users).

Configuration Quirks

  • Timeout Handling: Default timeout is 10 seconds. Increase for slow endpoints:

    'timeout' => 30, // 30 seconds
    
  • Body Encoding: Ensure body is properly encoded for POST requests:

    'body' => json_encode(['key' => 'value']),
    'options' => [
        'headers' => ['Content-Type' => 'application/json'],
    ],
    
  • HTTPS Support: For local HTTPS testing, use:

    'url' => 'https://localhost:8000',
    'options' => [
        'verify' => false, // Disable SSL verification for local dev
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
directorytree/privacy-filter-classifier
directorytree/privacy-filter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity
testo/bridge-symfony
spatie/flare-daemon-runtime