- Makers Make by SaaSykit
- Posts
- 700+ SaaSykit Customers! Laravel 12.32-33, Laravel Architecture Basics Explained, From 400 Queries to 4, Spotting billion-dollar Markets Before They Look Big & more
700+ SaaSykit Customers! Laravel 12.32-33, Laravel Architecture Basics Explained, From 400 Queries to 4, Spotting billion-dollar Markets Before They Look Big & more
Hey Makers 👋
We just hit a big milestone — 700+ customers using SaaSykit! 🎉 Huge thanks to everyone who’s been part of the journey so far. It’s wild seeing so many makers building cool apps with it.

Meanwhile, Laravel dropped versions 12.32 and 12.33, packed with some neat little features and improvements that make coding life smoother. 🚀
If you’ve been sitting on that SaaS idea for a while, now’s the time — grab your SaaSykit license and start building your dream app today. 💡
Let’s dive in and check out what’s new! 👇
Laravel 12.32-33 updates
Stringable::doesntContain()
Method
A newdoesntContain()
method has been added toStringable
, providing symmetry withcontains()
.
You can now easily check whether a string does not include a given substring:
$url = str('laravel-news.com');
$url->doesntContain('laravel'); // false
$url->doesntContain('NEWS'); // true
$url->doesntContain('NEWS', ignoreCase: true); // false
This makes Str
and Stringable
behave consistently when handling substring checks.
HTTP Client: Merging URL Parameters
withUrlParameters()
now merges parameters instead of replacing them.
This makes working with reusable HTTP clients more predictable.
Http::macro('service', fn () =>
Http::baseUrl('https://api.example.com')
->withUrlParameters(['version' => 'v1', 'tenant' => 'acme'])
);
// Before (pre-12.33): replaced parameters
Http::service()->withUrlParameters(['tenant' => 'beta']);
// => ['tenant' => 'beta']
// Now (12.33+): merges them
Http::service()->withUrlParameters(['tenant' => 'beta']);
// => ['version' => 'v1', 'tenant' => 'beta']
Clearer BroadcastManager Errors
Broadcast driver error messages are now more descriptive when initialization fails.
// Old message:
TypeError: Pusher\Pusher::__construct(): Argument #3 ($app_id) must be of type string, null given
// New message:
BroadcastException: Failed to create broadcaster for connection "my-connection" with error:
Pusher\Pusher::__construct(): Argument #3 ($app_id) must be of type string, null given
HTTP Batch Requests
You can now handle multiple concurrent HTTP requests using the newHttp::batch()
feature.
use Illuminate\Http\Client\Batch;
$responses = Http::batch(fn (Batch $batch) => [
$batch->as('first')->get('https://example.com/one'),
$batch->as('second')->get('https://example.com/two'),
])->then(fn ($batch, $results) => Log::info('Batch completed'))
->catch(fn ($batch, $key, $error) => report($error))
->send();
// You can track progress, inspect failures, and access helpful batch statistics:
$batch->totalRequests;
$batch->failedRequests;
$batch->hasFailures(); // bool
afterRollback()
Transaction Hook
A newafterRollback()
callback has been added to database transactions, complementingafterCommit()
.
DB::transaction(function () {
DB::afterCommit(fn () => Log::info('Transaction committed'));
DB::afterRollback(fn () => Log::warning('Transaction rolled back'));
// Perform database operations...
});
Batch Job Failure Callbacks
PendingBatch::allowFailures()
now supports callbacks.
You can define custom logic when a job within a batch fails:
$batch->allowFailures(function ($batch, $exception) {
Log::error("Job failed in batch {$batch->id}: {$exception->getMessage()}");
});
From the Community
Your dashboard is making over 400 queries, but the fix is simpler than you think. What if I told you that a few strategic changes could reduce those queries to just 4 and slash your response time from 180ms to 40ms?
In this episode of Laravel In Practice, I show you how to eliminate N+1 queries and add strategic database indexes without breaking your clean architecture. You'll learn to fix the top customers method that was generating hundreds of queries using loadMissing()
and lookup tables, add composite indexes to frequently queried columns like status and user_id, and use EXPLAIN query plans to verify your optimizations are actually working.
When feature testing a Laravel application, Laravel provides useful tools for database testing, like refreshing the database, factories, seeders, and database assertions. In a modern Laravel application, a Pest test using database refreshing might look like the following.
DTOs (Data Transfer Objects) aren't mentioned anywhere in the Laravel docs, but some devs use them heavily in their applications, whereas other devs never use them at all.
In the latest episode of the No Compromises podcast, we weigh the pros and cons of DTOs in everyday Laravel apps, comparing them to form requests, PHPDoc-typed arrays, and service-layer boundaries. We also share one area where we feel DTOs truly shine.
I'm currently working on a project that is command line only, synchronising tens of thousands of products in one go. While everything worked great in testing, and even a test API account, large scale imports of data rarely go quite according to plan.
In Laravel, a model symbolizes your application’s data structure and interacts with the database via Eloquent ORM, simplifying database operations with an ActiveRecord implementation, as demonstrated in creating a simple User model.
Migrating from MySQL to Postgres is not an easy feat in general; there are numerous packages & scripts to accomplish this, like Pgloader and Nmig.
For us, the best way to do this was using Laravel's query builder, since it is agnostic to the database layer and allows us to transform any data as needed in a language we know (PHP) and a framework we know and love.
All about SaaS
Remember when everyone said 2025 would be “the year of AI agents”? Well, we’re living it—and the hangover is starting to hit.
The tech world moved at breakneck speed from NFTs to the metaverse to generative AI, and now we’ve landed squarely in the era of agentic AI.
Hey, Sahil here — Welcome back to Venture Curator, where we explore how top investors think, how real founders build, and the strategies shaping tomorrow’s companies. Here’s today at a glance -
Elad Gil’s framework for spotting billion-dollar markets before they look big.
Do early-stage startups need a financial model for fundraising?
Validating without launching by Nikita Bier.
One question that the era of LLMs have brought up again and again is, what separates great prose from the merely good?
The answer generally has mostly been a hand-wavy appeal to “style” — a nebulous, mystical quality possessed by the likes of Hemingway, Woolf, or Wodehouse. Like the judge said about pornography, we know it when we see it. We can identify it, we can even imitate it. But can we measure it? Can we build a production function for it?
For decades, startups have followed the same playbook. They raised capital, hired fast, and scaled headcount as a proxy for momentum. Founders were pressured to build out entire departments, add layers of management, and expand their teams aggressively with each new funding round. Growth was synonymous with bodies on payroll.
Throughout my career, I have had the pleasure (and sometimes the pain) of working with various programming languages and paradigms. And recently, like everyone else, I have been leveraging large language models (LLMs), and user interfaces for them like GitHub Copilot, Cursor, Claude Code, …, for increasing my output. Yet, I get skeptical when I read claims like “English will be the only programming language you’ll ever need”. What this really means, especially the “ever” part, is: if AI can translate our English descriptions into working code, do we still need programming languages at all?
Videos
Keep building, keep rocking! 🤘