๐งฉ What Happens When You Use Multiple Preload() Calls in GORM
In GORM, when you useย .Preload("Relation"), it automatically runs additional SQL queries to fetch related data and attach it to your mainโฆ

๐งฉ What Happens When You Use Multiple Preload() Calls in GORM
In GORM, when you use .Preload("Relation"), it automatically runs additional SQL queries to fetch related data and attach it to your main model.
For example:
db.Preload("Roles.Permissions").Find(&users)
generates something like:
SELECT * FROM usersSELECT * FROM roles WHERE user_id IN (...)SELECT * FROM permissions WHERE role_id IN (...)
Each .Preload() adds at least one extra SQL query, and if you chain multiple nested preloads (Preload("A.B.C")), the number of queries can grow rapidly.
โ ๏ธ The Performance Impact
1. More Queries โ Higher Latency
Each preload is equal to one extra round trip to the database. If you have many relationships (or a large dataset), youโre quickly sending dozens of SQL statements per request.
โก๏ธ Example:
If fetching 100 users with 3 preloads โ GORM might execute 4โ6 queries.
With nested preloads (e.g. Roles.Permissions.Actions), it could balloon to 10โ15 queries.
2. Bigger Memory Footprint
Each preload loads entire related tables into memory and builds the associations in Go. If the dataset is large, this means:
- High memory usage (Go heap)
- Increased GC pressure
- Slower JSON marshaling when returning API responses
3. Complex Joins / Duplicated Data
If you mix .Preload() with .Joins(), you can get large, repetitive result sets โ especially if you use Preload("Nested.Relations").
This causes unnecessary data duplication and slower queries due to large joins.
4. Difficult to Control Data Volume
Preload doesnโt support granular filters easily (e.g. โonly active rolesโ). You can pass conditions, but if you do this for multiple associations, the query logic becomes scattered and harder to maintain.
๐ Optimization Strategies
โ 1. Load Only What You Need
Avoid preloading all associations by default.
Instead, use Preload() conditionally or use lazy loading patterns.
Example:
if includeRoles {
db = db.Preload("Roles", "roles.status = ?", "active")
}
โ 2. Use Joins for Simple Relationships
If you only need fields from a related table (not nested data), use .Joins() instead of .Preload().
Example:
db.Joins("LEFT JOIN roles ON users.role_id = roles.id").Select("users.*, roles.name")
This executes a single SQL query, instead of one per relation.
โ 3. Use Manual Batching
Instead of fetching everything in one go, fetch in batches:
db.Limit(100).Find(&users)
and then separately preload needed associations for just those users.
โ 4. Cache Expensive Preload Results
If relationships rarely change, you can cache preloaded results (e.g. role-permission mapping) in Redis or memory and avoid repeated SQL lookups.
โ 5. Profile & Monitor
Use:
db = db.Debug()
to print queries and count how many are executed per request.
Or log slow queries via:
db.Logger = logger.Default.LogMode(logger.Info)
Also, tools like New Relic, Datadog, or Prometheus can help track slow SQL calls.
โก Summary
Issue: Too many DB round trips
Description: Each preload runs a new query
Solution: Minimize preloads, use joins
Issue: High memory usage
Description: GORM builds all relations in memory
Solution: Limit dataset, use selective preloads
Issue: Slow serialization
Description: Nested data takes time to encode
Solution: Use lightweight structs for API
Issue: Harder debugging
Description: Multiple hidden queries
Solution: Enable GORM debug logs
๐ Iโm excited to share the link to my book on Design Patterns โ a practical and developer-friendly guide that distills complex patterns into real-world examples. Whether youโre just getting started or brushing up on your software design skills, I hope you find it insightful and useful.
๐ Check it out here: [Software Design Patterns for Java Developers] ๐ฌ Iโd love to hear your feedback, and feel free to share it with fellow devs who might benefit!
๋ฉํ๋ฐ์ดํฐ
- post_id
- 4e67ab52a7fe
- slug
- what-happens-when-you-use-multiple-preload-calls-in-gorm-4e67ab52a7fe
- url
- https://medium.com/codex/what-happens-when-you-use-multiple-preload-calls-in-gorm-4e67ab52a7fe
- canonical_url
- https://medium.com/codex/what-happens-when-you-use-multiple-preload-calls-in-gorm-4e67ab52a7fe
- author_url
- https://medium.com/@mehralalit3
- status
- ok
- fetched_at
- 2026-07-16 16:54:54