--- title: Parallel Data Loading in Model Hooks impact: CRITICAL impactDescription: 2-10× improvement tags: routes, data-fetching, parallelization, performance --- ## Parallel Data Loading in Model Hooks When fetching multiple independent data sources in a route's model hook, use `Promise.all()` or RSVP.hash() to load them in parallel instead of sequentially. `export default` in these route examples is intentional because route modules are discovered through resolver lookup. In hybrid `.gjs`/`.hbs` codebases, keep route defaults and add named exports only when you need explicit imports elsewhere. **Incorrect (sequential loading, 3 round trips):** ```javascript // app/routes/dashboard.js import Route from '@ember/routing/route'; import { service } from '@ember/service'; export default class DashboardRoute extends Route { @service store; async model() { const user = await this.store.request({ url: '/users/me' }); const posts = await this.store.request({ url: '/posts?recent=true' }); const notifications = await this.store.request({ url: '/notifications?unread=true' }); return { user, posts, notifications }; } } ``` **Correct (parallel loading, 1 round trip):** ```javascript // app/routes/dashboard.js import Route from '@ember/routing/route'; import { service } from '@ember/service'; import { hash } from 'rsvp'; export default class DashboardRoute extends Route { @service store; model() { return hash({ user: this.store.request({ url: '/users/me' }), posts: this.store.request({ url: '/posts?recent=true' }), notifications: this.store.request({ url: '/notifications?unread=true' }), }); } } ``` Using `hash()` from RSVP allows Ember to resolve all promises concurrently, significantly reducing load time.