Meet Doppar: Laravel's Leaner, Faster Cousin

Or: What happens when “fast enough” isn’t

318 requests per second. 1,000 concurrent users. Zero dropped connections.

Those are stress test results from Doppar, a PHP framework you probably haven’t heard of. Laravel optimizes for developer experience. Symfony optimizes for enterprise stability. Doppar optimizes for raw speed — and lets you handle the rest.

Who this is for: You’ve profiled your PHP application, optimized your queries, added caching, and still need more throughput. You’re comfortable writing integrations that would be a composer require elsewhere. You want Laravel-like syntax without Laravel-like overhead.


What Is Doppar?

Permalink to "What Is Doppar?"

Doppar is a high-performance, minimalist PHP framework that launched version 3.x in late 2025. It’s built on three principles:

  1. Zero external dependencies for core features
  2. Intelligent memoization of repeated executions
  3. Attribute-first configuration
composer create-project doppar/doppar my-app
cd my-app
php pool server:start

Your first route:

// app/Http/Controllers/HelloController.php
#[Mapper(prefix: 'api')]
class HelloController extends Controller
{
    #[Route(uri: 'hello/{name}', methods: ['GET'])]
    public function greet(string $name): Response
    {
        return response()->json(['message' => "Hello, {$name}!"]);
    }
}

Requirements: PHP 8.3+ and Composer.


History & Philosophy

Permalink to "History & Philosophy"

Doppar was created by techmahedy, a developer who wanted Laravel’s elegant syntax without the overhead. The 3.x release in late 2025 marked its transition from experiment to usable framework. It draws a parallel to Laravel’s own origin story — Symfony existed and was robust, yet Laravel found its voice by offering something different.

The philosophy is simple:

“Need a feature? Install and use it. Don’t need it? Keep your application as simple and clean as possible.”

Doppar isn’t trying to replace Laravel or Symfony. It’s an alternative for developers who’ve squeezed every optimization out of their current stack and still need more.


Why Is It Fast?

Permalink to "Why Is It Fast?"

Three techniques make Doppar faster than typical PHP frameworks:

1. Intelligent Memoization

Permalink to "1. Intelligent Memoization"

Repeated executions are cached automatically. Configuration parsing, service resolution, route matching — anything that runs more than once gets memoized without manual intervention.

2. Zero-Dependency Core

Permalink to "2. Zero-Dependency Core"

The ORM, validation, WebSocket server, and scheduler are built into the core. No Doctrine. No external queue packages. No third-party HTTP clients for internal operations. Fewer packages means fewer autoload calls and less initialization overhead.

3. Minimal Boot Tax

Permalink to "3. Minimal Boot Tax"

Heavy frameworks pay a “boot tax” — the time spent bootstrapping before handling a single request. Doppar minimizes this by lazy-loading services and avoiding deep dependency chains. In worker mode, the application boots once and stays in memory.

The result: benchmarks show roughly 7-8x higher throughput than typical PHP frameworks under comparable conditions.

Benchmark methodology: The 318 req/s figure comes from Doppar’s stress test documentation using wrk with 1,000 concurrent connections over 30 seconds. The “7-8x” comparison is against a default Laravel installation on the same hardware. These are vendor-provided numbers — independent benchmarks are welcome.

Deployment model: Doppar runs in two modes. Traditional PHP-FPM works but loses the performance benefits — each request bootstraps fresh. Worker mode (php pool server:start) keeps the application in memory between requests, similar to Swoole or RoadRunner. (For background on these async runtimes, see Async PHP in Production.) The benchmarks assume worker mode. If your hosting requires PHP-FPM (shared hosting, some PaaS), the speed advantage shrinks significantly.


Unique Features

Permalink to "Unique Features"

Before comparing individual modules, here’s what Doppar offers that Laravel and Symfony don’t have built-in:

Airbend: Native WebSockets

Permalink to "Airbend: Native WebSockets"

Most PHP frameworks treat WebSockets as an afterthought — use Pusher, run a Node.js server, or configure Ratchet. Symfony has Mercure, which solves real-time elegantly but requires a separate hub service (written in Go). Laravel offers Broadcasting with Pusher or a self-hosted solution via Laravel Reverb.

Doppar takes a different approach with Airbend — a native WebSocket component that runs in the same PHP process:

