Master Laravel database notifications to store and retrieve user alerts efficiently. Learn how to implement this powerful feature in your PHP application.
Last month, I was debugging an issue where users kept missing critical updates because we relied entirely on email notifications. I realized that if a user didn't check their inbox, the alerts effectively didn't exist, so I pivoted our design to include persistent laravel database notifications directly within the dashboard.
If you’re building a feature-rich application, you need a way to track user activity, and storing these alerts in your laravel database is the most reliable way to ensure nothing gets lost.
Before you can send your first alert, you need a place to store them. Laravel makes this incredibly easy with a built-in migration command. Run this in your terminal:
Bashphp artisan notifications:table php artisan migrate
This creates a notifications table. It’s a polymorphic table, meaning it can store notifications for any model (usually your User model) without needing a separate table for every alert type. It’s elegant, clean, and saves you from writing custom schema migrations.
To generate a notification, use the artisan command:
Bashphp artisan make:notification OrderShipped
Open the newly created file in app/Notifications. You'll see a via method. This is where you tell Laravel how to deliver the notification. For our purpose, we want to return ['database'].
PHPpublic function via($notifiable) { return ['database']; }
Now, define the toArray method. This is the data that gets serialized into the data column of your notifications table.
PHPpublic function toArray($notifiable) { return [ 'order_id' => $this->order->id, 'message' => 'Your order #' . $this->order->id . ' has shipped!', ]; }
If you are just getting started with multi-channel alerts, check out my previous post on Laravel Notifications: A Beginner’s Guide to Multi-Channel Alerts to see how you can extend this to email or Slack later.
Once you send a notification, it sits in your database waiting to be fetched. You can access these via the notifications relationship on your model.
In your controller or view, you can pull them like this:
PHP$user = auth()->user(); foreach ($user->unreadNotifications as $notification) { echo $notification->data['message']; }
I once tried to manually query the table using DB::table('notifications')->where(...). Don't do that. The Notifiable trait on your User model provides all the helper methods you need, like markAsRead() or unreadNotifications, which are much safer. If you're doing complex operations, always remember that Laravel database transactions: Mastering atomic operations with DB::transaction are your best friend to keep data consistent.
When I first started, I thought about building a custom Alerts table. It seemed easy until I had to handle read/unread states, timestamps, and polymorphic relationships. By sticking to the framework’s native implementation, I saved about two days of development time.
However, there is one catch: the data column is a JSON field. While this is flexible, it means you can't easily index specific fields inside the JSON for complex filtering. If you’re building a massive notification center with millions of rows, you might eventually need to denormalize your schema. For 99% of projects, though, the standard setup is more than enough.
$user->unreadNotifications->markAsRead() is the standard way to handle this.I'm still tinkering with how to handle notification expiration—right now, I just run a scheduled task to delete notifications older than 30 days. It keeps the table lean and ensures the app stays fast. If you find yourself needing to automate parts of this process, look into Mastering Laravel Observers: A Beginner’s Guide to Automation to trigger alerts whenever a model changes.
What’s your biggest struggle with user alerts? Are you worried about database bloat or just getting the UI right? Start simple, get the data flowing, and iterate from there.
Laravel pagination is essential for high-performance apps. Learn how to use Eloquent pagination to manage large datasets and keep your database queries fast.