diff --git a/.jules/bolt.md b/.jules/bolt.md new file mode 100644 index 0000000000..2e112a6d91 --- /dev/null +++ b/.jules/bolt.md @@ -0,0 +1,3 @@ +## 2024-08-24 - Eloquent Memory Exhaustion Anti-pattern +**Learning:** Found multiple instances where the codebase fetches entire tables into memory using `Model::all()` before filtering or grabbing the first record (e.g., `Model::all()->first()` or `Team::all()->filter(...)`). This creates severe memory bottlenecks and N+1 query issues on large tables. +**Action:** Always scan for `::all()->` usages and push the constraints down to the database level using `::first()`, `::where()`, or relationship queries like `::doesntHave()`. diff --git a/backend/app/Console/Commands/CleanupStuckedResources.php b/backend/app/Console/Commands/CleanupStuckedResources.php index 165a3ae219..2b87ed34c4 100644 --- a/backend/app/Console/Commands/CleanupStuckedResources.php +++ b/backend/app/Console/Commands/CleanupStuckedResources.php @@ -39,9 +39,9 @@ public function handle() private function cleanup_stucked_resources() { try { - $teams = Team::all()->filter(function ($team) { - return $team->members()->count() === 0 && $team->servers()->count() === 0; - }); + // Bolt: Optimize finding stuck teams by executing a single database query + // instead of fetching all teams and running N+1 queries for members and servers. + $teams = Team::doesntHave('members')->doesntHave('servers')->get(); foreach ($teams as $team) { $team->delete(); } @@ -263,7 +263,8 @@ private function cleanup_stucked_resources() echo "Error in application: {$e->getMessage()}\n"; } try { - $postgresqls = StandalonePostgresql::all()->where('id', '!=', 0); + // Bolt: Filter id != 0 at the database level instead of fetching everything into memory + $postgresqls = StandalonePostgresql::where('id', '!=', 0)->get(); foreach ($postgresqls as $postgresql) { if (! data_get($postgresql, 'environment')) { echo 'Postgresql without environment: '.$postgresql->name.'\n'; diff --git a/backend/app/Console/Commands/Emails.php b/backend/app/Console/Commands/Emails.php index 43ba06804c..8677d82862 100644 --- a/backend/app/Console/Commands/Emails.php +++ b/backend/app/Console/Commands/Emails.php @@ -128,13 +128,15 @@ public function handle() } break; case 'application-deployment-success': - $application = Application::all()->first(); + // Bolt: Optimize fetching the first record directly from DB instead of fetching all records into memory + $application = Application::first(); $this->mail = (new DeploymentSuccess($application, 'test'))->toMail(); $this->sendEmail(); break; case 'application-deployment-failed': - $application = Application::all()->first(); - $preview = ApplicationPreview::all()->first(); + // Bolt: Optimize fetching the first record directly from DB instead of fetching all records into memory + $application = Application::first(); + $preview = ApplicationPreview::first(); if (! $preview) { $preview = ApplicationPreview::create([ 'application_id' => $application->id, @@ -149,13 +151,15 @@ public function handle() $this->sendEmail(); break; case 'application-status-changed': - $application = Application::all()->first(); + // Bolt: Optimize fetching the first record directly from DB instead of fetching all records into memory + $application = Application::first(); $this->mail = (new StatusChanged($application))->toMail(); $this->sendEmail(); break; case 'backup-failed': - $backup = ScheduledDatabaseBackup::all()->first(); - $db = StandalonePostgresql::all()->first(); + // Bolt: Optimize fetching the first record directly from DB instead of fetching all records into memory + $backup = ScheduledDatabaseBackup::first(); + $db = StandalonePostgresql::first(); if (! $backup) { $backup = ScheduledDatabaseBackup::create([ 'enabled' => true, @@ -171,8 +175,9 @@ public function handle() $this->sendEmail(); break; case 'backup-success': - $backup = ScheduledDatabaseBackup::all()->first(); - $db = StandalonePostgresql::all()->first(); + // Bolt: Optimize fetching the first record directly from DB instead of fetching all records into memory + $backup = ScheduledDatabaseBackup::first(); + $db = StandalonePostgresql::first(); if (! $backup) { $backup = ScheduledDatabaseBackup::create([ 'enabled' => true,