use Doppar\Airbend\Broadcast;

Broadcast::channel('orders')
    ->event('order.created')
    ->data(['order_id' => $order->id])
    ->send();

// Channel authorization
Broadcast::channel('orders.{id}', function ($user, $id) {
    return $user->orders()->where('id', $id)->exists();
});

No external services. No separate server process. The trade-off: Mercure is battle-tested and scales horizontally; Airbend is newer and ties your WebSockets to your PHP worker’s lifecycle.

Dual-Mode Task Scheduler

Permalink to "Dual-Mode Task Scheduler"

Standard cron-triggered mode:

* * * * * cd /path/to/project && php pool schedule:run

Or daemon mode for sub-second precision:

php pool schedule:daemon

Daemon mode runs continuously, checking tasks multiple times per second — no Supervisor configuration required.

Schedule::call(fn() => $this->pingHealthCheck())
    ->everySecond();

Schedule::command('reports:generate')
    ->dailyAt('02:00')
    ->runInBackground();

Automatic Transactions via Attributes

Permalink to "Automatic Transactions via Attributes"
use Phaseolies\Utilities\Attributes\Transaction;

#[Transaction]
public function transferFunds(Account $from, Account $to, float $amount): void
{
    $from->decrement('balance', $amount);
    $to->increment('balance', $amount);
    // Commits on success, rolls back on exception
}

Optional AI Integration

Permalink to "Optional AI Integration"

Doppar includes an AI wrapper — not a core dependency, but available if you need it:

use Doppar\AI\Agent;

$response = Agent::make()
    ->model('gpt-4')
    ->prompt('Summarize this order')
    ->context(['order' => $order->toArray()])
    ->send();

Supported providers: OpenAI (GPT-3.5/4), Anthropic (Claude), and local models via TransformersPHP. You configure API keys in .env — no AI calls happen unless you explicitly use the Agent class.


Module Comparisons

Permalink to "Module Comparisons"

Routing

Permalink to "Routing"

Doppar — Attributes with inline rate limiting:

#[Mapper(prefix: 'api/users', middleware: ['auth'])]
class UserController extends Controller
{
    #[Route(uri: '{id}', methods: ['GET'], name: 'users.show')]
    public function show(string $id): Response
    {
        return response()->json(User::find($id));
    }

    #[Route(uri: '', methods: ['POST'], rateLimit: 10, rateLimitDecay: 1)]
    public function store(Request $request): Response
    {
        // Limited to 10 requests per minute
    }
}

Symfony — Native attributes, rate limiting via separate bundle:

#[Route('/api/users', name: 'users_')]
class UserController extends AbstractController
{
    #[Route('/{id}', name: 'show', methods: ['GET'])]
    public function show(int $id): Response
    {
        return $this->json($this->userRepository->find($id));
    }
}

Laravel — File-based routing (attributes via package):

// routes/api.php
Route::middleware(['auth:sanctum'])->prefix('api/users')->group(function () {
    Route::get('{id}', [UserController::class, 'show']);
    Route::post('', [UserController::class, 'store'])->middleware('throttle:10,1');
});

Dependency Injection

Permalink to "Dependency Injection"

Doppar — Explicit binding at parameter level:

class OrderController extends Controller
{
    #[Route(uri: 'orders', methods: ['POST'])]
    public function store(
        #[Bind(StripeGateway::class)] PaymentGatewayInterface $gateway,
        Request $request
    ): Response {
        // $gateway is StripeGateway
    }
}

Symfony — Config file or #[Autowire]:

// config/services.yaml
services:
    App\Payment\PaymentGatewayInterface:
        class: App\Payment\StripeGateway

Laravel — Service provider:

// AppServiceProvider.php
$this->app->bind(PaymentGatewayInterface::class, StripeGateway::class);

Doppar’s approach makes the binding visible at the call site. Trade-off: more verbose when you want framework-wide defaults.

ORM

Permalink to "ORM"

Doppar — Eloquent-style API, zero dependencies:

$users = User::where('active', true)
    ->whereBetween('created_at', [$start, $end])
    ->orderBy('name')
    ->limit(10)
    ->get();

// Batch insert with chunking
User::saveMany($records, 1000);

// Memory-efficient iteration
foreach (User::where('active', true)->cursor() as $user) {
    // One record at a time
}

