···138138 // Update IP immediately
139139 s.db.UpdateEndpointIP(ctx, ep.ID, ip, time.Now().UTC())
140140141141+ // STEP 1.5: Fetch IP info asynchronously ASAP (runs in parallel with scanning)
142142+ go s.updateIPInfoIfNeeded(ctx, ip)
143143+141144 // STEP 2: Health check
142145 available, responseTime, version, err := s.client.CheckHealth(ctx, ep.Endpoint)
143146 if err != nil || !available {
···226229 log.Verbose("✓ Processed %d repos for %s", len(repoList), ep.Endpoint)
227230 }
228231229229- // STEP 5: Fetch IP info if needed (async, with backoff)
230230- go s.updateIPInfoIfNeeded(ctx, ip)
232232+ // IP info fetch already started at the beginning (step 1.5)
233233+ // It will complete in the background
231234}
232235233236func (s *Scanner) saveScanResult(ctx context.Context, endpointID int64, result *ScanResult) {