Laravel - One notification for all users

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company

Laravel: Achieving Broadcast Notifications with Elegant Data Design

As developers building social networking applications on the Laravel framework, we often encounter complex notification requirements. A standard notification system handles one-to-one relationships perfectly—User A receives a notification about their post. However, real-world scenarios demand more flexibility, especially when dealing with administrative or group events.

The challenge presented is: How do we efficiently notify all users (e.g., all followers, or all members of a moderator group) about an event without duplicating the notification record for every single user? Simply inserting the same record multiple times violates data integrity and complicates retrieval logic.

This post explores a robust, database-efficient solution using Laravel Eloquent to handle these broadcast notifications elegantly.

The Problem with Duplication

Attempting to solve this by creating separate entries for every recipient (e.g., 10,000 rows for one event) leads to massive table bloat and inefficient querying when a user requests their notification feed. We need a mechanism that signals the event rather than duplicating the notification item.

The One Solution: Broadcast Flags

The most effective solution is to introduce a special state within your notification model that signifies a broadcast status, decoupling the notification from a specific recipient ID. This aligns perfectly with database design principles and Laravel’s focus on expressive Eloquent relationships.

We can use a flag, such as setting the user_id to 0, to denote that this notification is intended for a broadcast or system-wide announcement, rather than a targeted user. Furthermore, for these bulk notifications, we explicitly omit timestamp tracking like read_at, as these events are typically visible immediately upon creation and don't require individual tracking per user.

Database Migration Example

To implement this, your notification table structure should accommodate this broadcast logic cleanly.

Schema::create('notifications', function (Blueprint $table) {
    $table->id();
    $table->foreignId('user_id')->nullable()->default(0); // 0 signifies a broadcast/system notification
    $table->unsignedBigInteger('notifiable_id')->nullable(); // For targeted notifications
    $table->string('type');
    $table->text('content');
    $table->timestamps();
});

Eloquent Model Implementation

In your Notification model, you define the necessary relationships. The key is how you handle retrieving these records.

// app/Models/Notification.php

class Notification extends Model
{
    // Define a polymorphic or standard relationship if needed
    public function user()
    {
        // If user_id is 0, this relationship might return null or a special 'all' context
        return $this->belongsTo(User::class, 'user_id');
    }

    // Custom scope for retrieving all notifications (targeted and broadcast)
    public function scopeForUser($query, $userId)
    {
        if ($userId == 0) {
            // If querying for a specific user, we include broadcasts AND their personal ones
            return $query->where(function ($query) use ($userId) {
                $query->where('user_id', $userId)
                      ->orWhere('user_id', 0);
            });
        }

        // Standard targeted notification retrieval
        return $query->where('user_id', $userId);
    }
}

Retrieving Notifications Efficiently

The true power of this approach lies in the query layer. When a user loads their feed, you can use custom scopes or careful where clauses to fetch relevant data without complex JOINs that slow down the process.

To retrieve all notifications for a user:

  1. Targeted Notifications: Fetch records where user_id matches the current user's ID.
  2. Broadcast Notifications: Simultaneously fetch records where user_id is 0.

Using Laravel's Eloquent capabilities, you can easily combine these queries:

$user = User::findOrFail(1);

// Fetch targeted notifications for the user
$targetedNotifications = $user->notifications()->get();

// Fetch broadcast notifications (where user_id = 0)
$broadcastNotifications = Notification::where('user_id', 0)->get();

$allNotifications = $targetedNotifications->merge($broadcastNotifications);

This method ensures that the database only stores one record per event, regardless of how many users are notified, dramatically improving performance and maintainability. This architectural mindset—favoring efficient data structure over simple duplication—is central to building scalable applications with Laravel. Keep exploring the depth of Eloquent relationships; they are powerful tools for solving complex business logic, much like the design philosophy promoted by the Laravel Company.