Your addon's data layer works just like a standard Laravel app, namespaced under the addon. Eloquent models go in the Models/ directory under Addons\YourAddon\Models, with an explicit $table (use a table name prefixed with your addon), $fillable, and $casts. Models support everything Laravel offers: relationships to core models like App\Models\User, query scopes, modern Attribute accessors/mutators, and model events in boot() — which is also a good place to fire custom hooks (e.g. via run_hook_in_background()) so other addons can react.
Migrations live in Database/Migrations/ and run automatically during addon installation; manually you use php artisan module:migrate YourAddon (plus module:migrate-rollback, module:migrate-reset, module:seed). The safe pattern is to guard every migration with Schema::hasTable() / Schema::hasColumn() checks so reinstallation doesn't fail — this also applies when adding columns to core tables like users. Seeders go in Database/Seeders/ with a main YourAddonDatabaseSeeder calling child seeders; use firstOrCreate() so seeding is idempotent. For complex setup or raw inserts, versioned SQL files in Settings/install/ (v1.0.sql, v1.1.sql) execute in version order during install/update.
Performance basics still apply: index frequently queried columns, add composite indexes for common patterns, eager-load to avoid N+1 queries, process large datasets with chunk() or lazy(), and wrap multi-step writes (e.g. creating a batch and deducting credits) in DB::transaction().