Symfony (Doctrine) — QueryBuilder:

$users = $this->userRepository->createQueryBuilder('u')
    ->where('u.active = :active')
    ->andWhere('u.createdAt BETWEEN :start AND :end')
    ->orderBy('u.name')
    ->setMaxResults(10)
    ->setParameters(['active' => true, 'start' => $start, 'end' => $end])
    ->getQuery()
    ->getResult();

Laravel (Eloquent) — Nearly identical to Doppar:

$users = User::where('active', true)
    ->whereBetween('created_at', [$start, $end])
    ->orderBy('name')
    ->limit(10)
    ->get();

Doppar’s ORM syntax mirrors Eloquent — familiar if you’re coming from Laravel. The difference: no external package, built into core.

Validation

Permalink to "Validation"

Doppar:

$validated = $request->sanitize([
    'name' => 'required|min:2|max:100',
    'email' => 'required|email|unique:users',
    'age' => 'required|int|between:18,120',
]);

Symfony:

class UserDto
{
    #[Assert\NotBlank]
    #[Assert\Length(min: 2, max: 100)]
    public string $name;

    #[Assert\Email]
    public string $email;
}

$errors = $validator->validate($dto);

Laravel:

$validated = $request->validate([
    'name' => 'required|min:2|max:100',
    'email' => 'required|email|unique:users',
]);

Doppar and Laravel are nearly identical. Symfony’s DTO approach offers better type safety for complex domains but requires more code.


Community & Ecosystem

Permalink to "Community & Ecosystem"
Metric Doppar Laravel Symfony
GitHub Stars ~200* 78k+ 30k+
First Release 2024 2011 2005
Packagist Downloads <10k* 300M+ 500M+
Discord/Community Small* 120k+ Large

*Doppar figures are estimates as of January 2026. Check GitHub and Packagist for current numbers.

Doppar’s ecosystem is young. You’ll write integrations that would be a composer require in Laravel or Symfony. The trade-off for performance is doing more yourself.


Should You Use Doppar?

Permalink to "Should You Use Doppar?"

The honest answer: probably not — yet.

Doppar makes sense in a narrow scenario: you’re building high-throughput APIs, you’ve profiled your Laravel or Symfony app to death, and you’re still bottlenecked by framework overhead. You’re comfortable writing integrations yourself, and you don’t need PostgreSQL (MySQL and SQLite only). If that’s you, Doppar is worth a serious look.

For everyone else, the trade-offs are hard to justify. Laravel has thousands of packages and a massive community. Symfony powers enterprise systems with battle-tested stability. Both have weathered a decade of production edge cases, security audits, CVE tracking, and responsible disclosure processes. Doppar hasn’t seen that volume of real-world usage yet — some documentation pages still return 404, and the queue system isn’t fully documented.

There are also risks to consider. Doppar has a single primary maintainer. If techmahedy steps away, the project’s future is uncertain. The framework is young — expect breaking changes between minor versions as APIs mature. And hiring developers with Doppar experience will be significantly harder than Laravel or Symfony.

If you need raw performance but don’t want to abandon the ecosystem, consider Swoole or RoadRunner on top of Laravel or Symfony. You’ll get most of the performance gains while keeping access to packages, documentation, and community support.

For a deeper Laravel vs Symfony comparison without the performance angle, see Laravel vs Symfony 2025: When to Use Which.


Doppar isn’t a Laravel replacement. It’s a specialized tool for a specific problem.

My take: Doppar is an interesting project worth watching. The philosophy is sound — Laravel-like ergonomics without the overhead — and the native WebSocket integration is genuinely compelling. But I’m skeptical about production use. The gap to Laravel isn’t wide enough to justify the ecosystem trade-offs for most teams. If you need raw performance, Swoole or RoadRunner on top of Laravel/Symfony might give you 80% of the gains without abandoning the ecosystem. Doppar feels like a framework for a very specific niche: high-throughput APIs where every millisecond matters and you’re comfortable building everything yourself.

That said, competition is healthy. If Doppar pushes Laravel and Symfony to care more about performance, everyone wins. I’ll be keeping an eye on it — but my production apps stay on Symfony for now.

The documentation is at doppar.com. The framework is MIT-licensed on GitHub. PHP 8.3+, Composer, and a willingness to trade convenience for microseconds.